kernel support for non-English user messages
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
@@ -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
@@ -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
@@ -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
@@ -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);/*