Skip to contentSkip to conversation

kernel support for non-English user messages

DISCUSSION Jim Keniston[UNIX] 1 participant 1 message Apr 11, 2003

lore
Share & tools
lore
#0 lore raw
Quoted 10 lines · Alan Cox

Providing the viewer is translating the originals always exist. Indeed you can do

        LANG=es view-logs
        LANG=ru view-logs
        ...

You can have sysadmins with no common language("not a recommended configuration" ;))

Quoted 6 lines

You are right about needing to log parameters, but given a log line of the form

%s: went up in flames\n\0eth0\0\0

that can be handled by the log viewer

Other contributors have also endorsed the idea of creating a message log where the format and args are kept separate. Here's code to do it.

Enclosed is a patch that adds support for logging kernel events to a structured event log (see evlog.sourceforge.net). When EVLOG_FWPRINTK is enabled, printk messages are automatically forwarded to the event log in this form. (They are also logged to klogd/syslogd, as usual.)

The log viewer (evlview) can reconstruct the complete message from the components. If you provide translations (AKA formatting templates) for particular messages, and set your LANG environment variable appropriately,
evlview will display those messages in the selected language. (Messages without translations are displayed in English.)

A few more notes about this event-logging support:
- printk calls don't change; one line is added to printk(), about 20 to printk.c.
- Like syslog, it also handles messages from user space. There are also a variety of other ways to use this support to log information from the kernel.
- User-mode event logging requires no kernel support.
- There's a bunch of stuff that sysadmins and tech support people have found useful, such as APIs for examining the log and receiving notification
of events.

See evlog.sourceforge.net for more info.

Jim Keniston
IBM Linux Technology Center

include/linux/evl_log.h +142 -0
diff -Naur linux.org/include/linux/evl_log.h linux.kernel.patched/include/linux/evl_log.h
@@ -0,0 +1,142 @@
+/*
+ * Linux Event Logging for the Enterprise
+ * Copyright (c) International Business Machines Corp., 2003
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *  Please send e-mail to [email protected] if you have
+ *  questions or comments.
+ *
+ *  Project Website:  http://evlog.sourceforge.net/
+ *
+ */
+
+#ifndef _LINUX_EVL_LOG_H
+#define _LINUX_EVL_LOG_H
+
+#ifndef __KERNEL__
+#ifdef _POSIX_THREADS
+#include <pthread.h>
+#endif
+#endif
+
+/* Values for log_flags member */
+#define POSIX_LOG_TRUNCATE  0x1
+#define EVL_KERNEL_EVENT	0x2
+#define EVL_INITIAL_BOOT_EVENT 	0x4
+#define EVL_KERNTIME_LOCAL	0x8
+#define EVL_INTERRUPT		0x10	/* Logged from interrupt context */
+#define EVL_PRINTK		0x20	/* Logged by printk() */
+
+/* Formats for optional portion of record. */
+#define POSIX_LOG_NODATA    0
+#define POSIX_LOG_BINARY    1
+#define POSIX_LOG_STRING    2
+#define POSIX_LOG_PRINTF    3
+
+/* Maximum length of variable portion of record */
+#define POSIX_LOG_ENTRY_MAXLEN      (8 * 1024)
+
+/* Maximum length for a string returned by posix_log_memtostr */
+/* Thus also the max length of a facility name */
+#define POSIX_LOG_MEMSTR_MAXLEN	128
+
+typedef unsigned int posix_log_facility_t;
+typedef int posix_log_severity_t;
+typedef int posix_log_recid_t;
+typedef int posix_log_procid_t;
+
+#define EVL_INVALID_FACILITY ((posix_log_facility_t)-1)
+
+struct posix_log_entry {
+	unsigned int            log_magic;
+        posix_log_recid_t   	log_recid;
+        size_t          	log_size;
+        int             	log_format;
+        int             	log_event_type;
+        posix_log_facility_t 	log_facility;
+        posix_log_severity_t    log_severity;
+        uid_t           	log_uid;
+        gid_t           	log_gid;
+        pid_t           	log_pid;
+        pid_t           	log_pgrp;
+        struct timespec 	log_time;
+        unsigned int    	log_flags;
+#ifdef __KERNEL__
+        unsigned long int	log_thread;
+#else
+#ifdef _POSIX_THREADS
+	pthread_t		log_thread;
+#else
+	unsigned long int	log_thread;
+#endif
+#endif
+        posix_log_procid_t	log_processor;
+}; 
+
+typedef struct posix_log_entry rec_hdr_t;
+typedef struct evl_buf_rec {
+        struct posix_log_entry  rechdr;
+        char                    varbuf[1];
+} evl_buf_rec_t;
+
+
+#define LOGFILE_MAGIC   0xbeefface
+#define LOGREC_MAGIC    0xfeefface
+#define REC_HDR_SIZE    sizeof(struct posix_log_entry)
+
+/*
+ * Reserved Event Types
+ */
+#define EVL_SYSLOG_MESSAGE      0x1
+#define EVL_PRINTK_MESSAGE      0x2
+#define EVL_BUFFER_OVERRUN      0x6
+#define EVL_DUPS_DISCARDED      0x7
+
+#define LOG_LOGMGMT              (12<<3)	/* EVL Facility */
+
+#ifdef __KERNEL__
+/*
+ * Reserved Facilities
+ */
+#define LOG_KERN        (0<<3)  /* Kernel Facility */
+#define LOG_AUTHPRIV    (10<<3) /* security/authorization messages (private) */
+/*
+ * priorities (these are ordered)
+ */
+#define LOG_EMERG   0   /* system is unusable */
+#define LOG_ALERT   1   /* action must be taken immediately */
+#define LOG_CRIT    2   /* critical conditions */
+#define LOG_ERR     3   /* error conditions */
+#define LOG_WARNING 4   /* warning conditions */
+#define LOG_NOTICE  5   /* normal but significant condition */
+#define LOG_INFO    6   /* informational */
+#define LOG_DEBUG   7   /* debug-level messages */
+
+#ifdef CONFIG_EVLOG
+extern int posix_log_write(posix_log_facility_t facility, int event_type,
+         	posix_log_severity_t severity, const void *buf,
+        	size_t len, int format, unsigned int flags);
+#else	/* ! CONFIG_EVLOG */
+inline int posix_log_write(posix_log_facility_t facility, int event_type,
+		posix_log_severity_t severity, const void *buf,
+		size_t len, int format, unsigned int flags)
+		{ return -ENOSYS; }
+#endif	/* CONFIG_EVLOG */
+
+#endif	/* __KERNEL__ */
+
+#endif	/* _LINUX_EVL_LOG_H */
init/Kconfig +29 -0
diff -Naur linux.org/init/Kconfig linux.kernel.patched/init/Kconfig
@@ -92,6 +92,35 @@
 	  building a kernel for install/rescue disks or your system is very
 	  limited in memory.
 
