Commit e0fec357514bd5927743eb70f3f670bae9b3e4c4

zefir 2012-02-11T19:31:34

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.

diff --git a/Makefile.am b/Makefile.am
index 347b4af..e0be3ca 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 3110e0a..b3c339a 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 0000000..01ab87c
--- /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 0000000..18f3a74
--- /dev/null
+++ b/logging.h
@@ -0,0 +1,38 @@
+#ifndef __LOGGING_H__
+#define __LOGGING_H__
+
+#include "config.h"
+#include <stdbool.h>
+#include <stdarg.h>
+
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#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 72fdb24..d9a50a0 100644
--- a/miner.h
+++ b/miner.h
@@ -11,6 +11,7 @@
 #include <curl/curl.h>
 #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 <syslog.h>
-#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 55495be..cba36ce 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)