Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Log to syslog when running in background #350

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ set(SERVER_DEBUG ${ENABLE_DEBUG_SERVER})


check_symbol_exists(getopt "unistd.h" HAVE_GETOPT)
check_symbol_exists(vsyslog "syslog.h" HAVE_VSYSLOG)
if (HAVE_VSYSLOG)
add_compile_definitions(-DHAVE_VSYSLOG)
endif ()

# Does the compiler accept the "format" attribute?
try_compile(HAVE_ATTR_FORMAT
Expand Down
120 changes: 100 additions & 20 deletions src/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,74 @@
#include <sys/timeb.h>
#endif

#if defined(HAVE_VSYSLOG)
#include <syslog.h>
#endif

#include "log.h"

stubby_log_target_t log_target = STUBBY_LOG_STDERR;

#if defined(HAVE_VSYSLOG)
static void stubby_syslog_open()
{
static int is_syslog_open = 0;

if (!is_syslog_open) {
openlog("stubby", LOG_PID, LOG_DAEMON);
is_syslog_open = 1;
}
}

static int stubby_syslog_priority(getdns_loglevel_type level)
{
int priority = LOG_INFO;

switch (level) {
case GETDNS_LOG_EMERG:
priority = LOG_EMERG;
break;
case GETDNS_LOG_ALERT:
priority = LOG_ALERT;
break;
case GETDNS_LOG_CRIT:
priority = LOG_CRIT;
break;
case GETDNS_LOG_ERR:
priority = LOG_ERR;
break;
case GETDNS_LOG_WARNING:
priority = LOG_WARNING;
break;
case GETDNS_LOG_NOTICE:
priority = LOG_NOTICE;
break;
case GETDNS_LOG_INFO:
priority = LOG_INFO;
break;
case GETDNS_LOG_DEBUG:
priority = LOG_DEBUG;
break;
}

return priority;
}
#endif

static void default_stubby_verror(getdns_loglevel_type level, const char *fmt, va_list ap)
{
(void) level;
(void) vfprintf(stderr, fmt, ap);
switch (log_target) {
#if defined(HAVE_VSYSLOG)
case STUBBY_LOG_SYSLOG:
stubby_syslog_open();
vsyslog(stubby_syslog_priority(level), fmt, ap);
break;
#endif
case STUBBY_LOG_STDERR:
(void) level;
(void) vfprintf(stderr, fmt, ap);
break;
}
}

long log_level = GETDNS_LOG_DEBUG + 1;
Expand All @@ -49,27 +111,40 @@ static void default_stubby_vlog(void *userarg, uint64_t system,
getdns_loglevel_type level,
const char *fmt, va_list ap)
{
struct timeval tv;
struct tm tm;
char buf[10];
(void)userarg; (void)system;

switch (log_target) {
#if defined(HAVE_VSYSLOG)
case STUBBY_LOG_SYSLOG:
stubby_syslog_open();
vsyslog(stubby_syslog_priority(level), fmt, ap);
break;
#endif
case STUBBY_LOG_STDERR:
(void)0;
struct timeval tv;
struct tm tm;
char buf[10];
#if defined(STUBBY_ON_WINDOWS)
struct _timeb timeb;
time_t tsec;
if (level > log_level) return;

_ftime_s(&timeb);
tsec = (time_t)timeb.time;
tv.tv_usec = timeb.millitm * 1000;
gmtime_s(&tm, &tsec);
struct _timeb timeb;
time_t tsec;
if (level > log_level) return;

_ftime_s(&timeb);
tsec = (time_t)timeb.time;
tv.tv_usec = timeb.millitm * 1000;
gmtime_s(&tm, &tsec);
#else
if (level > log_level) return;
gettimeofday(&tv, NULL);
gmtime_r(&tv.tv_sec, &tm);
if (level > log_level) return;
gettimeofday(&tv, NULL);
gmtime_r(&tv.tv_sec, &tm);
#endif
strftime(buf, 10, "%H:%M:%S", &tm);
(void)userarg; (void)system; (void)level;
(void) fprintf(stderr, "[%s.%.6d] STUBBY: ", buf, (int)tv.tv_usec);
(void) vfprintf(stderr, fmt, ap);
strftime(buf, 10, "%H:%M:%S", &tm);
(void)level;
(void) fprintf(stderr, "[%s.%.6d] STUBBY: ", buf, (int)tv.tv_usec);
(void) vfprintf(stderr, fmt, ap);
break;
}
}

static stubby_verror_t stubby_verror = default_stubby_verror;
Expand Down Expand Up @@ -114,6 +189,11 @@ void stubby_set_log_funcs(stubby_verror_t errfunc, stubby_vlog_t logfunc)
stubby_vlog = logfunc;
}

void stubby_set_log_target(stubby_log_target_t target)
{
log_target = target;
}

void stubby_set_getdns_logging(getdns_context *context, int loglevel)
{
(void) getdns_context_set_logfunc(context, NULL, GETDNS_LOG_UPSTREAM_STATS, loglevel, stubby_vlog);
Expand Down
8 changes: 8 additions & 0 deletions src/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@
#include <getdns/getdns.h>
#include <getdns/getdns_extra.h>

typedef enum stubby_log_target {
#if defined(HAVE_VSYSLOG)
STUBBY_LOG_SYSLOG,
#endif
STUBBY_LOG_STDERR
} stubby_log_target_t;

typedef void(*stubby_verror_t)(getdns_loglevel_type level, const char *fmt, va_list ap);
typedef void(*stubby_vlog_t)(void *userarg, uint64_t system,
getdns_loglevel_type level,
Expand All @@ -50,6 +57,7 @@ void stubby_warning(const char *fmt, ...);
void stubby_debug(const char *fmt, ...);

void stubby_set_log_funcs(stubby_verror_t errfunc, stubby_vlog_t logfunc);
void stubby_set_log_target(stubby_log_target_t target);

void stubby_set_getdns_logging(getdns_context *context, int loglevel);

Expand Down
6 changes: 6 additions & 0 deletions src/stubby.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,12 @@ main(int argc, char **argv)
}
#endif

#if defined(HAVE_VSYSLOG) && !defined(STUBBY_ON_WINDOWS)
if (!run_in_foreground) {
stubby_set_log_target(STUBBY_LOG_SYSLOG);
}
#endif

if ((r = getdns_context_create(&context, 1))) {
stubby_error("Create context failed: %s",
stubby_getdns_strerror(r));
Expand Down