1*2912Sartem /*************************************************************************** 2*2912Sartem * CVSID: $Id$ 3*2912Sartem * 4*2912Sartem * logger.c : Logging 5*2912Sartem * 6*2912Sartem * Copyright (C) 2003 David Zeuthen, <david@fubar.dk> 7*2912Sartem * Copyright (C) 2006 Danny Kukawka, <danny.kukawka@web.de> 8*2912Sartem * 9*2912Sartem * Licensed under the Academic Free License version 2.1 10*2912Sartem * 11*2912Sartem * This program is free software; you can redistribute it and/or modify 12*2912Sartem * it under the terms of the GNU General Public License as published by 13*2912Sartem * the Free Software Foundation; either version 2 of the License, or 14*2912Sartem * (at your option) any later version. 15*2912Sartem * 16*2912Sartem * This program is distributed in the hope that it will be useful, 17*2912Sartem * but WITHOUT ANY WARRANTY; without even the implied warranty of 18*2912Sartem * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19*2912Sartem * GNU General Public License for more details. 20*2912Sartem * 21*2912Sartem * You should have received a copy of the GNU General Public License 22*2912Sartem * along with this program; if not, write to the Free Software 23*2912Sartem * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24*2912Sartem * 25*2912Sartem **************************************************************************/ 26*2912Sartem 27*2912Sartem #ifdef HAVE_CONFIG_H 28*2912Sartem # include <config.h> 29*2912Sartem #endif 30*2912Sartem 31*2912Sartem #include <stdio.h> 32*2912Sartem #include <stdlib.h> 33*2912Sartem #include <string.h> 34*2912Sartem #include <stdarg.h> 35*2912Sartem #include <time.h> 36*2912Sartem #include <sys/time.h> 37*2912Sartem #include <syslog.h> 38*2912Sartem #include <unistd.h> 39*2912Sartem 40*2912Sartem #include "logger.h" 41*2912Sartem 42*2912Sartem /** 43*2912Sartem * @defgroup HalDaemonLogging Logging system 44*2912Sartem * @ingroup HalDaemon 45*2912Sartem * @brief Logging system for the HAL daemon 46*2912Sartem * @{ 47*2912Sartem */ 48*2912Sartem 49*2912Sartem 50*2912Sartem static int priority; 51*2912Sartem static const char *file; 52*2912Sartem static int line; 53*2912Sartem static const char *function; 54*2912Sartem 55*2912Sartem static int log_pid = 0; 56*2912Sartem static int is_enabled = 1; 57*2912Sartem static int syslog_enabled = 0; 58*2912Sartem 59*2912Sartem 60*2912Sartem /** Disable all logging 61*2912Sartem * 62*2912Sartem */ 63*2912Sartem void 64*2912Sartem logger_disable (void) 65*2912Sartem { 66*2912Sartem is_enabled = 0; 67*2912Sartem } 68*2912Sartem 69*2912Sartem /** Enable all logging 70*2912Sartem * 71*2912Sartem */ 72*2912Sartem void 73*2912Sartem logger_enable (void) 74*2912Sartem { 75*2912Sartem is_enabled = 1; 76*2912Sartem } 77*2912Sartem 78*2912Sartem /** enable usage of syslog for logging 79*2912Sartem * 80*2912Sartem */ 81*2912Sartem void 82*2912Sartem logger_enable_syslog (void) 83*2912Sartem { 84*2912Sartem syslog_enabled = 1; 85*2912Sartem } 86*2912Sartem 87*2912Sartem /** disable usage of syslog for logging 88*2912Sartem * 89*2912Sartem */ 90*2912Sartem void 91*2912Sartem logger_disable_syslog (void) 92*2912Sartem { 93*2912Sartem syslog_enabled = 0; 94*2912Sartem } 95*2912Sartem 96*2912Sartem /** allow setup logger from a addon/prober via the env 97*2912Sartem * 98*2912Sartem */ 99*2912Sartem void 100*2912Sartem setup_logger (void) 101*2912Sartem { 102*2912Sartem if ((getenv ("HALD_VERBOSE")) != NULL) { 103*2912Sartem is_enabled = 1; 104*2912Sartem log_pid = 1; 105*2912Sartem } 106*2912Sartem else 107*2912Sartem is_enabled = 0; 108*2912Sartem 109*2912Sartem if ((getenv ("HALD_USE_SYSLOG")) != NULL) 110*2912Sartem syslog_enabled = 1; 111*2912Sartem else 112*2912Sartem syslog_enabled = 0; 113*2912Sartem } 114*2912Sartem 115*2912Sartem /** Setup logging entry 116*2912Sartem * 117*2912Sartem * @param priority Logging priority, one of HAL_LOGPRI_* 118*2912Sartem * @param file Name of file where the log entry originated 119*2912Sartem * @param line Line number of file 120*2912Sartem * @param function Name of function 121*2912Sartem */ 122*2912Sartem void 123*2912Sartem logger_setup (int _priority, const char *_file, int _line, const char *_function) 124*2912Sartem { 125*2912Sartem priority = _priority; 126*2912Sartem file = _file; 127*2912Sartem line = _line; 128*2912Sartem function = _function; 129*2912Sartem } 130*2912Sartem 131*2912Sartem /** Emit logging entry 132*2912Sartem * 133*2912Sartem * @param format Message format string, printf style 134*2912Sartem * @param ... Parameters for message, printf style 135*2912Sartem */ 136*2912Sartem void 137*2912Sartem logger_emit (const char *format, ...) 138*2912Sartem { 139*2912Sartem va_list args; 140*2912Sartem char buf[512]; 141*2912Sartem char *pri; 142*2912Sartem char tbuf[256]; 143*2912Sartem char logmsg[1024]; 144*2912Sartem struct timeval tnow; 145*2912Sartem struct tm *tlocaltime; 146*2912Sartem struct timezone tzone; 147*2912Sartem static pid_t pid = -1; 148*2912Sartem 149*2912Sartem if (!is_enabled) 150*2912Sartem return; 151*2912Sartem 152*2912Sartem va_start (args, format); 153*2912Sartem vsnprintf (buf, sizeof (buf), format, args); 154*2912Sartem 155*2912Sartem switch (priority) { 156*2912Sartem case HAL_LOGPRI_TRACE: 157*2912Sartem pri = "[T]"; 158*2912Sartem break; 159*2912Sartem case HAL_LOGPRI_DEBUG: 160*2912Sartem pri = "[D]"; 161*2912Sartem break; 162*2912Sartem case HAL_LOGPRI_INFO: 163*2912Sartem pri = "[I]"; 164*2912Sartem break; 165*2912Sartem case HAL_LOGPRI_WARNING: 166*2912Sartem pri = "[W]"; 167*2912Sartem break; 168*2912Sartem default: /* explicit fallthrough */ 169*2912Sartem case HAL_LOGPRI_ERROR: 170*2912Sartem pri = "[E]"; 171*2912Sartem break; 172*2912Sartem } 173*2912Sartem 174*2912Sartem gettimeofday (&tnow, &tzone); 175*2912Sartem tlocaltime = localtime (&tnow.tv_sec); 176*2912Sartem strftime (tbuf, sizeof (tbuf), "%H:%M:%S", tlocaltime); 177*2912Sartem 178*2912Sartem if (log_pid) { 179*2912Sartem if ((int) pid == -1) 180*2912Sartem pid = getpid (); 181*2912Sartem snprintf (logmsg, sizeof(logmsg), "[%d]: %s.%03d %s %s:%d: %s\n", pid, tbuf, (int)(tnow.tv_usec/1000), pri, file, line, buf); 182*2912Sartem } else { 183*2912Sartem snprintf (logmsg, sizeof(logmsg), "%s.%03d %s %s:%d: %s\n", tbuf, (int)(tnow.tv_usec/1000), pri, file, line, buf); 184*2912Sartem } 185*2912Sartem 186*2912Sartem /** @todo Make programmatic interface to logging */ 187*2912Sartem if (priority != HAL_LOGPRI_TRACE && !syslog_enabled ) { 188*2912Sartem fprintf (stderr, "%s", logmsg ); 189*2912Sartem } else if (priority != HAL_LOGPRI_TRACE && syslog_enabled ) { 190*2912Sartem /* use syslog for debug/log messages if HAL started as daemon */ 191*2912Sartem switch (priority) { 192*2912Sartem case HAL_LOGPRI_DEBUG: 193*2912Sartem case HAL_LOGPRI_INFO: 194*2912Sartem syslog(LOG_INFO, "%s", logmsg ); 195*2912Sartem break; 196*2912Sartem case HAL_LOGPRI_WARNING: 197*2912Sartem syslog(LOG_WARNING, "%s", logmsg ); 198*2912Sartem break; 199*2912Sartem default: /* explicit fallthrough */ 200*2912Sartem case HAL_LOGPRI_ERROR: 201*2912Sartem syslog(LOG_ERR, "%s", logmsg ); 202*2912Sartem break; 203*2912Sartem } 204*2912Sartem } 205*2912Sartem 206*2912Sartem va_end (args); 207*2912Sartem } 208*2912Sartem 209*2912Sartem void 210*2912Sartem logger_forward_debug (const char *format, ...) 211*2912Sartem { 212*2912Sartem va_list args; 213*2912Sartem char buf[512]; 214*2912Sartem char tbuf[256]; 215*2912Sartem struct timeval tnow; 216*2912Sartem struct tm *tlocaltime; 217*2912Sartem struct timezone tzone; 218*2912Sartem static pid_t pid = -1; 219*2912Sartem 220*2912Sartem if (!is_enabled) 221*2912Sartem return; 222*2912Sartem 223*2912Sartem if ((int) pid == -1) 224*2912Sartem pid = getpid (); 225*2912Sartem 226*2912Sartem va_start (args, format); 227*2912Sartem vsnprintf (buf, sizeof (buf), format, args); 228*2912Sartem 229*2912Sartem gettimeofday (&tnow, &tzone); 230*2912Sartem tlocaltime = localtime (&tnow.tv_sec); 231*2912Sartem strftime (tbuf, sizeof (tbuf), "%H:%M:%S", tlocaltime); 232*2912Sartem 233*2912Sartem if (syslog_enabled) 234*2912Sartem syslog (LOG_INFO, "%d: %s.%03d: %s", pid, tbuf, (int)(tnow.tv_usec/1000), buf); 235*2912Sartem else 236*2912Sartem fprintf (stderr, "%d: %s.%03d: %s", pid, tbuf, (int)(tnow.tv_usec/1000), buf); 237*2912Sartem 238*2912Sartem va_end (args); 239*2912Sartem } 240*2912Sartem 241*2912Sartem /** @} */ 242