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