Skip to content

Commit 2201a29

Browse files
Log to syslog when running in background
Log messages are unconditionally written to stderr, and are therefore lost after the fork when running in the background (`-g`). If syslog support is detected at compile time, and provided we're not on a platform for which an alternative non-stderr logging facility is provided (i.e. Windows), send log messages to syslog when running in the background.
1 parent 9292e28 commit 2201a29

File tree

4 files changed

+118
-20
lines changed

4 files changed

+118
-20
lines changed

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ set(SERVER_DEBUG ${ENABLE_DEBUG_SERVER})
103103

104104

105105
check_symbol_exists(getopt "unistd.h" HAVE_GETOPT)
106+
check_symbol_exists(vsyslog "syslog.h" HAVE_VSYSLOG)
107+
if (HAVE_VSYSLOG)
108+
add_compile_definitions(HAVE_VSYSLOG)
109+
endif ()
106110

107111
# Does the compiler accept the "format" attribute?
108112
try_compile(HAVE_ATTR_FORMAT

src/log.c

Lines changed: 100 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,74 @@
3535
#include <sys/timeb.h>
3636
#endif
3737

38+
#if defined(HAVE_VSYSLOG)
39+
#include <syslog.h>
40+
#endif
41+
3842
#include "log.h"
3943

44+
stubby_log_target_t log_target = STUBBY_LOG_STDERR;
45+
46+
#if defined(HAVE_VSYSLOG)
47+
static void stubby_syslog_open()
48+
{
49+
static int is_syslog_open = 0;
50+
51+
if (!is_syslog_open) {
52+
openlog("stubby", LOG_PID, LOG_DAEMON);
53+
is_syslog_open = 1;
54+
}
55+
}
56+
57+
static int stubby_syslog_priority(getdns_loglevel_type level)
58+
{
59+
int priority = LOG_INFO;
60+
61+
switch (level) {
62+
case GETDNS_LOG_EMERG:
63+
priority = LOG_EMERG;
64+
break;
65+
case GETDNS_LOG_ALERT:
66+
priority = LOG_ALERT;
67+
break;
68+
case GETDNS_LOG_CRIT:
69+
priority = LOG_CRIT;
70+
break;
71+
case GETDNS_LOG_ERR:
72+
priority = LOG_ERR;
73+
break;
74+
case GETDNS_LOG_WARNING:
75+
priority = LOG_WARNING;
76+
break;
77+
case GETDNS_LOG_NOTICE:
78+
priority = LOG_NOTICE;
79+
break;
80+
case GETDNS_LOG_INFO:
81+
priority = LOG_INFO;
82+
break;
83+
case GETDNS_LOG_DEBUG:
84+
priority = LOG_DEBUG;
85+
break;
86+
}
87+
88+
return priority;
89+
}
90+
#endif
91+
4092
static void default_stubby_verror(getdns_loglevel_type level, const char *fmt, va_list ap)
4193
{
42-
(void) level;
43-
(void) vfprintf(stderr, fmt, ap);
94+
switch (log_target) {
95+
#if defined(HAVE_VSYSLOG)
96+
case STUBBY_LOG_SYSLOG:
97+
stubby_syslog_open();
98+
vsyslog(stubby_syslog_priority(level), fmt, ap);
99+
break;
100+
#endif
101+
case STUBBY_LOG_STDERR:
102+
(void) level;
103+
(void) vfprintf(stderr, fmt, ap);
104+
break;
105+
}
44106
}
45107

46108
long log_level = GETDNS_LOG_DEBUG + 1;
@@ -49,27 +111,40 @@ static void default_stubby_vlog(void *userarg, uint64_t system,
49111
getdns_loglevel_type level,
50112
const char *fmt, va_list ap)
51113
{
52-
struct timeval tv;
53-
struct tm tm;
54-
char buf[10];
114+
(void)userarg; (void)system;
115+
116+
switch (log_target) {
117+
#if defined(HAVE_VSYSLOG)
118+
case STUBBY_LOG_SYSLOG:
119+
stubby_syslog_open();
120+
vsyslog(stubby_syslog_priority(level), fmt, ap);
121+
break;
122+
#endif
123+
case STUBBY_LOG_STDERR:
124+
(void)0;
125+
struct timeval tv;
126+
struct tm tm;
127+
char buf[10];
55128
#if defined(STUBBY_ON_WINDOWS)
56-
struct _timeb timeb;
57-
time_t tsec;
58-
if (level > log_level) return;
59-
60-
_ftime_s(&timeb);
61-
tsec = (time_t)timeb.time;
62-
tv.tv_usec = timeb.millitm * 1000;
63-
gmtime_s(&tm, &tsec);
129+
struct _timeb timeb;
130+
time_t tsec;
131+
if (level > log_level) return;
132+
133+
_ftime_s(&timeb);
134+
tsec = (time_t)timeb.time;
135+
tv.tv_usec = timeb.millitm * 1000;
136+
gmtime_s(&tm, &tsec);
64137
#else
65-
if (level > log_level) return;
66-
gettimeofday(&tv, NULL);
67-
gmtime_r(&tv.tv_sec, &tm);
138+
if (level > log_level) return;
139+
gettimeofday(&tv, NULL);
140+
gmtime_r(&tv.tv_sec, &tm);
68141
#endif
69-
strftime(buf, 10, "%H:%M:%S", &tm);
70-
(void)userarg; (void)system; (void)level;
71-
(void) fprintf(stderr, "[%s.%.6d] STUBBY: ", buf, (int)tv.tv_usec);
72-
(void) vfprintf(stderr, fmt, ap);
142+
strftime(buf, 10, "%H:%M:%S", &tm);
143+
(void)level;
144+
(void) fprintf(stderr, "[%s.%.6d] STUBBY: ", buf, (int)tv.tv_usec);
145+
(void) vfprintf(stderr, fmt, ap);
146+
break;
147+
}
73148
}
74149

75150
static stubby_verror_t stubby_verror = default_stubby_verror;
@@ -114,6 +189,11 @@ void stubby_set_log_funcs(stubby_verror_t errfunc, stubby_vlog_t logfunc)
114189
stubby_vlog = logfunc;
115190
}
116191

