Guys
See the attach patch, this implements a xentoollog consumer that can log
in to syslog
Following are the changes
xentoollog.h:
1) Generic, xtl_logger_set_minlevel and xtl_logger_adjust_flags
functions to be called from outside,
2) Making logger flags to be more generic
3) Change the struct xentool_logger, each logger will implement its own
"set_minlevel" and "adjust_flags" which will be invoked by
xtl_logger_set_minlevel and xtl_logger_adjust_flags generic functions.
4) New function prototype to create a xentool_logger_syslogger
Going forward I would like to suggest that xentoollog.h file should only
have generic functions, except for xtl_createlogger_* functions. Logger
type specific function should not be included(e.g
xtl_stdiostream_set_minlevel ) this will make sure outside code can
switch from one logger to another (from stdiologger to syslogger vice
versa) with out breaking the code.
xtl_core.c:
1) Implementation of xtl_logger_set_minlevel and xtl_logger_adjust_flags
functions.
xtl_logger_syslog.c :
New logger implementation to log in to syslog.
I did some testing by changing the code in xl. This seems to work, but I
would really like if more people can test this.
Also could someone look @ the syslogger_progress function and add any
extra bits if needed, I did a very basic implementation of this.
Signed-off-by : Gihan Munasinghe <GMunasinghe@xxxxxxxxxxxx>
Thanks
Gihan
diff -Nuar a/tools/libxc/Makefile b/tools/libxc/Makefile
--- a/tools/libxc/Makefile 2010-06-01 23:32:43.000000000 +0100
+++ b/tools/libxc/Makefile 2010-06-03 22:56:42.000000000 +0100
@@ -29,6 +29,7 @@
CTRL_SRCS-y += xc_memshr.c
CTRL_SRCS-y += xtl_core.c
CTRL_SRCS-y += xtl_logger_stdio.c
+CTRL_SRCS-y += xtl_logger_syslog.c
CTRL_SRCS-$(CONFIG_X86) += xc_pagetab.c
CTRL_SRCS-$(CONFIG_Linux) += xc_linux.c
CTRL_SRCS-$(CONFIG_SunOS) += xc_solaris.c
diff -Nuar a/tools/libxc/xentoollog.h b/tools/libxc/xentoollog.h
--- a/tools/libxc/xentoollog.h 2010-06-01 23:32:43.000000000 +0100
+++ b/tools/libxc/xentoollog.h 2010-06-04 22:49:54.000000000 +0100
@@ -45,16 +45,28 @@
* will always be called with done==0 for each new
* context/doing_what */;
void (*destroy)(struct xentoollog_logger *logger);
+ void (*set_minlevel)(xentoollog_logger *logger,
+ xentoollog_level min_level);
+ void (*adjust_flags)(xentoollog_logger *logger,
+ unsigned set_flags, unsigned clear_flags);
/* each logger can put its necessary data here */
+
};
/*---------- facilities for consuming log messages ----------*/
+//-- Should be depricated not generic enough --//
#define XTL_STDIOSTREAM_SHOW_PID 01u
#define XTL_STDIOSTREAM_SHOW_DATE 02u
#define XTL_STDIOSTREAM_HIDE_PROGRESS 04u
+//---Plase use the following as the new flags when creating and setting loggers
+#define XTL_SHOW_PID 01u
+#define XTL_SHOW_DATE 02u
+#define XTL_HIDE_PROGRESS 04u
+
+
typedef struct xentoollog_logger_stdiostream xentoollog_logger_stdiostream;
xentoollog_logger_stdiostream *xtl_createlogger_stdiostream
@@ -62,15 +74,47 @@
/* may return 0 if malloc fails, in which case error was logged */
/* destroy on this logger does not close the file */
+//This method need to be depricated use more generic xtl_logger_set_minlevel
method insted
void xtl_stdiostream_set_minlevel(xentoollog_logger_stdiostream*,
xentoollog_level min_level);
+
+//This method need to be depricated use more generic xtl_logger_adjust_flags
method insted.
void xtl_stdiostream_adjust_flags(xentoollog_logger_stdiostream*,
unsigned set_flags, unsigned clear_flags);
/* if set_flags and clear_flags overlap, set_flags takes precedence */
+
+typedef struct xentoollog_logger_syslogger xentoollog_logger_syslogger;
+
+/**
+Create a logger that will log to syslog
+syslog_facility is the facilities that are in the sys/syslog.h
+edit /etc/syslog.conf file to indicate where you wansyslog to send log data
+
+example config:-
+Add the following line in to /etc/syslog.conf
+
+local1.* /var/log/xenlog
+restart syslogd
+When setting up the logger give LOG_LOCAL1 as the logging facility
+now all your logs will appear in /var/log/xenlog file
+
+Please look more in to syslog and syslogng configs if you want to send the
data in to remote logging servers
+
+NOTE: XTL_SHOW_DATE flag will not take any effect as syslogd will put the date
by default
+**/
+xentoollog_logger_syslogger *xtl_createlogger_syslogger
+ (int syslog_facility, xentoollog_level min_level, unsigned flags);
+
void xtl_logger_destroy(struct xentoollog_logger *logger /* 0 is ok */);
+void xtl_logger_set_minlevel(struct xentoollog_logger *logger,xentoollog_level
min_level);
+
+void xtl_logger_adjust_flags(struct xentoollog_logger *logger,
+ unsigned set_flags, unsigned clear_flags);
+
+
/*---------- facilities for generating log messages ----------*/
void xtl_logv(struct xentoollog_logger *logger,
@@ -104,6 +148,8 @@
(buffer).vtable.vmessage = LOGGER##_vmessage; \
(buffer).vtable.progress = LOGGER##_progress; \
(buffer).vtable.destroy = LOGGER##_destroy; \
+ (buffer).vtable.set_minlevel = LOGGER##_set_minlevel; \
+ (buffer).vtable.adjust_flags = LOGGER##_adjust_flags; \
\
new_consumer = malloc(sizeof(*new_consumer)); \
if (!new_consumer) { \
diff -Nuar a/tools/libxc/xtl_core.c b/tools/libxc/xtl_core.c
--- a/tools/libxc/xtl_core.c 2010-06-01 23:32:43.000000000 +0100
+++ b/tools/libxc/xtl_core.c 2010-06-04 21:34:55.000000000 +0100
@@ -63,7 +63,23 @@
logger->progress(logger, context, doing_what, percent, done, total);
}
+void xtl_logger_set_minlevel(struct xentoollog_logger *logger,
+ xentoollog_level min_level){
+ if (!logger || !logger->set_minlevel) return;
+
+ logger->set_minlevel(logger,min_level);
+}
+
+void xtl_logger_adjust_flags(struct xentoollog_logger *logger,
+ unsigned set_flags, unsigned clear_flags){
+ if (!logger || !logger->adjust_flags) return;
+
+ logger->adjust_flags(logger,set_flags,clear_flags);
+}
+
+
void xtl_logger_destroy(struct xentoollog_logger *logger) {
- if (!logger) return;
+ if (!logger || !logger->destroy) return;
+
logger->destroy(logger);
}
diff -Nuar a/tools/libxc/xtl_logger_stdio.c b/tools/libxc/xtl_logger_stdio.c
--- a/tools/libxc/xtl_logger_stdio.c 2010-06-01 23:32:43.000000000 +0100
+++ b/tools/libxc/xtl_logger_stdio.c 2010-06-04 21:44:52.000000000 +0100
@@ -124,6 +124,20 @@
lg->flags = new_flags;
}
+static void stdiostream_set_minlevel(struct xentoollog_logger *logger_in,
+ xentoollog_level min_level){
+
+ xentoollog_logger_stdiostream *lg = (void*)logger_in;
+ xtl_stdiostream_set_minlevel(lg,min_level);
+}
+
+static void stdiostream_adjust_flags(struct xentoollog_logger *logger_in,
+ unsigned set_flags, unsigned clear_flags) {
+
+ xentoollog_logger_stdiostream *lg = (void*)logger_in;
+ xtl_stdiostream_adjust_flags(lg,set_flags,clear_flags);
+}
+
xentoollog_logger_stdiostream *xtl_createlogger_stdiostream
(FILE *f, xentoollog_level min_level, unsigned flags) {
xentoollog_logger_stdiostream newlogger;
diff -Nuar a/tools/libxc/xtl_logger_syslog.c b/tools/libxc/xtl_logger_syslog.c
--- a/tools/libxc/xtl_logger_syslog.c 1970-01-01 01:00:00.000000000 +0100
+++ b/tools/libxc/xtl_logger_syslog.c 2010-06-05 00:52:09.000000000 +0100
@@ -0,0 +1,152 @@
+/**
+*xtl_logger_syslog.c
+*
+*xentool log comsumer implementation, that will log into syslog
+*
+*Copyright (c) 2010 Flexiant Ltd.
+**/
+#include "xentoollog.h"
+
+#include <sys/syslog.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <pthread.h>
+
+typedef struct _log_map{
+ xentoollog_level xen_log;
+ int syslog_level;
+}LOG_MAP;
+
+LOG_MAP log_mappings[] =
+ {
+ {XTL_DEBUG,LOG_DEBUG},
+ {XTL_VERBOSE,LOG_DEBUG},
+ {XTL_DETAIL,LOG_DEBUG},
+ {XTL_PROGRESS,LOG_DEBUG},
+ {XTL_INFO,LOG_INFO},
+ {XTL_NOTICE,LOG_NOTICE},
+ {XTL_WARN,LOG_WARNING},
+ {XTL_ERROR,LOG_ERR},
+ {XTL_CRITICAL,LOG_CRIT}
+ };
+
+int maptable_len = sizeof(log_mappings)/sizeof(LOG_MAP);
+
+
+struct xentoollog_logger_syslogger{
+ xentoollog_logger vtable;
+ pthread_mutex_t mutex; //syslog in not thread safe at all therefore we
need a lock before issue a syslog call
+ unsigned flags;
+};
+
+/**
+Returns mapping syslog level for a given xentoollog_level
+**/
+static int get_syslog_level(xentoollog_level level){
+ int i;
+ for (i=0; i<maptable_len; i++){
+ LOG_MAP map = log_mappings[i];
+ if (map.xen_log==level){
+ return map.syslog_level;
+ }
+ }
+ // If a mapping is not found use LOG_INFO as default
+ return LOG_INFO;
+}
+
+
+static void syslogger_vmessage(xentoollog_logger *logger_in,
+ xentoollog_level level,
+ int errnoval,
+ const char *context,
+ const char *format,
+ va_list al) {
+ char *buffer;
+ xentoollog_logger_syslogger *lg = (void*)logger_in;
+
+ buffer = (char *)calloc(1024,sizeof(char));
+ if (context && (lg->flags & XTL_SHOW_PID)){
+ char *new_format = (char *) calloc(13+strlen(context)+10,sizeof(char));
+ sprintf(new_format,"[%s] [%lu] : ",context,(unsigned long)getpid());
+ strcat(buffer,new_format);
+ free(new_format);
+
+ }else if(context){
+ char *new_format = (char *) calloc(7+strlen(context),sizeof(char));
+ sprintf(new_format,"[%s] : ",context);
+ strcat(buffer,new_format);
+ free(new_format);
+
+ }else if(lg->flags & XTL_SHOW_PID){
+ char *new_format = (char *) calloc(18,sizeof(char));
+ sprintf(new_format,"[%lu] : ",(unsigned long)getpid());
+ strcat(buffer,new_format);
+ free(new_format);
+
+ }
+
+ if (errnoval >= 0){
+ char *new_format = (char *) calloc(100,sizeof(char));
+ sprintf(new_format,"[%s] : ",strerror(errnoval));
+ strcat(buffer,new_format);
+ free(new_format);
+ }
+
+ strcat(buffer,format);
+
+ pthread_mutex_lock(&lg->mutex);
+ vsyslog(get_syslog_level(level),buffer,al);
+ pthread_mutex_unlock(&lg->mutex);
+
+ free(buffer);
+}
+
+static void syslogger_progress(struct xentoollog_logger *logger_in,
+ const char *context,
+ const char *doing_what, int percent,
+ unsigned long done, unsigned long total){
+ xentoollog_logger_syslogger *lg = (void *)logger_in;
+
+ pthread_mutex_lock(&lg->mutex);
+ syslog(get_syslog_level(XTL_PROGRESS),"%s%s" "%s: %lu/%lu %3d%%",
+ context?context:"", context?": ":"",
+ doing_what, done, total, percent);
+ pthread_mutex_unlock(&lg->mutex);
+}
+
+static void syslogger_destroy(struct xentoollog_logger *logger_in) {
+ xentoollog_logger_syslogger *lg = (void*)logger_in;
+ closelog();
+ pthread_mutex_destroy(&lg->mutex);
+ free(lg);
+}
+
+static void syslogger_set_minlevel(struct xentoollog_logger *logger_in,
+ xentoollog_level minlevel){
+ setlogmask(LOG_UPTO(get_syslog_level(minlevel)));
+}
+
+static void syslogger_adjust_flags(struct xentoollog_logger *logger_in,
+ unsigned set_flags, unsigned clear_flags){
+ xentoollog_logger_syslogger *lg = (void *)logger_in;
+ unsigned new_flags = (lg->flags & ~clear_flags) | set_flags;
+ lg->flags = new_flags;
+}
+
+xentoollog_logger_syslogger *xtl_createlogger_syslogger
+ (int syslog_facility, xentoollog_level min_level, unsigned flags) {
+
+ xentoollog_logger_syslogger newlogger;
+ newlogger.flags = flags;
+ pthread_mutex_init(&newlogger.mutex,NULL);;
+
+ openlog("",LOG_CONS | LOG_NDELAY,syslog_facility);
+ setlogmask(LOG_UPTO(get_syslog_level(min_level)));
+
+ return XTL_NEW_LOGGER(syslogger, newlogger);
+}
+
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|