From e0fec357514bd5927743eb70f3f670bae9b3e4c4 Mon Sep 17 00:00:00 2001 From: zefir Date: Sat, 11 Feb 2012 19:31:34 +0100 Subject: [PATCH] modularized logging, support for priority based logging Functions related to logging are extracted into dedicated source files for better maintainability. The existing low-level logging API is extended with a generalized scheme providing log functions log_{error, warning, notice, info, debug} that log messages based on a global opt_log_level. opt_log_level for now is set to LOG_NOTICE and might be modified via command line options or config files in future releases. --- Makefile.am | 7 +-- cgminer.c | 6 +- logging.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++++ logging.h | 38 ++++++++++++ miner.h | 17 +----- util.c | 63 -------------------- 6 files changed, 205 insertions(+), 88 deletions(-) create mode 100644 logging.c create mode 100644 logging.h diff --git a/Makefile.am b/Makefile.am index 347b4af4..e0be3ca7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -26,17 +26,14 @@ cgminer_LDADD = $(DLOPEN_FLAGS) @LIBCURL_LIBS@ @JANSSON_LIBS@ @PTHREAD_LIBS@ \ cgminer_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib @OPENCL_FLAGS@ # common sources - -# this is the original monolithic main.c, kept as reference -# cgminer_SOURCES := main.c - -# this is the original main.c without extracted CPU and GPU code cgminer_SOURCES := cgminer.c cgminer_SOURCES += elist.h miner.h compat.h bench_block.h \ util.c uthash.h \ sha2.c sha2.h api.c +cgminer_SOURCES += logging.c + # GPU sources, TODO: make them selectable # the GPU portion extracted from original main.c cgminer_SOURCES += device-gpu.h device-gpu.c diff --git a/cgminer.c b/cgminer.c index 3110e0ae..b3c339a0 100644 --- a/cgminer.c +++ b/cgminer.c @@ -78,7 +78,6 @@ static char packagename[255]; int gpu_threads; -bool opt_debug = false; bool opt_protocol = false; static bool want_longpoll = true; static bool have_longpoll = false; @@ -92,7 +91,6 @@ static int opt_retries = -1; static int opt_fail_pause = 5; static int fail_pause = 5; int opt_log_interval = 5; -bool opt_log_output = false; static int opt_queue = 1; int opt_vectors; int opt_worksize; @@ -1474,7 +1472,7 @@ static bool submit_upstream_work(const struct work *work) sprintf(where, " pool %d", work->pool->pool_no); else strcpy(where, ""); - + res = json_object_get(val, "reject-reason"); if (res) { const char *reasontmp = json_string_value(res); @@ -1487,7 +1485,7 @@ static bool submit_upstream_work(const struct work *work) reason[reasonLen + 2] = ')'; reason[reasonLen + 3] = '\0'; } else strcpy(reason, ""); - + applog(LOG_NOTICE, "Rejected %s %s %d thread %d%s%s", hashshow, cgpu->api->name, cgpu->device_id, thr_id, where, reason); } diff --git a/logging.c b/logging.c new file mode 100644 index 00000000..01ab87c5 --- /dev/null +++ b/logging.c @@ -0,0 +1,162 @@ +#include "logging.h" +#include "miner.h" + +bool opt_debug = false; +bool opt_log_output = false; + +/* per default priorities higher than LOG_NOTICE are logged */ +int opt_log_level = LOG_NOTICE; + +void vapplog(int prio, const char *fmt, va_list ap) +{ + extern bool use_curses; + if (!opt_debug && prio == LOG_DEBUG) + return; + +#ifdef HAVE_SYSLOG_H + if (use_syslog) { + vsyslog(prio, fmt, ap); + } +#else + if (0) {} +#endif + else if (opt_log_output || prio <= LOG_NOTICE) { + char *f; + int len; + struct timeval tv = { }; + struct tm *tm; + + gettimeofday(&tv, NULL); + + tm = localtime(&tv.tv_sec); + + len = 40 + strlen(fmt) + 22; + f = alloca(len); + sprintf(f, "[%d-%02d-%02d %02d:%02d:%02d] %s\n", + tm->tm_year + 1900, + tm->tm_mon + 1, + tm->tm_mday, + tm->tm_hour, + tm->tm_min, + tm->tm_sec, + fmt); + /* Only output to stderr if it's not going to the screen as well */ + if (!isatty(fileno((FILE *)stderr))) { + va_list apc; + + va_copy(apc, ap); + vfprintf(stderr, f, apc); /* atomic write to stderr */ + fflush(stderr); + } + + if (use_curses) + log_curses(prio, f, ap); + else { + int len = strlen(f); + + strcpy(f + len - 1, " \n"); + + log_curses(prio, f, ap); + } + } +} + +void applog(int prio, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vapplog(prio, fmt, ap); + va_end(ap); +} + + +/* high-level logging functions, based on global opt_log_level */ + +/* + * generic log function used by priority specific ones + * equals vapplog() without additional priority checks + */ +static void log_generic(int prio, const char *fmt, va_list ap) +{ + extern bool use_curses; +#ifdef HAVE_SYSLOG_H + if (use_syslog) { + vsyslog(prio, fmt, ap); + } +#else + if (0) {} +#endif + else { + char *f; + int len; + struct timeval tv = { }; + struct tm *tm; + + gettimeofday(&tv, NULL); + + tm = localtime(&tv.tv_sec); + + len = 40 + strlen(fmt) + 22; + f = alloca(len); + sprintf(f, "[%d-%02d-%02d %02d:%02d:%02d] %s\n", + tm->tm_year + 1900, + tm->tm_mon + 1, + tm->tm_mday, + tm->tm_hour, + tm->tm_min, + tm->tm_sec, + fmt); + /* Only output to stderr if it's not going to the screen as well */ + if (!isatty(fileno((FILE *)stderr))) { + va_list apc; + + va_copy(apc, ap); + vfprintf(stderr, f, apc); /* atomic write to stderr */ + fflush(stderr); + } + + if (use_curses) + log_curses(prio, f, ap); + else { + int len = strlen(f); + + strcpy(f + len - 1, " \n"); + + log_curses(prio, f, ap); + } + } +} +/* we can not generalize variable argument list */ +#define LOG_TEMPLATE(PRIO) \ + if (PRIO <= opt_log_level) { \ + va_list ap; \ + va_start(ap, fmt); \ + vapplog(PRIO, fmt, ap); \ + va_end(ap); \ + } + +void log_error(const char *fmt, ...) +{ + LOG_TEMPLATE(LOG_ERR); +} + +void log_warning(const char *fmt, ...) +{ + LOG_TEMPLATE(LOG_WARNING); +} + +void log_notice(const char *fmt, ...) +{ + LOG_TEMPLATE(LOG_NOTICE); +} + +void log_info(const char *fmt, ...) +{ + LOG_TEMPLATE(LOG_INFO); +} + +void log_debug(const char *fmt, ...) +{ + LOG_TEMPLATE(LOG_DEBUG); +} diff --git a/logging.h b/logging.h new file mode 100644 index 00000000..18f3a744 --- /dev/null +++ b/logging.h @@ -0,0 +1,38 @@ +#ifndef __LOGGING_H__ +#define __LOGGING_H__ + +#include "config.h" +#include +#include + +#ifdef HAVE_SYSLOG_H +#include +#else +enum { + LOG_ERR, + LOG_WARNING, + LOG_NOTICE, + LOG_INFO, + LOG_DEBUG, +}; +#endif + +/* original / legacy debug flags */ +extern bool opt_debug; +extern bool opt_log_output; + +/* global log_level, messages with lower or equal prio are logged */ +extern int opt_log_level; + +/* low-level logging functions with priority parameter */ +extern void vapplog(int prio, const char *fmt, va_list ap); +extern void applog(int prio, const char *fmt, ...); + +/* high-level logging functions with implicit priority */ +extern void log_error(const char *fmt, ...); +extern void log_warning(const char *fmt, ...); +extern void log_notice(const char *fmt, ...); +extern void log_info(const char *fmt, ...); +extern void log_debug(const char *fmt, ...); + +#endif /* __LOGGING_H__ */ diff --git a/miner.h b/miner.h index 72fdb241..d9a50a0b 100644 --- a/miner.h +++ b/miner.h @@ -11,6 +11,7 @@ #include #include "elist.h" #include "uthash.h" +#include "logging.h" #ifdef HAVE_OPENCL #ifdef __APPLE_CC__ @@ -102,18 +103,6 @@ void *alloca (size_t); #endif #endif -#ifdef HAVE_SYSLOG_H -#include -#else -enum { - LOG_ERR, - LOG_WARNING, - LOG_NOTICE, - LOG_INFO, - LOG_DEBUG, -}; -#endif - #undef unlikely #undef likely #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) @@ -403,9 +392,7 @@ static inline void rwlock_init(pthread_rwlock_t *lock) struct pool; -extern bool opt_debug; extern bool opt_protocol; -extern bool opt_log_output; extern char *opt_kernel_path; extern char *opt_socks_proxy; extern char *cgminer_path; @@ -609,8 +596,6 @@ extern void switch_pools(struct pool *selected); extern void write_config(FILE *fcfg); extern void log_curses(int prio, const char *f, va_list ap); extern void clear_logwin(void); -extern void vapplog(int prio, const char *fmt, va_list ap); -extern void applog(int prio, const char *fmt, ...); extern struct thread_q *tq_new(void); extern void tq_free(struct thread_q *tq); extern bool tq_push(struct thread_q *tq, void *data); diff --git a/util.c b/util.c index 55495be8..cba36ce7 100644 --- a/util.c +++ b/util.c @@ -65,69 +65,6 @@ struct tq_ent { struct list_head q_node; }; -void vapplog(int prio, const char *fmt, va_list ap) -{ - extern bool use_curses; - if (!opt_debug && prio == LOG_DEBUG) - return; - -#ifdef HAVE_SYSLOG_H - if (use_syslog) { - vsyslog(prio, fmt, ap); - } -#else - if (0) {} -#endif - else if (opt_log_output || prio <= LOG_NOTICE) { - char *f; - int len; - struct timeval tv = { }; - struct tm *tm; - - gettimeofday(&tv, NULL); - - tm = localtime(&tv.tv_sec); - - len = 40 + strlen(fmt) + 22; - f = alloca(len); - sprintf(f, "[%d-%02d-%02d %02d:%02d:%02d] %s\n", - tm->tm_year + 1900, - tm->tm_mon + 1, - tm->tm_mday, - tm->tm_hour, - tm->tm_min, - tm->tm_sec, - fmt); - /* Only output to stderr if it's not going to the screen as well */ - if (!isatty(fileno((FILE *)stderr))) { - va_list apc; - - va_copy(apc, ap); - vfprintf(stderr, f, apc); /* atomic write to stderr */ - fflush(stderr); - } - - if (use_curses) - log_curses(prio, f, ap); - else { - int len = strlen(f); - - strcpy(f + len - 1, " \n"); - - log_curses(prio, f, ap); - } - } -} - -void applog(int prio, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vapplog(prio, fmt, ap); - va_end(ap); -} - static void databuf_free(struct data_buffer *db) { if (!db)