Mercurial > hg > waaad
view waaad/log.c @ 313:082d8f33f645
Temporary fix
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Wed, 25 Feb 2009 10:50:44 +0900 |
parents | c2f839305f23 |
children | 987cea8b1e37 |
line wrap: on
line source
/********************************************************************************************************* * Software License Agreement (BSD License) * * Author: Sebastien Decugis <sdecugis@nict.go.jp> * * * * Copyright (c) 2008, WIDE Project and NICT * * All rights reserved. * * * * Redistribution and use of this software in source and binary forms, with or without modification, are * * permitted provided that the following conditions are met: * * * * * Redistributions of source code must retain the above * * copyright notice, this list of conditions and the * * following disclaimer. * * * * * Redistributions in binary form must reproduce the above * * copyright notice, this list of conditions and the * * following disclaimer in the documentation and/or other * * materials provided with the distribution. * * * * * Neither the name of the WIDE Project or NICT nor the * * names of its contributors may be used to endorse or * * promote products derived from this software without * * specific prior written permission of WIDE Project and * * NICT. * * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED * * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *********************************************************************************************************/ /* Log facility. * * All messages generated by the application and extensions should be passed to one of the functions in this file. * * log_error : message is saved in syslog as error and/or sent to stderr. * log_normal: message is saved in syslog as info and/or sent to stdout. * log_debug : message is sent to stdout only. * * See log.h and log-api.h for more information on the functions * */ #include "waaad-internal.h" #include <stdarg.h> #include <syslog.h> #include <unistd.h> /* Save the facilities where the logs must be sent */ static int log_to = 0; pthread_key_t thread_name; /* Mutex to protect concurrent accesses to the logs */ pthread_mutex_t log_mtx = PTHREAD_MUTEX_INITIALIZER; /* Function to init/fini the log to the syslog */ static int log_init_syslog( void ) { /* open the log */ #ifndef PROJECT_NAME #define PROJECT_NAME PACKAGE_NAME #endif openlog(PROJECT_NAME, LOG_ODELAY, 0); /* Return */ return 0; } static int log_fini_syslog( void ) { /* close the log */ closelog(); /* Return */ return 0; } /* Function to init/fini the log to the console */ static int log_init_console( void ) { /* Nothing to do */ return 0; } static int log_fini_console( void ) { /* Nothing to do */ return 0; } /* Function to init/fini the log to a file */ static int log_init_file( void ) { fprintf (stderr, "Logging to file is not yet supported\n"); /* Return */ return ENOTSUP; } static int log_fini_file( void ) { fprintf (stderr, "Logging to file is not yet supported\n"); /* Return */ return ENOTSUP; } /* Function to set the thread's friendly name (usually called with THREAD_NAME) */ void log_set_thread_name(char * name, char * cat) { void * val = NULL; TRACE_ENTRY("%p(%s) %p(%s)", name, name?:"/", cat, cat?:"/") /* First, check if a value is already assigned to the current thread */ val = pthread_getspecific(thread_name); if (val != NULL) { TRACE_DEBUG(INFO, "Freeing old thread name: %s", val); free(val); } /* Now create the new string */ if (name == NULL) { CHECK_POSIX_DO( pthread_setspecific(thread_name, NULL), /* continue */); return; } if (cat == NULL) { CHECK_MALLOC_DO( val = strdup(name), return ); } else { CHECK_MALLOC_DO( val = malloc(strlen(name) + strlen(cat) + 2), return ); sprintf(val, "%s/%s", cat, name); } CHECK_POSIX_DO( pthread_setspecific(thread_name, val), /* continue */); return; } /* Initialize the log facility */ int log_init ( int flags ) { int ret; if (flags == 0) { fprintf (stderr, "invalid flags in log_init\n"); return EINVAL; } ret = pthread_key_create(&thread_name, free); if (ret != 0) { fprintf (stderr, "Error in pthread_key_create: %s\n", strerror(ret)); return ret; } ret = pthread_mutex_lock(&log_mtx); if (ret < 0) { fprintf (stderr, "pthread_mutex_lock failed\n"); return ret; } if (log_to != 0) { fprintf (stderr, "Module already initialized\n"); ret = EINVAL; goto error; } /* Save the value */ log_to = flags; /* Init the facilities */ if ( log_to & LOG_TO_SYSLOG ) { ret = log_init_syslog(); if (ret < 0) { goto error; } } if ( log_to & LOG_TO_CONSOLE ) { ret = log_init_console(); if (ret < 0) { goto error; } } if ( log_to & LOG_TO_FILE ) { ret = log_init_file(); if (ret < 0) { goto error; } } ret = 0; error: /* Unlock the mutex and return ret */ (void) pthread_mutex_unlock(&log_mtx); if (ret == 0) { TRACE_DEBUG(FULL, "Log facility initialized"); } return ret; } /* Reinit the facility */ int log_reinit ( int flags ) { int ret = 0; ret = pthread_mutex_lock(&log_mtx); if (ret < 0) { fprintf (stderr, "pthread_mutex_lock failed\n"); return ret; } /* log_to contains the previous facilities, flags contains the new ones */ if ( (log_to ^ flags) & LOG_TO_SYSLOG ) { if (flags & LOG_TO_SYSLOG ) { /* Start the syslog facility */ ret = log_init_syslog(); if (ret < 0) { goto error; } log_to |= LOG_TO_SYSLOG; } else { /* Stop the syslog facility */ (void) log_fini_syslog(); log_to &= ~LOG_TO_SYSLOG; } } if ( (log_to ^ flags) & LOG_TO_CONSOLE ) { if (flags & LOG_TO_CONSOLE ) { /* Start the syslog facility */ ret = log_init_console(); if (ret < 0) { goto error; } log_to |= LOG_TO_CONSOLE; } else { /* Stop the syslog facility */ (void) log_fini_console(); log_to &= ~LOG_TO_CONSOLE; } } /* For file, we would have to reinit in all case since the file may have changed */ if ( flags & LOG_TO_FILE ) { fprintf (stderr, "Logging to file is not yet supported\n"); /* Return */ ret = ENOTSUP; } ret = 0; error: /* Unlock the mutex and return ret */ (void) pthread_mutex_unlock(&log_mtx); return ret; } /* Terminate the facility */ int log_fini ( void ) { int ret; TRACE_ENTRY(); ret = pthread_mutex_lock(&log_mtx); if (ret < 0) { fprintf (stderr, "pthread_mutex_lock failed\n"); return ret; } if (log_to == 0) { fprintf (stderr, "Module not initialized\n"); ret = EINVAL; goto error; } /* Close the facilities */ if ( log_to & LOG_TO_SYSLOG ) { (void) log_fini_syslog(); } if ( log_to & LOG_TO_CONSOLE ) { (void) log_fini_console(); } if ( log_to & LOG_TO_FILE ) { (void) log_fini_file(); } /* Destroy the key */ (void)pthread_key_delete(thread_name); log_to = 0; ret = 0; error: /* Unlock the mutex and return ret */ (void) pthread_mutex_unlock(&log_mtx); return ret; } /* Write current time into a buffer */ char * log_time(char * buf, size_t len) { int ret; size_t offset = 0; struct timespec tp; struct tm tm; /* Get current time */ ret = clock_gettime(CLOCK_REALTIME, &tp); if (ret != 0) { snprintf(buf, len, "%s", strerror(ret)); return buf; } offset += strftime(buf + offset, len - offset, "%D,%T", localtime_r( &tp.tv_sec , &tm )); offset += snprintf(buf + offset, len - offset, ".%6.6ld", tp.tv_nsec / 1000); #if 0 /* Removed cause it is not very useful... */ #if defined(_POSIX_CPUTIME) && (_POSIX_CPUTIME != -1) if ((ret = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp))) { snprintf(buf + offset, len - offset, "(%s)", strerror(ret)); } else { long sec; offset += snprintf(buf + offset, len - offset, "(pr:%ldd", tp.tv_sec / 86400); sec = tp.tv_sec % 86400; offset += strftime(buf + offset, len - offset, "%T", gmtime_r( &sec , &tm )); offset += snprintf(buf + offset, len - offset, ".%6.6ld)", tp.tv_nsec / 1000); } #endif /* _POSIX_CPUTIME */ #if defined(_POSIX_THREAD_CPUTIME) && (_POSIX_THREAD_CPUTIME != -1) if ((ret = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp))) { snprintf(buf + offset, len - offset, "(%s)", strerror(ret)); } else { long sec; offset += snprintf(buf + offset, len - offset, "(th:%ldd", tp.tv_sec / 86400); sec = tp.tv_sec % 86400; offset += strftime(buf + offset, len - offset, "%T", gmtime_r( &sec , &tm )); offset += snprintf(buf + offset, len - offset, ".%6.6ld)", tp.tv_nsec / 1000); } #endif #endif /* 0 */ return buf; } /* Log an error message */ void log_error ( char * format, ... ) { int ret; va_list ap; ret = pthread_mutex_lock(&log_mtx); if (ret < 0) { fprintf (stderr, "pthread_mutex_lock failed\n"); return; } pthread_cleanup_push(cleanup_mutex, &log_mtx); if ( log_to & LOG_TO_SYSLOG ) { va_start(ap, format); vsyslog( LOG_ERR, format, ap); va_end(ap); } if ( log_to & LOG_TO_CONSOLE ) { va_start(ap, format); fprintf( stderr, "[ERR] "); vfprintf( stderr, format, ap); va_end(ap); fflush(stderr); } if ( log_to & LOG_TO_FILE ) { /* ignore yet, not supported */ ASSERT(0); } /* Unlock the mutex and return ret */ pthread_cleanup_pop(0); (void) pthread_mutex_unlock(&log_mtx); return; } /* Log a normal message */ void log_normal ( char * format, ... ) { int ret; va_list ap; ret = pthread_mutex_lock(&log_mtx); if (ret < 0) { fprintf (stderr, "pthread_mutex_lock failed\n"); return; } pthread_cleanup_push(cleanup_mutex, &log_mtx); if ( log_to & LOG_TO_SYSLOG ) { va_start(ap, format); vsyslog( LOG_INFO, format, ap); va_end(ap); } if ( log_to & LOG_TO_CONSOLE ) { va_start(ap, format); fprintf( stdout, "[NRM] "); vfprintf( stdout, format, ap); va_end(ap); fflush(stdout); } if ( log_to & LOG_TO_FILE ) { /* ignore yet, not supported */ ASSERT(0); } /* Unlock the mutex and return ret */ pthread_cleanup_pop(0); (void) pthread_mutex_unlock(&log_mtx); return; } /* Log a debug message */ void log_debug ( char * format, ... ) { int ret; va_list ap; /* If "quiet" has been specified, do not issue debug */ if (g_conf->log_verbose < 0) return; ret = pthread_mutex_lock(&log_mtx); if (ret < 0) { fprintf (stderr, "pthread_mutex_lock failed\n"); return; } pthread_cleanup_push(cleanup_mutex, &log_mtx); if ( log_to & LOG_TO_SYSLOG ) { va_start(ap, format); vsyslog( LOG_DEBUG, format, ap); va_end(ap); } if ( log_to & LOG_TO_CONSOLE ) { va_start(ap, format); fprintf( stdout, "[DBG] "); vfprintf( stdout, format, ap); va_end(ap); fflush(stdout); } if ( log_to & LOG_TO_FILE ) { /* ignore yet, not supported */ ASSERT(0); } /* Unlock the mutex and return ret */ pthread_cleanup_pop(0); (void) pthread_mutex_unlock(&log_mtx); return; }