dnscrypto-proxy: Update to release 1.3.0
[tomato.git] / release / src / router / dnscrypt / src / proxy / logger.c
blobcfb65b0ccc796727703f9f43a067143c70a81805
2 #include <config.h>
3 #include <sys/types.h>
5 #include <assert.h>
6 #include <errno.h>
7 #include <stdio.h>
8 #include <string.h>
9 #ifndef _WIN32
10 # include <syslog.h>
11 #endif
12 #include <stdarg.h>
13 #include <time.h>
14 #include <unistd.h>
16 #include <event2/util.h>
18 #include "dnscrypt_proxy.h"
19 #include "logger.h"
20 #include "safe_rw.h"
22 int
23 logger_open_syslog(struct ProxyContext_ * const context)
25 assert(context->daemonize != 0);
26 #ifndef _WIN32
27 openlog(PACKAGE_TARNAME, LOG_NDELAY | LOG_PID, LOG_DAEMON);
28 #endif
29 return 0;
32 int
33 logger(struct ProxyContext_ * const context,
34 const int crit, const char * const format, ...)
36 static char previous_line[MAX_LOG_LINE];
37 static time_t last_log_ts = (time_t) 0;
38 static unsigned int burst_counter = 0U;
39 char line[MAX_LOG_LINE];
40 va_list va;
41 const char *urgency;
42 time_t now = time(NULL);
43 size_t len;
44 int log_fd;
46 if (context != NULL) {
47 if (crit > context->max_log_level) {
48 return 0;
50 } else {
51 #ifndef DEBUG
52 if (crit > LOG_INFO) {
53 return 0;
55 #endif
57 switch (crit) {
58 case LOG_INFO:
59 urgency = "[INFO] ";
60 break;
61 case LOG_WARNING:
62 urgency = "[WARNING] ";
63 break;
64 case LOG_ERR:
65 urgency = "[ERROR] ";
66 break;
67 case LOG_NOTICE:
68 urgency = "[NOTICE] ";
69 break;
70 case LOG_DEBUG:
71 urgency = "[DEBUG] ";
72 break;
73 default:
74 urgency = "";
76 va_start(va, format);
77 len = (size_t) evutil_vsnprintf(line, sizeof line, format, va);
78 va_end(va);
80 if (len >= sizeof line) {
81 assert(sizeof line > (size_t) 0U);
82 len = sizeof line - (size_t) 1U;
84 line[len++] = 0;
85 #ifndef _WIN32
86 if (context != NULL && context->log_fd == -1 && context->daemonize) {
87 syslog(crit, "%s", line);
88 return 0;
90 #endif
91 if (memcmp(previous_line, line, len) == 0) {
92 burst_counter++;
93 if (burst_counter > LOGGER_ALLOWED_BURST_FOR_IDENTICAL_LOG_ENTRIES &&
94 now - last_log_ts < LOGGER_DELAY_BETWEEN_IDENTICAL_LOG_ENTRIES) {
95 return 1;
97 } else {
98 burst_counter = 0U;
100 last_log_ts = now;
101 assert(sizeof previous_line >= sizeof line);
102 memcpy(previous_line, line, len);
103 if (context == NULL || context->log_fd == -1) {
104 log_fd = STDERR_FILENO;
105 } else {
106 log_fd = context->log_fd;
108 #ifndef _WIN32
109 safe_write(log_fd, urgency, strlen(urgency), LOG_WRITE_TIMEOUT);
110 safe_write(log_fd, line, strlen(line), LOG_WRITE_TIMEOUT);
111 safe_write(log_fd, "\n", (size_t) 1U, LOG_WRITE_TIMEOUT);
112 #else
113 (void) log_fd;
114 printf("%s%s\n", urgency, line);
115 fflush(stdout);
116 #endif
118 return 0;
122 logger_noformat(struct ProxyContext_ * const context,
123 const int crit, const char * const msg)
125 return logger(context, crit, "%s", msg);
129 logger_error(struct ProxyContext_ * const context,
130 const char * const msg)
132 const char *const err_msg = strerror(errno);
134 return logger(context, LOG_ERR, "%s: %s", msg, err_msg);
138 logger_close(struct ProxyContext_ * const context)
140 #ifdef _WIN32
141 (void) context;
142 #else
143 if (context->daemonize) {
144 closelog();
146 if (context->log_fd != -1) {
147 fsync(context->log_fd);
148 return close(context->log_fd);
150 #endif
151 return 0;