+config EVLOG
+	bool "Enterprise event logging support"
+	help
+	  This enables support for enterprise-level event logging based
+	  upon the draft POSIX 1003.25 standard.  Enabling this feature
+	  does not affect the operation of the sysklogd package in any
+	  way.  In order to fully utilize this feature, user must also
+	  install the companion evlog package in user-space.
+
+	  For more information see http://evlog.sourceforge.net
+
+	  If you don't know what to do here, say N.
+
+config EVLOG_BUFSIZE
+	int "Event log buffer size (in Kbytes)"
+	depends on EVLOG
+	default "128"
+	help
+	  Event log buffer size in Kbytes. Default size is 128 Kbytes.
+
+config EVLOG_FWPRINTK
+	bool "Forward printk messages to enterprise event log"
+	depends on EVLOG
+	help
+	  This option forwards printk log messages to the enterprise event
+	  log.  Printk messages are still logged to /var/log/messages.
+
+	  If you don't know what to do here, say N.
+
 config LOG_BUF_SHIFT
 	int "Kernel log buffer size" if DEBUG_KERNEL
 	default 17 if ARCH_S390
kernel/Makefile +1 -0
diff -Naur linux.org/kernel/Makefile linux.kernel.patched/kernel/Makefile
@@ -18,6 +18,7 @@
 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
 obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o
 obj-$(CONFIG_COMPAT) += compat.o
+obj-$(CONFIG_EVLOG) += evlog.o
 
 ifneq ($(CONFIG_IA64),y)
 # According to Alan Modra <[email protected]>, the -fno-omit-frame-pointer is
kernel/evlog.c +933 -0

933 lines not on this page · raw message

kernel/printk.c +22 -0
diff -Naur linux.org/kernel/printk.c linux.kernel.patched/kernel/printk.c
@@ -83,6 +83,13 @@
 struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
 static int preferred_console = -1;
 
+#ifdef CONFIG_EVLOG
+extern int evl_kbufread(char *, size_t);
+#endif
+#ifdef CONFIG_EVLOG_FWPRINTK
+extern int evl_fwd_printk(const char *fmt, va_list args, const char *msg);
+#endif
+
 /* Flag: console code may call schedule() */
 static int console_may_schedule;
 
@@ -154,6 +161,7 @@
  * 	7 -- Enable printk's to console
  *	8 -- Set level of messages printed to console
  *	9 -- Return number of unread characters in the log buffer
+ *     20 -- Read from event logging buffer 
  */
 int do_syslog(int type, char * buf, int len)
 {
@@ -268,6 +276,17 @@
 	case 9:		/* Number of chars in the log buffer */
 		error = log_end - log_start;
 		break;
+	case 20:
+#ifdef CONFIG_EVLOG
+		error = verify_area(VERIFY_WRITE, buf, len);
+		if (error) {
+			goto out;
+		}
+		error = evl_kbufread(buf, len);
+#else
+		error = -EIO;
+#endif
+		break;
 	default:
 		error = -EINVAL;
 		break;
@@ -408,6 +427,9 @@
 	/* Emit the output into the temporary buffer */
 	va_start(args, fmt);
 	printed_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args);
+#ifdef CONFIG_EVLOG_FWPRINTK
+	(void) evl_fwd_printk(fmt, args, printk_buf);
+#endif
 	va_end(args);
 
 	/*