00001
00002
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
00022 extern int facility;
00023
00024
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;
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
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;
00116
00117
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 }