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