Changes to update Tomato RAF.
[tomato.git] / release / src / router / dnscrypt / src / proxy / logger.c
bloba9fb5cfc6720dde724ed119f2da8297bac8014fa
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 #ifndef DEBUG
47 if (crit == LOG_DEBUG) {
48 return 0;
50 #endif
51 switch (crit) {
52 case LOG_INFO:
53 urgency = "[INFO] ";
54 break;
55 case LOG_WARNING:
56 urgency = "[WARNING] ";
57 break;
58 case LOG_ERR:
59 urgency = "[ERROR] ";
60 break;
61 case LOG_NOTICE:
62 urgency = "[NOTICE] ";
63 break;
64 case LOG_DEBUG:
65 urgency = "[DEBUG] ";
66 break;
67 default:
68 urgency = "";
70 va_start(va, format);
71 len = (size_t) evutil_vsnprintf(line, sizeof line, format, va);
72 va_end(va);
74 if (len >= sizeof line) {
75 assert(sizeof line > (size_t) 0U);
76 len = sizeof line - (size_t) 1U;
78 line[len++] = 0;
79 #ifndef _WIN32
80 if (context != NULL && context->log_fd == -1 && context->daemonize) {
81 syslog(crit, "%s", line);
82 return 0;
84 #endif
85 if (memcmp(previous_line, line, len) == 0) {
86 burst_counter++;
87 if (burst_counter > LOGGER_ALLOWED_BURST_FOR_IDENTICAL_LOG_ENTRIES &&
88 now - last_log_ts < LOGGER_DELAY_BETWEEN_IDENTICAL_LOG_ENTRIES) {
89 return 1;
91 } else {
92 burst_counter = 0U;
94 last_log_ts = now;
95 assert(sizeof previous_line >= sizeof line);
96 memcpy(previous_line, line, len);
97 if (context == NULL || context->log_fd == -1) {
98 log_fd = STDERR_FILENO;
99 } else {
100 log_fd = context->log_fd;
102 #ifndef _WIN32
103 safe_write(log_fd, urgency, strlen(urgency), LOG_WRITE_TIMEOUT);
104 safe_write(log_fd, line, strlen(line), LOG_WRITE_TIMEOUT);
105 safe_write(log_fd, "\n", (size_t) 1U, LOG_WRITE_TIMEOUT);
106 #else
107 (void) log_fd;
108 printf("%s%s\n", urgency, line);
109 fflush(stdout);
110 #endif
112 return 0;
116 logger_noformat(struct ProxyContext_ * const context,
117 const int crit, const char * const msg)
119 return logger(context, crit, "%s", msg);
123 logger_error(struct ProxyContext_ * const context,
124 const char * const msg)
126 const char *const err_msg = strerror(errno);
128 return logger(context, LOG_ERR, "%s: %s", msg, err_msg);
132 logger_close(struct ProxyContext_ * const context)
134 #ifdef _WIN32
135 (void) context;
136 #else
137 if (context->daemonize) {
138 closelog();
140 if (context->log_fd != -1) {
141 fsync(context->log_fd);
142 return close(context->log_fd);
144 #endif
145 return 0;