xdasd_logger.c
Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00039 #include <xdas_base.h>
00040 
00041 #include "xdasd_logger.h"
00042 #include "xdasd_parse.h"
00043 #include "xdasd_mqueue.h"
00044 #include "xdasd_mcache.h"
00045 #include "xdasd_conf.h"
00046 #include "xdasd_log.h"
00047 
00048 #include <stdio.h>
00049 #include <string.h>
00050 
00055 #ifdef _WIN32
00056 # define WIN32_LEAN_AND_MEAN
00057 # include <windows.h>
00058 #else
00059 # include <sys/types.h>
00060 # include <sys/stat.h>
00061 # include <dlfcn.h>
00062 #endif
00063 
00065 #define XDASD_MAX_LOGGERS 16
00066 
00070 #define XDM_INIT_SYM_NAME "xdm_init"
00071 #define XDM_APND_SYM_NAME "xdm_append"
00072 #define XDM_EXIT_SYM_NAME "xdm_exit"
00073 
00074 
00076 typedef void * xdasd_lib_t;
00077 
00079 typedef void (*xdasd_fptr_t)(void);
00080 
00082 typedef int logger_init_fn_t(void (*logmsg)(int level, const char *, ... ), 
00083       char * (*getcnfstr)(const char *, char *, size_t *));
00084 typedef int logger_apnd_fn_t(const char ** fields);
00085 typedef void logger_exit_fn_t(void);
00086 
00088 typedef struct xdasd_logger_tag
00089 {
00090    xdasd_lib_t lib;
00091    logger_init_fn_t * init_fn;
00092    logger_apnd_fn_t * apnd_fn;
00093    logger_exit_fn_t * exit_fn;
00094    char fname[FILENAME_MAX];
00095 } xdasd_logger_t;
00096 
00098 static xdasd_logger_t s_loggers[XDASD_MAX_LOGGERS];
00099 static MsgQueue s_mq_logger = 0;
00100 static MsgCache s_mcache = 0;
00101 
00110 static xdasd_lib_t xdasd_load_library(const char * libname)
00111 {
00112 #ifdef _WIN32
00113    return (xdasd_lib_t)LoadLibraryA(libname);
00114 #else
00115    return (xdasd_lib_t)dlopen(libname, RTLD_NOW | RTLD_LOCAL);
00116 #endif
00117 }
00118 
00128 static xdasd_fptr_t xdasd_import_symbol(xdasd_lib_t lib, const char * sym)
00129 {
00130 #ifdef _WIN32
00131    return (xdasd_fptr_t)GetProcAddress((HANDLE)lib, sym);
00132 #else
00133    return (xdasd_fptr_t)dlsym((void *)lib, sym);
00134 #endif
00135 }
00136 
00143 static void xdasd_free_library(xdasd_lib_t lib)
00144 {
00145 #ifdef _WIN32
00146    FreeLibrary((HANDLE)lib);
00147 #else
00148    dlclose((void *)lib);
00149 #endif
00150 }
00151 
00156 void logger_clear(void)
00157 {
00158    xdasd_logger_t * p = s_loggers;
00159    while (p->lib)
00160    {
00161       xdasd_log(0, "Logger %s unloading.\n", p->fname);
00162       xdasd_free_library(p->lib);
00163       p++;
00164    }
00165    memset(s_loggers, 0, sizeof(s_loggers));
00166 }
00167 
00176 static int logger_put(void * data)
00177 {
00178    return xdasd_mcache_put_msg(s_mcache, (Parsed *)data);
00179 }
00180 
00188 static void * logger_get(void)
00189 {
00190    return xdasd_mcache_get_msg(s_mcache);
00191 } 
00192 
00206 static void logger_append(void * data)
00207 {
00208    Parsed * parsed = (Parsed *)data;
00209 
00210    int logged = 0;
00211    xdasd_logger_t * p = s_loggers;
00212 
00213    while (p->lib)
00214    {
00215       if ((*p->apnd_fn)(parsed->parsed) == 0)
00216          logged = 1;
00217       p++;
00218    }
00219    if (!logged) 
00220       xdasd_log(0, "logger: All loggers FAILED to log message:\n[ %s ]\n", 
00221             parsed->msg);
00222 
00223    xdasd_parse_free(parsed);
00224 }
00225 
00229 
00230 
00239 int xdasd_logger_append(Parsed * parsed)
00240 {
00241    return xdasd_mqueue_append(s_mq_logger, parsed);
00242 }
00243 
00255 int xdasd_logger_init(const char * msgfdir)
00256 {
00257    char * libfile;
00258    char buf[4096];
00259    size_t bufsz = sizeof(buf);
00260    unsigned loadcnt = 0;
00261 
00262    
00263    memset(s_loggers, 0, sizeof(s_loggers));
00264 
00265    
00266 
00267    (void)xdasd_conf_getstr("xdasd.loggers", buf, &bufsz);
00268    if (!bufsz) 
00269       return -1;
00270 
00271    
00272    libfile = strtok(buf, ",");
00273    while (libfile != 0 && loadcnt < xdas_elemcount(s_loggers))
00274    {
00275       char * ep;
00276 
00277       
00278       while (isspace(*libfile))
00279          libfile++;
00280 
00281       
00282       ep = libfile + strlen(libfile);
00283       while (ep > libfile && isspace(ep[-1]))
00284          *--ep = 0;
00285 
00286       
00287       if (*libfile)
00288       {
00289          xdasd_lib_t lib;
00290 
00291          if ((lib = xdasd_load_library(libfile)) != 0)
00292          {
00293             logger_init_fn_t * init_fn;
00294             logger_apnd_fn_t * apnd_fn;
00295             logger_exit_fn_t * exit_fn;
00296 
00297             
00298             init_fn = (logger_init_fn_t *)xdasd_import_symbol(lib, XDM_INIT_SYM_NAME);
00299             apnd_fn = (logger_apnd_fn_t *)xdasd_import_symbol(lib, XDM_APND_SYM_NAME);
00300             exit_fn = (logger_exit_fn_t *)xdasd_import_symbol(lib, XDM_EXIT_SYM_NAME);
00301 
00302             
00303             if (init_fn != 0 && apnd_fn != 0 && exit_fn != 0 
00304                   && (*init_fn)(xdasd_log, xdasd_conf_getstr) == 0)
00305             {
00306                s_loggers[loadcnt].lib = lib;
00307                s_loggers[loadcnt].init_fn = init_fn;
00308                s_loggers[loadcnt].apnd_fn = apnd_fn;
00309                s_loggers[loadcnt].exit_fn = exit_fn;
00310                strncpy(s_loggers[loadcnt].fname, libfile, FILENAME_MAX - 1);
00311                s_loggers[loadcnt].fname[FILENAME_MAX - 1] = 0;
00312                loadcnt++;
00313                xdasd_log(0, "Logger %s loaded and initialized.\n", libfile);
00314             }
00315             else
00316             {
00317                if (init_fn == 0 || apnd_fn == 0 || exit_fn == 0)
00318                   xdasd_log(0, "Logger %s FAILED. Missing required symbols.\n", libfile);
00319                else
00320                   xdasd_log(0, "Logger %s FAILED. Initialization failure.\n", libfile);
00321                xdasd_free_library(lib);
00322             }
00323          }
00324          else
00325             xdasd_log(0, "Logger %s FAILED. Load failure.\n", libfile);
00326       }
00327       libfile = strtok(0, ",");
00328    }
00329    if (loadcnt == 0)
00330    {
00331       xdasd_log(0, "logger: No back-end loggers loaded.\n");
00332       return -1;
00333    }
00334 
00335    
00336    if ((s_mcache = xdasd_mcache_create(msgfdir)) == 0)
00337    {
00338       xdasd_log(0, "logger: Unable to create the persistent message cache.\n");
00339       logger_clear();
00340       return -1;
00341    }
00342 
00343    
00344    if ((s_mq_logger = xdasd_mqueue_create(logger_put, logger_get, logger_append)) == 0)
00345    {
00346       xdasd_log(0, "logger: Unable to create logger message queue.\n");
00347       xdasd_mcache_destroy(s_mcache);
00348       logger_clear();
00349       return -1;
00350    }
00351    return 0;
00352 }
00353 
00358 void xdasd_logger_exit(void)
00359 {
00360    xdasd_mqueue_destroy(s_mq_logger);
00361    xdasd_mcache_destroy(s_mcache);
00362    logger_clear();
00363 }
00364