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