linux-raid.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [mdadm PATCH 0/2] Improvement: new logging library for mdadm/mdmon
@ 2010-01-28 16:04 Artur Wojcik
  2010-01-28 16:04 ` [mdadm PATCH 1/2] Improvement: new logging facility Artur Wojcik
  2010-01-29  9:52 ` [mdadm PATCH 0/2] Improvement: new logging library for mdadm/mdmon Neil Brown
  0 siblings, 2 replies; 7+ messages in thread
From: Artur Wojcik @ 2010-01-28 16:04 UTC (permalink / raw)
  To: linux-raid; +Cc: dan.j.williams, ed.ciechanowski

The following two patches contains the new method of logging messages
in mdadm and mdmon applications. The first patch is just the library,
and the second patch is the proposal on how to use the library in the
applications.

As for the library, please let me know if detailed explanation is required.

---

Artur Wojcik (2):
      Improvement: new logging facility.
      Improvement: Replace fprintf functions with log_* functions.


 Assemble.c    |  382 +++++++++++++++--------------------
 Build.c       |   65 +++---
 Create.c      |  206 ++++++++-----------
 Detail.c      |   39 ++--
 Examine.c     |   11 +
 Grow.c        |  333 +++++++++++++++++-------------
 Incremental.c |  229 ++++++++-------------
 Kill.c        |   21 +-
 Makefile      |    6 -
 Manage.c      |  163 ++++++---------
 Monitor.c     |  107 +++++-----
 Query.c       |    2
 ReadMe.c      |   18 ++
 bitmap.c      |   35 +--
 config.c      |  142 ++++++-------
 log.c         |  625 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 log.h         |  148 +++++++++++++
 managemon.c   |   10 -
 mdadm.c       |  556 +++++++++++++++++++++++++++++++++++----------------
 mdadm.h       |   78 ++++---
 mdmon.c       |   45 ++--
 mdopen.c      |   39 ++--
 mdstat.c      |    2
 monitor.c     |   29 +--
 super-ddf.c   |  185 +++++++----------
 super-intel.c |  366 ++++++++++++++-------------------
 super0.c      |   68 ++----
 super1.c      |   53 ++---
 sysfs.c       |   24 +-
 test          |    0
 util.c        |   22 +-
 31 files changed, 2396 insertions(+), 1613 deletions(-)
 create mode 100644 log.c
 create mode 100644 log.h
 mode change 100644 => 100755 test

---
Artur Wojcik

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [mdadm PATCH 1/2] Improvement: new logging facility.
  2010-01-28 16:04 [mdadm PATCH 0/2] Improvement: new logging library for mdadm/mdmon Artur Wojcik
@ 2010-01-28 16:04 ` Artur Wojcik
  2010-01-29  9:52 ` [mdadm PATCH 0/2] Improvement: new logging library for mdadm/mdmon Neil Brown
  1 sibling, 0 replies; 7+ messages in thread
From: Artur Wojcik @ 2010-01-28 16:04 UTC (permalink / raw)
  To: linux-raid; +Cc: dan.j.williams, ed.ciechanowski

This patch introduces the new method of message logging for
mdadm and mdmon applications.

The new logging library allows redirecting log messages to
terminal console, log file and syslog, simultaneously with
a single function call. The library defines 6 log levels and
10 log hives. The log levels are: ALERT, FATAL, ERROR, WARNING,
NOTICE, INFO and DEBUG. The log hive is an object to ease
operations on group of log messages e.g. form a module of an
application or from a certain functionality.

Each hive has verbosity level and a mask determining where to
redirect the log messages. The mask is useful, for example,
in quiet mode: an application will stop logging messages on
terminal console but it will keep logging to a file and/or
syslog. The log hive is similar to facility parameter of syslog.

The default location of a log file is /var/log/<binname>.log.
The format of log messages differs depending on output. Sylog
and log file outputs have messages prefixed with timestamp and
pid information. Additionally debug logs have messages prefixed
with file name, function name and line in source code. Terminal
console output has message format as close as it is possible to
original format.

Debug messages can be redirected to different log file then
rest of log messages.

Signed-off-by: Artur Wojcik <artur.wojcik@intel.com>
---
 Makefile |    6 -
 log.c    |  625 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 log.h    |  148 +++++++++++++++
 3 files changed, 776 insertions(+), 3 deletions(-)
 create mode 100644 log.c
 create mode 100644 log.h

diff --git a/Makefile b/Makefile
index 901b3e0..ae9f95c 100644
--- a/Makefile
+++ b/Makefile
@@ -81,19 +81,19 @@ OBJS =  mdadm.o config.o mdstat.o  ReadMe.o util.o Manage.o Assemble.o Build.o \
 	Incremental.o \
 	mdopen.o super0.o super1.o super-ddf.o super-intel.o bitmap.o \
 	restripe.o sysfs.o sha1.o mapfile.o crc32.o sg_io.o msg.o \
