1
0
mirror of https://github.com/gophernicus/gophernicus.git synced 2024-06-16 06:25:23 +00:00
gophernicus/src/log.c
Augustin Fabre 9c0b6a66a4
Rework logging logic
This commit fixes issue #42 [0].

Debug level messages are masked unless option `-d' (debug) is used. In this
case, all messages are also printed to stderr.

syslog.h is included in the base POSIX only since issue 6 (POSIX:2001) [1].

`LOG_UPTO' is an extension, not defined by POSIX; an implementation is provided
here for platforms where it is missing.

This code is inspired by OpenBSD's httpd(8) logging functions [2].

[0] https://github.com/gophernicus/gophernicus/issues/42
[1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/setlogmask.html
[2] https://cvsweb.openbsd.org/src/usr.sbin/httpd/log.c?rev=1.14&content-type=text/x-cvsweb-markup
2020-10-12 20:21:06 +02:00

89 lines
2.4 KiB
C

#include <stdarg.h>
#include <syslog.h>
#include "gophernicus.h"
#if defined(LOG_UPTO)
#define _LOG_UPTO LOG_UPTO
#else
#define _LOG_UPTO(pri) \
( \
((pri) == LOG_EMERG) ? (LOG_MASK(LOG_EMERG)) : \
((pri) == LOG_ALERT) ? (LOG_MASK(LOG_EMERG) | LOG_MASK(LOG_ALERT)) : \
((pri) == LOG_CRIT) ? (LOG_MASK(LOG_EMERG) | LOG_MASK(LOG_ALERT) | LOG_MASK(LOG_CRIT)) : \
((pri) == LOG_ERR) ? (LOG_MASK(LOG_EMERG) | LOG_MASK(LOG_ALERT) | LOG_MASK(LOG_CRIT) | LOG_MASK(LOG_ERR)) : \
((pri) == LOG_WARNING) ? (LOG_MASK(LOG_EMERG) | LOG_MASK(LOG_ALERT) | LOG_MASK(LOG_CRIT) | LOG_MASK(LOG_ERR) | LOG_MASK(LOG_WARNING)) : \
((pri) == LOG_NOTICE) ? (LOG_MASK(LOG_EMERG) | LOG_MASK(LOG_ALERT) | LOG_MASK(LOG_CRIT) | LOG_MASK(LOG_ERR) | LOG_MASK(LOG_WARNING) | LOG_MASK(LOG_NOTICE)) : \
((pri) == LOG_INFO) ? (LOG_MASK(LOG_EMERG) | LOG_MASK(LOG_ALERT) | LOG_MASK(LOG_CRIT) | LOG_MASK(LOG_ERR) | LOG_MASK(LOG_WARNING) | LOG_MASK(LOG_NOTICE) | LOG_MASK(LOG_INFO)) : \
((pri) == LOG_DEBUG) ? (LOG_MASK(LOG_EMERG) | LOG_MASK(LOG_ALERT) | LOG_MASK(LOG_CRIT) | LOG_MASK(LOG_ERR) | LOG_MASK(LOG_WARNING) | LOG_MASK(LOG_NOTICE) | LOG_MASK(LOG_INFO) | LOG_MASK(LOG_DEBUG)) : \
0)
#endif
static int _enable = 0;
void log_init(int enable, int debug)
{
if (!enable) return;
_enable = enable;
openlog(PROGNAME,
LOG_PID | (debug ? LOG_PERROR : 0),
LOG_DAEMON);
setlogmask(_LOG_UPTO(debug ? LOG_DEBUG : LOG_INFO));
}
static void _vlog(int priority, const char *fmt, va_list ap)
{
char buf[BUFSIZE];
if (!_enable) return;
vsnprintf(buf, sizeof(buf), fmt, ap);
syslog(priority, "%s", buf);
}
static void _log(int priority, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
_vlog(priority, fmt, ap);
va_end(ap);
}
void log_fatal(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
if (errno) {
int en = errno;
char buf[BUFSIZE];
vsnprintf(buf, sizeof(buf), fmt, ap);
_log(LOG_CRIT, "%s (%s)", buf, strerror(en));
} else {
_vlog(LOG_CRIT, fmt, ap);
}
va_end(ap);
}
#define _GOPHERNICUS_MK_LOG_FUNCTION(FCT_LVL, LOG_LVL) \
void FCT_LVL(const char *fmt, ...) \
{ \
va_list ap; \
\
va_start(ap, fmt); \
_vlog(LOG_LVL, fmt, ap); \
va_end(ap); \
}
_GOPHERNICUS_MK_LOG_FUNCTION(log_warning, LOG_WARNING)
_GOPHERNICUS_MK_LOG_FUNCTION(log_info, LOG_INFO)
_GOPHERNICUS_MK_LOG_FUNCTION(log_debug, LOG_DEBUG)
#undef _GOPHERNICUS_MK_LOG_FUNCTION