192+
void stubby_set_log_target(stubby_log_target_t target)
193+
{
194+
log_target = target;
195+
}
196+
117197
void stubby_set_getdns_logging(getdns_context *context, int loglevel)
118198
{
119199
(void) getdns_context_set_logfunc(context, NULL, GETDNS_LOG_UPSTREAM_STATS, loglevel, stubby_vlog);

src/log.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@
3434
#include <getdns/getdns.h>
3535
#include <getdns/getdns_extra.h>
3636

37+
typedef enum stubby_log_target {
38+
#if defined(HAVE_VSYSLOG)
39+
STUBBY_LOG_SYSLOG,
40+
#endif
41+
STUBBY_LOG_STDERR
42+
} stubby_log_target_t;
43+
3744
typedef void(*stubby_verror_t)(getdns_loglevel_type level, const char *fmt, va_list ap);
3845
typedef void(*stubby_vlog_t)(void *userarg, uint64_t system,
3946
getdns_loglevel_type level,
@@ -50,6 +57,7 @@ void stubby_warning(const char *fmt, ...);
5057
void stubby_debug(const char *fmt, ...);
5158

5259
void stubby_set_log_funcs(stubby_verror_t errfunc, stubby_vlog_t logfunc);
60+
void stubby_set_log_target(stubby_log_target_t target);
5361

5462
void stubby_set_getdns_logging(getdns_context *context, int loglevel);
5563

src/stubby.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,12 @@ main(int argc, char **argv)
169169
}
170170
#endif
171171

172+
#if defined(HAVE_VSYSLOG) && !defined(STUBBY_ON_WINDOWS)
173+
if (!run_in_foreground) {
174+
stubby_set_log_target(STUBBY_LOG_SYSLOG);
175+
}
176+
#endif
177+
172178
if ((r = getdns_context_create(&context, 1))) {
173179
stubby_error("Create context failed: %s",
174180
stubby_getdns_strerror(r));

0 commit comments

Comments
 (0)