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