Main Page | Modules | Data Structures | File List | Data Fields

log.c

00001 /*
00002  * Copyright (c) 2005, 2006 by KoanLogic s.r.l. - All rights reserved.  
00003  */
00004 
00005 static const char rcsid[] =
00006     "$Id: log.c,v 1.9 2006/03/11 14:41:16 tat Exp $";
00007 
00008 #include <sys/types.h>
00009 #include <errno.h>
00010 #include <stdio.h>
00011 #include <string.h>
00012 #include <stdarg.h>
00013 #include <signal.h>
00014 #include <unistd.h>
00015 #include <u/log.h>
00016 #include <u/carpal.h>
00017 #include <u/misc.h>
00018 #include <u/os.h>
00019 #include <u/syslog.h>
00020 
00021 /* applications that use libu will defined their own "int facility" variable */
00022 extern int facility;
00023 
00024 /* log hook. if not-zero use this function to write log messages */
00025 static u_log_hook_t hook = NULL;
00026 static void *hook_arg = NULL;
00027 
00028 #ifdef OS_WIN
00029 #define err_type DWORD
00030 #define save_errno(var) var = GetLastError();
00031 #define restore_errno(var) SetLastError(var);
00032 #else
00033 #define err_type int
00034 #define save_errno(var) var = errno;
00035 #define restore_errno(var) errno = var;
00036 #endif
00037 
00038 static inline const char* u_log_label(int lev)
00039 {
00040     switch(lev)
00041     {
00042     case LOG_CRIT:   
00043         return "crt";
00044     case LOG_ERR:    
00045         return "err";
00046     case LOG_WARNING:
00047         return "wrn";
00048     case LOG_NOTICE: 
00049         return "not"; 
00050     case LOG_INFO:   
00051         return "inf"; 
00052     case LOG_DEBUG:  
00053         return "dbg"; 
00054     default: 
00055         syslog(LOG_WARNING, 
00056                "[wrn][%d:::] unknown log level: %d", getpid(), lev);
00057         return "unk";
00058     }
00059 }
00060 
00061 
00062 static int u_log(int fac, int level, const char *fmt, ...)
00063 {
00064     va_list ap;
00065     char buf[U_MAX_LOG_LENGTH];
00066 
00067     va_start(ap, fmt); 
00068 
00069     if(hook)
00070     {
00071         if(vsnprintf(buf, U_MAX_LOG_LENGTH, fmt, ap) > U_MAX_LOG_LENGTH)
00072         {
00073             va_end(ap);
00074             return ~0; /* buffer too small */
00075         }
00076         buf[U_MAX_LOG_LENGTH - 1] = 0; 
00077         hook(hook_arg, level, buf);
00078     } else 
00079         vsyslog(fac | level, fmt, ap);
00080 
00081     va_end(ap);
00082 
00083     return 0;
00084 }
00085 
00086 int u_log_set_hook(u_log_hook_t func, void *arg, u_log_hook_t *old, void **parg)
00087 {
00088     if(old)
00089         *old = hook;
00090     if(parg)
00091         *parg = hook_arg;
00092 
00093     hook = func;
00094     hook_arg = arg;
00095 
00096     return 0;
00097 }
00098 
00099 int u_log_write_ex(int fac, int lev, int ctx, const char* file, int line, 
00100     const char *func, const char* fmt, ...)
00101 {
00102     va_list ap;
00103     char msg[U_MAX_LOG_LENGTH];
00104     int rc;
00105     err_type savederr;
00106 
00107     save_errno(savederr);
00108 
00109     /* build the message to send to the log system */
00110     va_start(ap, fmt); 
00111     rc = vsnprintf(msg, U_MAX_LOG_LENGTH, fmt, ap);
00112     va_end(ap);
00113 
00114     if(rc > U_MAX_LOG_LENGTH)
00115         goto err; /* message too long */
00116 
00117     /* ok, send the msg to the logger */
00118     if(ctx)
00119         u_log(fac, lev, "[%s][%d:%s:%d:%s] %s", 
00120                u_log_label(lev), getpid(), file, line, func, msg);
00121     else
00122         u_log(fac, lev, "[%s][%d:::] %s", 
00123                u_log_label(lev), getpid(), msg);
00124 
00125     restore_errno(savederr);
00126     return 0;
00127 err:
00128     restore_errno(savederr);
00129     return ~0;
00130 }

←Products
© 2005-2006 - KoanLogic S.r.l. - All rights reserved