]> arthur.barton.de Git - netdata.git/blob - src/log.c
Merge remote-tracking branch 'fredericopissarra/changes' into registry
[netdata.git] / src / log.c
1 #ifdef HAVE_CONFIG_H
2 #include <config.h>
3 #endif
4 #include <time.h>
5 #include <syslog.h>
6 #include <errno.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <stdlib.h>
10
11 #include "log.h"
12 #include "common.h"
13
14
15 // ----------------------------------------------------------------------------
16 // LOG
17
18 const char *program_name = "";
19 unsigned long long debug_flags = DEBUG;
20
21 int silent = 0;
22
23 int access_fd = -1;
24 FILE *stdaccess = NULL;
25
26 int access_log_syslog = 1;
27 int error_log_syslog = 1;
28 int output_log_syslog = 1;      // debug log
29
30 time_t error_log_throttle_period = 1200;
31 unsigned long error_log_errors_per_period = 200;
32
33 int error_log_limit(int reset) {
34         static time_t start = 0;
35         static unsigned long counter = 0, prevented = 0;
36
37         // do not throttle if the period is 0
38         if(error_log_throttle_period == 0)
39                 return 0;
40
41         // prevent all logs if the errors per period is 0
42         if(error_log_errors_per_period == 0)
43                 return 1;
44
45         time_t now = time(NULL);
46         if(!start) start = now;
47
48         if(reset) {
49                 if(prevented) {
50                         log_date(stderr);
51                         fprintf(stderr, "%s: Resetting logging for process '%s' (prevented %lu logs in the last %ld seconds).\n"
52                                         , program_name
53                                 , program_name
54                                         , prevented
55                                         , now - start
56                         );
57                 }
58
59                 start = now;
60                 counter = 0;
61                 prevented = 0;
62         }
63
64         // detect if we log too much
65         counter++;
66
67         if(now - start > error_log_throttle_period) {
68                 if(prevented) {
69                         log_date(stderr);
70                         fprintf(stderr, "%s: Resuming logging from process '%s' (prevented %lu logs in the last %ld seconds).\n"
71                                         , program_name
72                                 , program_name
73                                         , prevented
74                                         , error_log_throttle_period
75                         );
76                 }
77
78                 // restart the period accounting
79                 start = now;
80                 counter = 1;
81                 prevented = 0;
82
83                 // log this error
84                 return 0;
85         }
86
87         if(counter > error_log_errors_per_period) {
88                 if(!prevented) {
89                         log_date(stderr);
90                         fprintf(stderr, "%s: Too many logs (%lu logs in %ld seconds, threshold is set to %lu logs in %ld seconds). Preventing more logs from process '%s' for %ld seconds.\n"
91                                         , program_name
92                                 , counter
93                                 , now - start
94                                 , error_log_errors_per_period
95                                 , error_log_throttle_period
96                                 , program_name
97                                         , start + error_log_throttle_period - now);
98                 }
99
100                 prevented++;
101
102                 // prevent logging this error
103                 return 1;
104         }
105
106         return 0;
107 }
108
109 void log_date(FILE *out)
110 {
111                 char outstr[200];
112                 time_t t;
113                 struct tm *tmp, tmbuf;
114
115                 t = time(NULL);
116                 tmp = localtime_r(&t, &tmbuf);
117
118                 if (tmp == NULL) return;
119                 if (strftime(outstr, sizeof(outstr), "%y-%m-%d %H:%M:%S", tmp) == 0) return;
120
121                 fprintf(out, "%s: ", outstr);
122 }
123
124 void debug_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... )
125 {
126         va_list args;
127
128         log_date(stdout);
129         va_start( args, fmt );
130         fprintf(stdout, "DEBUG (%04lu@%-10.10s:%-15.15s): %s: ", line, file, function, program_name);
131         vfprintf( stdout, fmt, args );
132         va_end( args );
133         fprintf(stdout, "\n");
134         // fflush( stdout );
135
136         if(output_log_syslog) {
137                 va_start( args, fmt );
138                 vsyslog(LOG_ERR,  fmt, args );
139                 va_end( args );
140         }
141 }
142
143 void info_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... )
144 {
145         va_list args;
146
147         // prevent logging too much
148         if(error_log_limit(0)) return;
149
150         log_date(stderr);
151
152         va_start( args, fmt );
153         if(debug_flags) fprintf(stderr, "INFO (%04lu@%-10.10s:%-15.15s): %s: ", line, file, function, program_name);
154         else            fprintf(stderr, "INFO: %s: ", program_name);
155         vfprintf( stderr, fmt, args );
156         va_end( args );
157
158         fprintf(stderr, "\n");
159
160         if(error_log_syslog) {
161                 va_start( args, fmt );
162                 vsyslog(LOG_INFO,  fmt, args );
163                 va_end( args );
164         }
165 }
166
167 void error_int( const char *prefix, const char *file, const char *function, const unsigned long line, const char *fmt, ... )
168 {
169         va_list args;
170
171         // prevent logging too much
172         if(error_log_limit(0)) return;
173
174         log_date(stderr);
175
176         va_start( args, fmt );
177         if(debug_flags) fprintf(stderr, "%s (%04lu@%-10.10s:%-15.15s): %s: ", prefix, line, file, function, program_name);
178         else            fprintf(stderr, "%s: %s: ", prefix, program_name);
179         vfprintf( stderr, fmt, args );
180         va_end( args );
181
182         if(errno) {
183                 char buf[200];
184                 char *s = strerror_r(errno, buf, 200);
185                 fprintf(stderr, " (errno %d, %s)\n", errno, s);
186                 errno = 0;
187         }
188         else fprintf(stderr, "\n");
189
190         if(error_log_syslog) {
191                 va_start( args, fmt );
192                 vsyslog(LOG_ERR,  fmt, args );
193                 va_end( args );
194         }
195 }
196
197 void fatal_int( const char *file, const char *function, const unsigned long line, const char *fmt, ... )
198 {
199         va_list args;
200
201         log_date(stderr);
202
203         va_start( args, fmt );
204         if(debug_flags) fprintf(stderr, "FATAL (%04lu@%-10.10s:%-15.15s): %s: ", line, file, function, program_name);
205         else            fprintf(stderr, "FATAL: %s: ", program_name);
206         vfprintf( stderr, fmt, args );
207         va_end( args );
208
209         perror(" # ");
210         fprintf(stderr, "\n");
211
212         if(error_log_syslog) {
213                 va_start( args, fmt );
214                 vsyslog(LOG_CRIT,  fmt, args );
215                 va_end( args );
216         }
217
218         exit(1);
219 }
220
221 void log_access( const char *fmt, ... )
222 {
223         va_list args;
224
225         if(stdaccess) {
226                 log_date(stdaccess);
227
228                 va_start( args, fmt );
229                 vfprintf( stdaccess, fmt, args );
230                 va_end( args );
231                 fprintf( stdaccess, "\n");
232                 // fflush( stdaccess );
233         }
234
235         if(access_log_syslog) {
236                 va_start( args, fmt );
237                 vsyslog(LOG_INFO,  fmt, args );
238                 va_end( args );
239         }
240 }
241