xdasd_logger.c

Go to the documentation of this file.
00001 /*----------------------------------------------------------------------------
00002  * Copyright (c) 2006, Novell, Inc.
00003  * All rights reserved.
00004  * 
00005  * Redistribution and use in source and binary forms, with or without 
00006  * modification, are permitted provided that the following conditions are 
00007  * met:
00008  * 
00009  *     * Redistributions of source code must retain the above copyright 
00010  *       notice, this list of conditions and the following disclaimer.
00011  *     * Redistributions in binary form must reproduce the above copyright 
00012  *       notice, this list of conditions and the following disclaimer in the 
00013  *       documentation and/or other materials provided with the distribution.
00014  *     * Neither the name of the Novell nor the names of its contributors 
00015  *       may be used to endorse or promote products derived from this 
00016  *       software without specific prior written permission.
00017  * 
00018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
00019  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00020  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
00021  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
00022  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00023  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
00024  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
00025  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
00026  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
00027  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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    /* clear all loggers */
00263    memset(s_loggers, 0, sizeof(s_loggers));
00264 
00265    /* access logger list, if empty, return failure - there's no point
00266       in being loaded if there are no loggers registered. */
00267    (void)xdasd_conf_getstr("xdasd.loggers", buf, &bufsz);
00268    if (!bufsz) 
00269       return -1;
00270 
00271    /* separate comma separated names into an array */
00272    libfile = strtok(buf, ",");
00273    while (libfile != 0 && loadcnt < xdas_elemcount(s_loggers))
00274    {
00275       char * ep;
00276 
00277       /* strip leading whitespace */
00278       while (isspace(*libfile))
00279          libfile++;
00280 
00281       /* strip trailing white space */
00282       ep = libfile + strlen(libfile);
00283       while (ep > libfile && isspace(ep[-1]))
00284          *--ep = 0;
00285 
00286       /* if there's any file name remaining, prefix it and load it */
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             /* import all symbols */
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             /* if import succeeded and initialization succeeds... */
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    /* initialize the message cache sub-system */
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    /* create the logger message queue */
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 

Generated on Thu Aug 20 22:33:05 2009 for OpenXDAS by  doxygen 1.5.6