2 * Copyright (c) 2009-2010 The FreeBSD Foundation
5 * This software was developed by Pawel Jakub Dawidek under sponsorship from
6 * the FreeBSD Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
45 static int pjdlog_mode = PJDLOG_MODE_STD;
46 static int pjdlog_debug_level = 0;
47 static char pjdlog_prefix[128];
50 * Configure where the logs should go.
51 * By default they are send to stdout/stderr, but after going into background
52 * (eg. by calling daemon(3)) application is responsible for changing mode to
53 * PJDLOG_MODE_SYSLOG, so logs will be send to syslog.
56 pjdlog_mode_set(int mode)
59 assert(mode == PJDLOG_MODE_STD || mode == PJDLOG_MODE_SYSLOG);
65 * Return current mode.
75 * Set debug level. All the logs above the level specified here will be
79 pjdlog_debug_set(int level)
84 pjdlog_debug_level = level;
88 * Return current debug level.
91 pjdlog_debug_get(void)
94 return (pjdlog_debug_level);
98 * Set prefix that will be used before each log.
99 * Setting prefix to NULL will remove it.
102 pjdlog_prefix_set(const char *fmt, ...)
107 pjdlog_prefix_setv(fmt, ap);
112 * Set prefix that will be used before each log.
113 * Setting prefix to NULL will remove it.
116 pjdlog_prefix_setv(const char *fmt, va_list ap)
121 vsnprintf(pjdlog_prefix, sizeof(pjdlog_prefix), fmt, ap);
125 * Convert log level into string.
128 pjdlog_level_string(int loglevel)
149 assert(!"Invalid log level.");
150 abort(); /* XXX: gcc */
154 * Common log routine.
157 pjdlog_common(int loglevel, int debuglevel, int error, const char *fmt, ...)
162 pjdlogv_common(loglevel, debuglevel, error, fmt, ap);
167 * Common log routine, which can handle regular log level as well as debug
168 * level. We decide here where to send the logs (stdout/stderr or syslog).
171 pjdlogv_common(int loglevel, int debuglevel, int error, const char *fmt,
175 assert(loglevel == LOG_EMERG || loglevel == LOG_ALERT ||
176 loglevel == LOG_CRIT || loglevel == LOG_ERR ||
177 loglevel == LOG_WARNING || loglevel == LOG_NOTICE ||
178 loglevel == LOG_INFO || loglevel == LOG_DEBUG);
179 assert(loglevel != LOG_DEBUG || debuglevel > 0);
182 /* Ignore debug above configured level. */
183 if (loglevel == LOG_DEBUG && debuglevel > pjdlog_debug_level)
186 switch (pjdlog_mode) {
187 case PJDLOG_MODE_STD:
192 * We send errors and warning to stderr and the rest to stdout.
208 assert(!"Invalid loglevel.");
209 abort(); /* XXX: gcc */
212 fprintf(out, "[%s]", pjdlog_level_string(loglevel));
213 /* Attach debuglevel if this is debug log. */
214 if (loglevel == LOG_DEBUG)
215 fprintf(out, "[%d]", debuglevel);
217 fprintf(out, "%s", pjdlog_prefix);
218 vfprintf(out, fmt, ap);
220 fprintf(out, ": %s.", strerror(error));
224 case PJDLOG_MODE_SYSLOG:
229 len = snprintf(log, sizeof(log), "%s", pjdlog_prefix);
230 if ((size_t)len < sizeof(log))
231 len = vsnprintf(log + len, sizeof(log) - len, fmt, ap);
232 if (error != -1 && (size_t)len < sizeof(log)) {
233 (void)snprintf(log + len, sizeof(log) - len, ": %s.",
236 syslog(loglevel, "%s", log);
240 assert(!"Invalid mode.");
248 pjdlogv(int loglevel, const char *fmt, va_list ap)
251 /* LOG_DEBUG is invalid here, pjdlogv?_debug() should be used. */
252 assert(loglevel == LOG_EMERG || loglevel == LOG_ALERT ||
253 loglevel == LOG_CRIT || loglevel == LOG_ERR ||
254 loglevel == LOG_WARNING || loglevel == LOG_NOTICE ||
255 loglevel == LOG_INFO);
257 pjdlogv_common(loglevel, 0, -1, fmt, ap);
264 pjdlog(int loglevel, const char *fmt, ...)
269 pjdlogv(loglevel, fmt, ap);
277 pjdlogv_debug(int debuglevel, const char *fmt, va_list ap)
280 pjdlogv_common(LOG_DEBUG, debuglevel, -1, fmt, ap);
287 pjdlog_debug(int debuglevel, const char *fmt, ...)
292 pjdlogv_debug(debuglevel, fmt, ap);
297 * Error logs with errno logging.
300 pjdlogv_errno(int loglevel, const char *fmt, va_list ap)
303 pjdlogv_common(loglevel, 0, errno, fmt, ap);
307 * Error logs with errno logging.
310 pjdlog_errno(int loglevel, const char *fmt, ...)
315 pjdlogv_errno(loglevel, fmt, ap);
320 * Log error, errno and exit.
323 pjdlogv_exit(int exitcode, const char *fmt, va_list ap)
326 pjdlogv_errno(LOG_ERR, fmt, ap);
331 * Log error, errno and exit.
334 pjdlog_exit(int exitcode, const char *fmt, ...)
339 pjdlogv_exit(exitcode, fmt, ap);
345 * Log error and exit.
348 pjdlogv_exitx(int exitcode, const char *fmt, va_list ap)
351 pjdlogv(LOG_ERR, fmt, ap);
356 * Log error and exit.
359 pjdlog_exitx(int exitcode, const char *fmt, ...)
364 pjdlogv_exitx(exitcode, fmt, ap);