-	platform-intel.o probe_roms.o
+	platform-intel.o probe_roms.o log.o
 
 SRCS =  mdadm.c config.c mdstat.c  ReadMe.c util.c Manage.c Assemble.c Build.c \
 	Create.c Detail.c Examine.c Grow.c Monitor.c dlink.c Kill.c Query.c \
 	Incremental.c \
 	mdopen.c super0.c super1.c super-ddf.c super-intel.c bitmap.c \
 	restripe.c sysfs.c sha1.c mapfile.c crc32.c sg_io.c msg.c \
-	platform-intel.c probe_roms.c
+	platform-intel.c probe_roms.c log.c
 
 MON_OBJS = mdmon.o monitor.o managemon.o util.o mdstat.o sysfs.o config.o \
 	Kill.o sg_io.o dlink.o ReadMe.o super0.o super1.o super-intel.o \
 	super-ddf.o sha1.o crc32.o msg.o bitmap.o \
-	platform-intel.o probe_roms.o
+	platform-intel.o probe_roms.o log.o
 
 
 STATICSRC = pwgr.c
diff --git a/log.c b/log.c
new file mode 100644
index 0000000..5f0220a
--- /dev/null
+++ b/log.c
@@ -0,0 +1,625 @@
+/*
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <syslog.h>
+#include <assert.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+
+#include "log.h"
+
+/* */
+#define DEFAULT_LOG_NAME	"/var/log/%s.log"
+
+/* */
+#define PREFIX_ALERT		"ALERT"
+#define PREFIX_FATAL		"CRITICAL"
+#define PREFIX_ERROR		"ERROR"
+#define PREFIX_WARN		"WARNING"
+#define PREFIX_NOTICE		NULL
+#define PREFIX_INFO		NULL
+#define PREFIX_DEBUG		"DEBUG"
+
+/* */
+static FILE *stdlog = NULL;
+
+/* */
+static volatile struct __log_hive {
+	unsigned int mask;
+	char *name;
+	enum log_level level;
+	FILE *stream;
+} log_hive[LOG_HIVE_ALL] = {
+	[LOG_HIVE_GENERIC]	= {
+		.mask	= LOG_B_ALL,
+		.name	= NULL,
+		.level	= LOG_LEVEL_ALL,
+		.stream	= NULL},
+	[LOG_HIVE_0]		= {
+		.mask	= LOG_B_ALL,
+		.name	= NULL,
+		.level	= LOG_LEVEL_ALL,
+		.stream	= NULL},
+	[LOG_HIVE_1]		= {
+		.mask	= LOG_B_ALL,
+		.name	= NULL,
+		.level	= LOG_LEVEL_ALL,
+		.stream	= NULL},
+	[LOG_HIVE_2]		= {
+		.mask	= LOG_B_ALL,
+		.name	= NULL,
+		.level	= LOG_LEVEL_ALL,
+		.stream	= NULL},
+	[LOG_HIVE_3]		= {
+		.mask	= LOG_B_ALL,
+		.name	= NULL,
+		.level	= LOG_LEVEL_ALL,
+		.stream	= NULL},
+	[LOG_HIVE_4]		= {
+		.mask	= LOG_B_ALL,
+		.name	= NULL,
+		.level	= LOG_LEVEL_ALL,
+		.stream	= NULL},
+	[LOG_HIVE_5]		= {
+		.mask	= LOG_B_ALL,
+		.name	= NULL,
+		.level	= LOG_LEVEL_ALL,
+		.stream	= NULL},
+	[LOG_HIVE_6]		= {
+		.mask	= LOG_B_ALL,
+		.name	= NULL,
+		.level	= LOG_LEVEL_ALL,
+		.stream	= NULL},
+	[LOG_HIVE_7]		= {
+		.mask	= LOG_B_ALL,
+		.name	= NULL,
+		.level	= LOG_LEVEL_ALL,
+		.stream	= NULL},
+	[LOG_HIVE_DAEMON]	= {
+		.mask	= LOG_B_FILE | LOG_B_SYSLOG,
+		.name	= NULL,
+		.level	= LOG_LEVEL_ALL,
+		.stream	= NULL}
+};
+
+/* */
+static char * const log_prefix[LOG_LEVEL_ALL] = {
+	[LOG_LEVEL_ALERT]	= PREFIX_ALERT,
+	[LOG_LEVEL_FATAL]	= PREFIX_FATAL,
+	[LOG_LEVEL_ERROR]	= PREFIX_ERROR,
+	[LOG_LEVEL_WARNING]	= PREFIX_WARN,
+	[LOG_LEVEL_NOTICE]	= PREFIX_NOTICE,
+	[LOG_LEVEL_INFO]	= PREFIX_INFO,
+	[LOG_LEVEL_DEBUG]	= PREFIX_DEBUG
+};
+
+/* */
+static int const syslog_facil[LOG_HIVE_ALL] = {
+	[LOG_HIVE_GENERIC]	= LOG_USER,
+	[LOG_HIVE_0]		= LOG_LOCAL0,
+	[LOG_HIVE_1]		= LOG_LOCAL1,
+	[LOG_HIVE_2]		= LOG_LOCAL2,
+	[LOG_HIVE_3]		= LOG_LOCAL3,
+	[LOG_HIVE_4]		= LOG_LOCAL4,
+	[LOG_HIVE_5]		= LOG_LOCAL5,
+	[LOG_HIVE_6]		= LOG_LOCAL6,
+	[LOG_HIVE_7]		= LOG_LOCAL7,
+	[LOG_HIVE_DAEMON]	= LOG_DAEMON
+};
+
+/* */
+static int const syslog_prio[LOG_LEVEL_ALL] = {
+	[LOG_LEVEL_NONE]	= -1,
+	[LOG_LEVEL_ALERT]	= LOG_ALERT,
+	[LOG_LEVEL_FATAL]	= LOG_CRIT,
+	[LOG_LEVEL_ERROR]	= LOG_ERR,
+	[LOG_LEVEL_WARNING]	= LOG_WARNING,
+	[LOG_LEVEL_NOTICE]	= LOG_NOTICE,
+	[LOG_LEVEL_INFO]	= LOG_INFO,
+	[LOG_LEVEL_DEBUG]	= LOG_DEBUG
+};
+
+/* */
+static char *progname = NULL;
+
+/* */
+static int _log_mkdir(const char *path)
+{
+	int result = -1;
+	char *p, *t;
+
+	p = canonicalize_file_name(path);
+	t = p;
+	while (t) {
+		t = strchr(t + 1, '/');
+		if (t) *t = '\0';
+		errno = 0;
+		result = mkdir(p, 0640);
+		if (t) *t = '/';
+		if ((result < 0) && (errno != EEXIST))
+			break;
+		result = 0;
+
+	}
+	if (p)
+		free(p);
+
+	return result;
+}
+
+/* */
+static FILE * _log_open(const char *path)
+{
+	int result = 0;
+	FILE *log_strm = NULL;
+	char *t;
+
+	t = rindex(path, '/');
+	if (t) {
+		*t = '\0';
+		result = _log_mkdir(path);
+		*t = '/';
+	}
+	if (result == 0)
+		log_strm = fopen(path, "a");
+
+	return log_strm;
+}
+
+/* */
+static FILE * _log_open_default(void)
+{
+	FILE *result = NULL;
+	char *path;
+	assert(progname);
+	if (asprintf(&path, DEFAULT_LOG_NAME, progname) >= 0) {
+		result = _log_open(path);
+		free(path);
+	}
+	return result;
+}
+
+/* */
+static unsigned int _log_update(enum log_hive index)
+{
+	/* TODO: check environmental variables and update log_mask
+	         approprietally. */
+	return log_hive[index].mask;
+}
+
+/* */
+static void _log_close(FILE *stream)
+{
+	if (stream) {
+		fflush(stream);
+		fclose(stream);
+	}
+}
+
+/* */
+static void _vlog(FILE *stream, const char *tmstamp, const char *prefix,
+	int pid, const char *fmt, va_list vl)
+{
+	char *temp;
+
+	if (stream == NULL) {
+		if (stdlog == NULL)
+			stdlog = _log_open_default();
+		stream = stdlog;
+		if (stream == NULL)
+			return;
+	}
+	if (tmstamp)
+		fprintf(stream, "%s ", tmstamp);
+	assert(progname);
+	fprintf(stream, "%s", progname);
+	if (pid >= 0)
+		fprintf(stream, "[%d]", pid);
+	fprintf(stream, ": ");
+	if (prefix)
+		fprintf(stream, "%s: ", prefix);
+	if (vasprintf(&temp, fmt, vl) >= 0) {
+		fprintf(stream, "%s", temp);
+		if (temp[strlen(temp) - 1] != '\n')
+			fprintf(stream, "\n");
+		free(temp);
+	}
+	fflush(stream);
+}
+
+/* */
+static void _vsys(const char *prefix, int priority, int facility,
+	const char *fmt, va_list vl)
+{
+	assert(progname);
+	char *buffer;
+	if (vasprintf(&buffer, fmt, vl) >= 0) {
+		openlog(progname, LOG_PID | LOG_NDELAY, facility);
+		syslog(priority, "%s%s%s", prefix ? : "", prefix ? ": " : "", buffer);
+		closelog();
+		free(buffer);
+	}
+}
+
+/* */
+static char * _dbg_hdr(const char *file, int line, const char *fn)
+{
+	char *buffer;
+	if (asprintf(&buffer, "%s %s@%d, %s()", PREFIX_DEBUG, file, line, fn) < 0)
+		buffer = NULL;
+	return buffer;
+}
+
+/* */
+static char * _log_timestamp(void)
+{
+	static int index = 0;
+	static suseconds_t usec = 0;
+
+	char *result;
+	struct timeval current_time;
+
+	gettimeofday(&current_time, NULL);
+	if (usec == current_time.tv_usec) {
+		index++;
+	} else {
+		index = 0;
+		usec = current_time.tv_usec;
+	}
+	if (asprintf(&result, "%08x_%04x", (unsigned int)usec, index) < 0)
+		result = NULL;
+
+	return result;
+}
+
+/* */
+static char * _log_prefix(enum log_hive index, enum log_level level)
+{
+	char *result;
+	char *name = log_hive[index].name;
+	char *prefix = log_prefix[level];
+
+	if (asprintf(&result, "%s%s%s", name && prefix ? name : "", name && prefix ? " " : "", prefix ? : "") < 0)
+		return NULL;
+
+	if (*result == '\0') {
+		free(result);
+		result = NULL;
+	}
+	return result;
+}
+
+/* */
+static void _log_debug_close(enum log_hive index)
+{
+	FILE *stream;
+
+	stream = log_hive[index].stream;
+	log_hive[index].stream = NULL;
+
+	if (log_hive[LOG_HIVE_GENERIC].stream == stream)
+		return;
+	if (log_hive[LOG_HIVE_0].stream == stream)
+		return;
+	if (log_hive[LOG_HIVE_1].stream == stream)
+		return;
+	if (log_hive[LOG_HIVE_2].stream == stream)
+		return;
+	if (log_hive[LOG_HIVE_3].stream == stream)
+		return;
+	if (log_hive[LOG_HIVE_4].stream == stream)
+		return;
+	if (log_hive[LOG_HIVE_5].stream == stream)
+		return;
+	if (log_hive[LOG_HIVE_6].stream == stream)
+		return;
+	if (log_hive[LOG_HIVE_7].stream == stream)
+		return;
+	if (log_hive[LOG_HIVE_DAEMON].stream == stream)
+		return;
+
+	fclose(stream);
+}
+
+/* */
+static void _log_hive_free(enum log_hive index)
+{
+	if (log_hive[index].name)
+		free(log_hive[index].name);
+
+	_log_debug_close(index);
+}
+
+/* */
+static void _log_debug_redir(enum log_hive index, const char *path)
+{
+	FILE * stream;
+
+	if ((stream = _log_open(path)) == NULL)
+		return;
+
+	if (index < LOG_HIVE_ALL) {
+		log_hive[index].stream = stream;
+	}  else {
+		log_hive[LOG_HIVE_GENERIC].stream = stream;
+		log_hive[LOG_HIVE_0].stream = stream;
+		log_hive[LOG_HIVE_1].stream = stream;
+		log_hive[LOG_HIVE_2].stream = stream;
+		log_hive[LOG_HIVE_3].stream = stream;
+		log_hive[LOG_HIVE_4].stream = stream;
+		log_hive[LOG_HIVE_5].stream = stream;
+		log_hive[LOG_HIVE_6].stream = stream;
+		log_hive[LOG_HIVE_7].stream = stream;
+		log_hive[LOG_HIVE_DAEMON].stream = stream;
+	}
+}
+
+/* */
+const char * log_get_progname(void)
+{
+	assert(progname);
+	return progname;
+}
+
+/* */
+void log_fini(void)
+{
+	_log_hive_free(LOG_HIVE_GENERIC);
+	_log_hive_free(LOG_HIVE_0);
+	_log_hive_free(LOG_HIVE_1);
+	_log_hive_free(LOG_HIVE_2);
+	_log_hive_free(LOG_HIVE_3);
+	_log_hive_free(LOG_HIVE_4);
+	_log_hive_free(LOG_HIVE_5);
+	_log_hive_free(LOG_HIVE_6);
+	_log_hive_free(LOG_HIVE_7);
+	_log_hive_free(LOG_HIVE_DAEMON);
+
+	_log_close(stdlog);
+	closelog();
+
+	if (progname)
+		free(progname);
+}
+
+/* */
+void log_init(const char *pname)
+{
+	if (pname) {
+		char *t = rindex(pname, '/');
+		if (t)
+			progname = strdup(t + 1);
+		else
+			progname = strdup(pname);
+	}
+}
+
+/* */
+void log_debug_redirect(enum log_hive index, const char *path)
+{
+	if (path) {
+		_log_debug_redir(index, path);
+	} else {
+		if (index < LOG_HIVE_ALL) {
+			_log_debug_close(index);
+		} else {
+			_log_debug_close(LOG_HIVE_GENERIC);
+			_log_debug_close(LOG_HIVE_0);
+			_log_debug_close(LOG_HIVE_1);
+			_log_debug_close(LOG_HIVE_2);
+			_log_debug_close(LOG_HIVE_3);
+			_log_debug_close(LOG_HIVE_4);
+			_log_debug_close(LOG_HIVE_5);
+			_log_debug_close(LOG_HIVE_6);
+			_log_debug_close(LOG_HIVE_7);
+			_log_debug_close(LOG_HIVE_DAEMON);
+		}
+	}
+}
+
+/* */
+void log_redirect(const char *path)
+{
+	_log_close(stdlog);
+	if (path == NULL)
+		stdlog = _log_open_default();
+	else
+		stdlog = _log_open(path);
+}
+
+/* */
+unsigned int log_get_mask(enum log_hive index)
+{
+	if (index < LOG_HIVE_ALL)
+		return log_hive[index].mask;
+	else
+		return (unsigned int)(-1);
+}
+
+/* */
+void log_set_mask(enum log_hive index, unsigned int mask)
+{
+	mask &= 0x07;
+	if (index < LOG_HIVE_ALL) {
+		log_hive[index].mask |= mask;
+	} else {
+		log_hive[LOG_HIVE_GENERIC].mask |= mask;
+		log_hive[LOG_HIVE_0].mask |= mask;
+		log_hive[LOG_HIVE_1].mask |= mask;
+		log_hive[LOG_HIVE_2].mask |= mask;
+		log_hive[LOG_HIVE_3].mask |= mask;
+		log_hive[LOG_HIVE_4].mask |= mask;
+		log_hive[LOG_HIVE_5].mask |= mask;
+		log_hive[LOG_HIVE_6].mask |= mask;
+		log_hive[LOG_HIVE_7].mask |= mask;
+		log_hive[LOG_HIVE_DAEMON].mask |= mask;
+	}
+}
+
+/* */
+void log_reset_mask(enum log_hive index, unsigned int mask)
+{
+	mask = ~(mask & 0x07);
+	if (index < LOG_HIVE_ALL) {
+		log_hive[index].mask &= mask;
+	} else {
+		log_hive[LOG_HIVE_GENERIC].mask &= mask;
+		log_hive[LOG_HIVE_0].mask &= mask;
+		log_hive[LOG_HIVE_1].mask &= mask;
+		log_hive[LOG_HIVE_2].mask &= mask;
+		log_hive[LOG_HIVE_3].mask &= mask;
+		log_hive[LOG_HIVE_4].mask &= mask;
+		log_hive[LOG_HIVE_5].mask &= mask;
+		log_hive[LOG_HIVE_6].mask &= mask;
+		log_hive[LOG_HIVE_7].mask &= mask;
+		log_hive[LOG_HIVE_DAEMON].mask &= mask;
+	}
+}
+
+/* */
+void log_set_name(enum log_hive index, char *name)
+{
+	if (index < LOG_HIVE_ALL) {
+		if (log_hive[index].name)
+			free(log_hive[index].name);
+		if (name)
+			name = strdup(name);
+		log_hive[index].name = name;
+	}
+}
+
+/* */
+void log_set_level(enum log_hive index, enum log_level level)
+{
+	if (level >= LOG_LEVEL_ALL)
+		return;
+
+	if (index < LOG_HIVE_ALL) {
+		log_hive[index].level = level;
+	} else {
+		log_hive[LOG_HIVE_GENERIC].level = level;
+		log_hive[LOG_HIVE_0].level = level;
+		log_hive[LOG_HIVE_1].level = level;
+		log_hive[LOG_HIVE_2].level = level;
+		log_hive[LOG_HIVE_3].level = level;
+		log_hive[LOG_HIVE_4].level = level;
+		log_hive[LOG_HIVE_5].level = level;
+		log_hive[LOG_HIVE_6].level = level;
+		log_hive[LOG_HIVE_7].level = level;
+		log_hive[LOG_HIVE_DAEMON].level = level;
+	}
+}
+
+/* */
+enum log_level log_get_level(enum log_hive index)
+{
+	if (index < LOG_LEVEL_ALL)
+		return log_hive[index].level;
+	else
+		return LOG_LEVEL_NONE;
+}
+
+/* */
+void log_msg(enum log_hive index, enum log_level level, const char *fmt, ...)
+{
+	va_list vl;
+	char *timestamp, *prefix;
+	unsigned int mask;
+
+	if (index >= LOG_HIVE_ALL || fmt == NULL)
+		return;
+
+	mask = _log_update(index);
+
+	if (log_hive[index].level < level || level == LOG_LEVEL_DEBUG)
+		return;
+
+	timestamp = _log_timestamp();
+	prefix = _log_prefix(index, level);
+
+	if ((mask & LOG_B_SYSLOG) == LOG_B_SYSLOG) {
+		va_start(vl, fmt);
+		_vsys(prefix, syslog_prio[level], syslog_facil[index], fmt, vl);
+		va_end(vl);
+	}
+	if ((mask & LOG_B_FILE) == LOG_B_FILE) {
+		va_start(vl, fmt);
+		_vlog(stdlog, timestamp, prefix, getpid(), fmt, vl);
+		va_end(vl);
+	}
+	if ((mask & LOG_B_CONSOLE) == LOG_B_CONSOLE) {
+		va_start(vl, fmt);
+		_vlog(stderr, NULL, prefix, -1, fmt, vl);
+		va_end(vl);
+	}
+	if (prefix)
+		free(prefix);
+	if (timestamp)
+		free(timestamp);
+}
+
+/* */
+void log_dbg(enum log_hive index, const char *file, int ln, const char *fn,
+	const char *fmt, ...)
+{
+	va_list vl;
+	char *timestamp, *hdr;
+	unsigned int mask;
+
+	if (index >= LOG_HIVE_ALL || fmt == NULL)
+		return;
+
+	mask = _log_update(index);
+
+	if (log_hive[index].level < LOG_LEVEL_DEBUG)
+		return;
+
+	timestamp = _log_timestamp();
+	hdr = _dbg_hdr(file, ln, fn);
+
+	if ((mask & LOG_B_SYSLOG) == LOG_B_SYSLOG) {
+		va_start(vl, fmt);
+		_vsys(timestamp, LOG_DEBUG, syslog_facil[index], fmt, vl);
+		va_end(vl);
+	}
+	if ((mask & LOG_B_FILE) == LOG_B_FILE) {
+		va_start(vl, fmt);
+		_vlog(log_hive[index].stream ? : stdlog, timestamp,
+			hdr ? : PREFIX_DEBUG, getpid(), fmt, vl);
+		va_end(vl);
+	}
+	if ((mask & LOG_B_CONSOLE) == LOG_B_CONSOLE) {
+		va_start(vl, fmt);
+		_vlog(stderr, NULL, hdr ? : PREFIX_DEBUG, -1, fmt, vl);
+		va_end(vl);
+	}
+	if (hdr)
+		free(hdr);
+	if (timestamp)
+		free(timestamp);
+}
+
diff --git a/log.h b/log.h
new file mode 100644
index 0000000..c8d3471
--- /dev/null
+++ b/log.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _LOG_H
+#define _LOG_H		1
+
+/* */
+enum log_level {
+	LOG_LEVEL_QUIET = 0,
+	LOG_LEVEL_NONE = LOG_LEVEL_QUIET,
+	LOG_LEVEL_ALERT,
+	LOG_LEVEL_FATAL,
+	LOG_LEVEL_ERROR,
+	LOG_LEVEL_WARNING,
+	LOG_LEVEL_NOTICE,
+	LOG_LEVEL_INFO,
+	LOG_LEVEL_DEBUG,
+	LOG_LEVEL_ALL
+};
+
+/* */
+enum log_hive {
+	LOG_HIVE_GENERIC = 0,
+	LOG_HIVE_0,
+	LOG_HIVE_1,
+	LOG_HIVE_2,
+	LOG_HIVE_3,
+	LOG_HIVE_4,
+	LOG_HIVE_5,
+	LOG_HIVE_6,
+	LOG_HIVE_7,
+	LOG_HIVE_DAEMON,
+	LOG_HIVE_ALL
+};
+
+/* */
+#define LOG_B_CONSOLE	0x01
+
+/* */
+#define LOG_B_FILE	0x02
+
+/* */
+#define LOG_B_SYSLOG	0x04
+
+/* */
+#define LOG_B_ALL	(LOG_B_CONSOLE | LOG_B_SYSLOG | LOG_B_FILE)
+
+/* */
+#define log_alert(__hive, __fmt, ...) \
+	do { if (log_get_level(__hive) >= LOG_LEVEL_ALERT) \
+		log_msg(__hive, LOG_LEVEL_ALERT, __fmt, ## __VA_ARGS__); \
+	} while (0)
+
+/* */
+#define log_fatal(__hive, __fmt, ...) \
+	do { if (log_get_level(__hive) >= LOG_LEVEL_FATAL) \
+		log_msg(__hive, LOG_LEVEL_FATAL, __fmt, ## __VA_ARGS__); \
+	} while (0)
+
+/* */
+#define log_error(__hive, __fmt, ...) \
+	do { if (log_get_level(__hive) >= LOG_LEVEL_ERROR) \
+		log_msg(__hive, LOG_LEVEL_ERROR, __fmt, ## __VA_ARGS__); \
+	} while (0)
+
+/* */
+#define log_warn(__hive, __fmt, ...) \
+	do { if (log_get_level(__hive) >= LOG_LEVEL_WARNING) \
+		log_msg(__hive, LOG_LEVEL_WARNING, __fmt, ## __VA_ARGS__); \
+	} while (0)
+/* */
+#define log_notice(__hive, __fmt, ...) \
+	do { if (log_get_level(__hive) >= LOG_LEVEL_NOTICE) \
+		log_msg(__hive, LOG_LEVEL_NOTICE, __fmt, ## __VA_ARGS__); \
+	} while (0)
+
+/* */
+#define log_info(__hive, __fmt, ...) \
+	do { if (log_get_level(__hive) >= LOG_LEVEL_INFO) \
+		log_msg(__hive, LOG_LEVEL_INFO, __fmt, ## __VA_ARGS__); \
+	} while (0)
+
+/* */
+#define log_debug(__hive, __fmt, ...) \
+	do { if (log_get_level(__hive) >= LOG_LEVEL_DEBUG) \
+		log_dbg(__hive, __FILE__, __LINE__, __func__, __fmt, ## __VA_ARGS__); \
+	} while (0)
+
+/* */
+void log_init(const char *path);
+
+/* */
+void log_fini(void);
+
+/* */
+void log_set_progname(const char *path);
+
+/* */
+const char * log_get_progname(void);
+
+/* */
+void log_debug_redirect(enum log_hive hive, const char *path);
+
+/* */
+void log_redirect(const char *path);
+
+/* */
+void log_set_name(enum log_hive index, char *name);
+
+/* */
+void log_set_mask(enum log_hive hive, unsigned int mask);
+
+/* */
+unsigned int log_get_mask(enum log_hive hive);
+
+/* */
+void log_reset_mask(enum log_hive hive, unsigned int mask);
+
+/* */
+void log_set_level(enum log_hive hive, enum log_level level);
+
+/* */
+enum log_level log_get_level(enum log_hive hive);
+
+/* */
+void log_dbg(enum log_hive hive, const char *file, int ln, const char *fname,
+	const char *fmt, ...) __attribute__((format(printf,5,6)));
+
+/* */
+void log_msg(enum log_hive index, enum log_level level, const char *fmt, ...)
+	__attribute__((format(printf,3,4)));
+
+#endif /* _LOG_H */
+


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [mdadm PATCH 0/2] Improvement: new logging library for mdadm/mdmon
  2010-01-28 16:04 [mdadm PATCH 0/2] Improvement: new logging library for mdadm/mdmon Artur Wojcik
  2010-01-28 16:04 ` [mdadm PATCH 1/2] Improvement: new logging facility Artur Wojcik
@ 2010-01-29  9:52 ` Neil Brown
  2010-01-29 16:06   ` Artur Wojcik
  1 sibling, 1 reply; 7+ messages in thread
From: Neil Brown @ 2010-01-29  9:52 UTC (permalink / raw)
  To: Artur Wojcik; +Cc: linux-raid, dan.j.williams, ed.ciechanowski

On Thu, 28 Jan 2010 17:04:04 +0100
Artur Wojcik <artur.wojcik@intel.com> wrote:

> The following two patches contains the new method of logging messages
> in mdadm and mdmon applications. The first patch is just the library,
> and the second patch is the proposal on how to use the library in the
> applications.
> 
> As for the library, please let me know if detailed explanation is required.
> 

Detailed explanations are always necessary.

I'd probably need a lot of convincing to add something like this to mdadm.

NeilBrown

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [mdadm PATCH 0/2] Improvement: new logging library for mdadm/mdmon
  2010-01-29  9:52 ` [mdadm PATCH 0/2] Improvement: new logging library for mdadm/mdmon Neil Brown
@ 2010-01-29 16:06   ` Artur Wojcik
  2010-01-29 16:38     ` Robin Hill
  2010-01-29 22:23     ` Dan Williams
  0 siblings, 2 replies; 7+ messages in thread
From: Artur Wojcik @ 2010-01-29 16:06 UTC (permalink / raw)
  To: Neil Brown; +Cc: linux-raid@vger.kernel.org, Williams, Dan J, Ciechanowski, Ed

On Fri, 2010-01-29 at 09:52 +0000, Neil Brown wrote:
> I'd probably need a lot of convincing to add something like this to mdadm.
> 

I did not expect this patch to be accepted without convincing you or at
least without a lot of explanations :). What interest you the most?

The reason for this improvement/patch is:

1) to unify the way mdadm and mdmon log messages,
2) to have logs from mdadm and mdmon applications at the same time, 
3) to be able to capture log messages when system is booting, 
4) to simplify the source code. 

This all should improve problem diagnosis/resolution (complete log) and
reduce the complexity of source code (one function call, less parameters
in parent function) and simpler code is easier to maintain.

This is only the library, the next step would be to clean up the logs
i.e. mdmon does not log much. I started this in 2nd patch. 

BTW. I have a problem with patch 2/2 - it didn't appear on the list. I
tried sending it several times - is it too big?. However you should
receive it on your mailbox, if not please let me know. 

The second patch is only a proposal on how to incorporate the logging
library into mdmon/mdmadm.

At the moment all I can ask you is to try it first. The command line
works as before i.e. -v[v[v]] increases the level of verbosity and
'quiet' makes no output on terminal console only (mdadm still will be
logging to file and to syslog). 

The command line does not work for mdadm yet.

The logs are redirected to terminal console, syslog and log file with a
single function call.

There are new command line options, use them to on/off certain group of
logs and change verbosity level. The new commands are

--log-alert=[list of hives comma separated; all - for all hives]
--log-fatal=[same as above]
--log-error=[same as above]
--log-warn=[same as above]
--log-notice=[same as above]
--log-info=[same as above]
--log-debug=[same as above]

If no argument is given (optarg is null) then verbosity is changed for
generic hive only.

There will be command line options options added soon to redirect the
log messages.

Here's the list of hives: generic, io, super, ddf, mode, imsm, deamon,
all

generic - command line parser and config file parser

io - e.g. file acces errors, file seek errors, etc.

super - log messages related to super0 and super1.

ddf - log messages related to DDF volumes and containers only.

mode - log messages related to mode operations (Assemble, Create, Build,
etc) - the logs visualizing the stages of an algorithm.

imsm - the logs from all Intel modules.

deamon - the logs from mdmon deamon process and from monitor proces of
mdadm.

all - means 'perform an operation on all hives'

Thanks,
Artur



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [mdadm PATCH 0/2] Improvement: new logging library for mdadm/mdmon
  2010-01-29 16:06   ` Artur Wojcik
@ 2010-01-29 16:38     ` Robin Hill
  2010-01-29 22:23     ` Dan Williams
  1 sibling, 0 replies; 7+ messages in thread
From: Robin Hill @ 2010-01-29 16:38 UTC (permalink / raw)
  To: linux-raid@vger.kernel.org

[-- Attachment #1: Type: text/plain, Size: 508 bytes --]

On Fri Jan 29, 2010 at 05:06:28PM +0100, Artur Wojcik wrote:

> deamon - the logs from mdmon deamon process and from monitor proces of
> mdadm.
> 
Just to be pedantic, can I point out that this should be either demon or
daemon, but definitely not deamon.

Cheers,
    Robin
-- 
     ___        
    ( ' }     |       Robin Hill        <robin@robinhill.me.uk> |
   / / )      | Little Jim says ....                            |
  // !!       |      "He fallen in de water !!"                 |

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [mdadm PATCH 0/2] Improvement: new logging library for mdadm/mdmon
  2010-01-29 16:06   ` Artur Wojcik
  2010-01-29 16:38     ` Robin Hill
@ 2010-01-29 22:23     ` Dan Williams
  2010-01-30  7:19       ` Michael Evans
  1 sibling, 1 reply; 7+ messages in thread
From: Dan Williams @ 2010-01-29 22:23 UTC (permalink / raw)
  To: Wojcik, Artur; +Cc: Neil Brown, Ciechanowski, Ed, linux-raid

Wojcik, Artur wrote:
> On Fri, 2010-01-29 at 09:52 +0000, Neil Brown wrote:
>> I'd probably need a lot of convincing to add something like this to mdadm.
>>
> 
> I did not expect this patch to be accepted without convincing you or at
> least without a lot of explanations :). What interest you the most?
> 
> The reason for this improvement/patch is:
> 
> 1) to unify the way mdadm and mdmon log messages,

Unification implies code reduction, this is currently just code movement.

> 2) to have logs from mdadm and mdmon applications at the same time
> 3) to be able to capture log messages when system is booting, 
> 4) to simplify the source code. 

The only one that would be interesting from a debug perspective is 3, 
but syslog is not available in the initramfs and I currently do not see 
how it would be much better than just redirecting the console to the 
serial port and logging it there.  The dprintf() calls in mdmon are 
sometimes useful, but I am skeptical of needing those on all the time.

Can you identify debug scenarios that require this level of logging 
sophistication (versus doing one-off build/configuration changes to dump 
some diagnostic info)?  As it stands this looks like a solution looking 
for a problem.

--
Dan


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [mdadm PATCH 0/2] Improvement: new logging library for mdadm/mdmon
  2010-01-29 22:23     ` Dan Williams
@ 2010-01-30  7:19       ` Michael Evans
  0 siblings, 0 replies; 7+ messages in thread
From: Michael Evans @ 2010-01-30  7:19 UTC (permalink / raw)
  To: Dan Williams; +Cc: Wojcik, Artur, Neil Brown, Ciechanowski, Ed, linux-raid

On Fri, Jan 29, 2010 at 2:23 PM, Dan Williams <dan.j.williams@intel.com> wrote:
> Wojcik, Artur wrote:
>>
>> On Fri, 2010-01-29 at 09:52 +0000, Neil Brown wrote:
>>>
>>> I'd probably need a lot of convincing to add something like this to
>>> mdadm.
>>>
>>
>> I did not expect this patch to be accepted without convincing you or at
>> least without a lot of explanations :). What interest you the most?
>>
>> The reason for this improvement/patch is:
>>
>> 1) to unify the way mdadm and mdmon log messages,
>
> Unification implies code reduction, this is currently just code movement.
>
>> 2) to have logs from mdadm and mdmon applications at the same time
>> 3) to be able to capture log messages when system is booting, 4) to
>> simplify the source code.
>
> The only one that would be interesting from a debug perspective is 3, but
> syslog is not available in the initramfs and I currently do not see how it
> would be much better than just redirecting the console to the serial port
> and logging it there.  The dprintf() calls in mdmon are sometimes useful,
> but I am skeptical of needing those on all the time.
>

3) If you're worried about the kernel messages look in to netconsole.

If you're worried about where system logs go after startup, isn't that
what the various syslog daemons are for (in fact on my 24/7 linux
system my syslog /captures/ netconsole logs from any other machine I
care to set up sending from)?
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2010-01-30  7:19 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-28 16:04 [mdadm PATCH 0/2] Improvement: new logging library for mdadm/mdmon Artur Wojcik
2010-01-28 16:04 ` [mdadm PATCH 1/2] Improvement: new logging facility Artur Wojcik
2010-01-29  9:52 ` [mdadm PATCH 0/2] Improvement: new logging library for mdadm/mdmon Neil Brown
2010-01-29 16:06   ` Artur Wojcik
2010-01-29 16:38     ` Robin Hill
2010-01-29 22:23     ` Dan Williams
2010-01-30  7:19       ` Michael Evans

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).