~ubuntu-branches/ubuntu/intrepid/haproxy/intrepid

« back to all changes in this revision

Viewing changes to src/log.c

  • Committer: Bazaar Package Importer
  • Author(s): Arnaud Cornet
  • Date: 2008-03-09 21:30:29 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080309213029-8oupnrc607mg5uqw
Tags: 1.3.14.3-1
* New Upstream Version
* Add status argument support to init-script to conform to LSB.
* Cleanup pidfile after stop in init script. Init script return code fixups.

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
 *
11
11
 */
12
12
 
 
13
#include <fcntl.h>
13
14
#include <stdarg.h>
14
15
#include <stdio.h>
15
16
#include <stdlib.h>
17
18
#include <syslog.h>
18
19
#include <time.h>
19
20
#include <unistd.h>
 
21
#include <errno.h>
20
22
 
21
23
#include <sys/time.h>
22
24
 
29
31
#include <types/log.h>
30
32
#include <types/session.h>
31
33
 
 
34
#ifndef MSG_NOSIGNAL
 
35
#define MSG_NOSIGNAL    (0)
 
36
#endif /* !MSG_NOSIGNAL */
32
37
 
33
38
const char *log_facilities[NB_LOG_FACILITIES] = {
34
39
        "kern", "user", "mail", "daemon",
60
65
void Alert(const char *fmt, ...)
61
66
{
62
67
        va_list argp;
63
 
        struct tm *tm;
 
68
        struct tm tm;
64
69
 
65
70
        if (!(global.mode & MODE_QUIET) || (global.mode & (MODE_VERBOSE | MODE_STARTING))) {
66
71
                va_start(argp, fmt);
67
72
 
68
 
                tm = localtime((time_t *)&now.tv_sec);
 
73
                get_localtime(now.tv_sec, &tm);
69
74
                fprintf(stderr, "[ALERT] %03d/%02d%02d%02d (%d) : ",
70
 
                        tm->tm_yday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)getpid());
 
75
                        tm.tm_yday, tm.tm_hour, tm.tm_min, tm.tm_sec, (int)getpid());
71
76
                vfprintf(stderr, fmt, argp);
72
77
                fflush(stderr);
73
78
                va_end(argp);
81
86
void Warning(const char *fmt, ...)
82
87
{
83
88
        va_list argp;
84
 
        struct tm *tm;
 
89
        struct tm tm;
85
90
 
86
91
        if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)) {
87
92
                va_start(argp, fmt);
88
93
 
89
 
                tm = localtime((time_t *)&now.tv_sec);
 
94
                get_localtime(now.tv_sec, &tm);
90
95
                fprintf(stderr, "[WARNING] %03d/%02d%02d%02d (%d) : ",
91
 
                        tm->tm_yday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)getpid());
 
96
                        tm.tm_yday, tm.tm_hour, tm.tm_min, tm.tm_sec, (int)getpid());
92
97
                vfprintf(stderr, fmt, argp);
93
98
                fflush(stderr);
94
99
                va_end(argp);
139
144
        return facility;
140
145
}
141
146
 
 
147
/*
 
148
 * Return the length of the address endpoint, suitable for use with sendto().
 
149
 */
 
150
static inline int logsrv_addrlen(const struct logsrv *logsrv)
 
151
{
 
152
        switch (logsrv->u.addr.sa_family) {
 
153
        case AF_UNIX:
 
154
                return sizeof(logsrv->u.un);
 
155
        case AF_INET:
 
156
                return sizeof(logsrv->u.in);
 
157
        default:
 
158
                break;
 
159
        }
 
160
        return -1;
 
161
}
142
162
 
143
163
/*
144
164
 * This function sends a syslog message to both log servers of a proxy,
148
168
 */
149
169
void send_log(struct proxy *p, int level, const char *message, ...)
150
170
{
151
 
        static int logfd = -1;  /* syslog UDP socket */
 
171
        static int logfdunix = -1;      /* syslog to AF_UNIX socket */
 
172
        static int logfdinet = -1;      /* syslog to AF_INET socket */
152
173
        static long tvsec = -1; /* to force the string to be initialized */
153
174
        va_list argp;
154
175
        static char logmsg[MAX_SYSLOG_LEN];
155
176
        static char *dataptr = NULL;
156
177
        int fac_level;
157
178
        int hdr_len, data_len;
158
 
        struct sockaddr_in *sa[2];
 
179
        struct logsrv *logsrvs[2];
159
180
        int facilities[2], loglevel[2];
 
181
        int nblogger;
160
182
        int nbloggers = 0;
161
183
        char *log_ptr;
162
184
 
163
 
        if (logfd < 0) {
164
 
                if ((logfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
165
 
                        return;
166
 
        }
167
 
    
168
185
        if (level < 0 || progname == NULL || message == NULL)
169
186
                return;
170
187
 
171
188
        if (now.tv_sec != tvsec || dataptr == NULL) {
172
189
                /* this string is rebuild only once a second */
173
 
                struct tm *tm = localtime((time_t *)&now.tv_sec);
 
190
                struct tm tm;
 
191
 
174
192
                tvsec = now.tv_sec;
 
193
                get_localtime(tvsec, &tm);
175
194
 
176
195
                hdr_len = snprintf(logmsg, sizeof(logmsg),
177
196
                                   "<<<<>%s %2d %02d:%02d:%02d %s[%d]: ",
178
 
                                   monthname[tm->tm_mon],
179
 
                                   tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
 
197
                                   monthname[tm.tm_mon],
 
198
                                   tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
180
199
                                   progname, pid);
181
200
                /* WARNING: depending upon implementations, snprintf may return
182
201
                 * either -1 or the number of bytes that would be needed to store
201
220
 
202
221
        if (p == NULL) {
203
222
                if (global.logfac1 >= 0) {
204
 
                        sa[nbloggers] = &global.logsrv1;
 
223
                        logsrvs[nbloggers] = &global.logsrv1;
205
224
                        facilities[nbloggers] = global.logfac1;
206
225
                        loglevel[nbloggers] = global.loglev1;
207
226
                        nbloggers++;
208
227
                }
209
228
                if (global.logfac2 >= 0) {
210
 
                        sa[nbloggers] = &global.logsrv2;
 
229
                        logsrvs[nbloggers] = &global.logsrv2;
211
230
                        facilities[nbloggers] = global.logfac2;
212
231
                        loglevel[nbloggers] = global.loglev2;
213
232
                        nbloggers++;
214
233
                }
215
234
        } else {
216
235
                if (p->logfac1 >= 0) {
217
 
                        sa[nbloggers] = &p->logsrv1;
 
236
                        logsrvs[nbloggers] = &p->logsrv1;
218
237
                        facilities[nbloggers] = p->logfac1;
219
238
                        loglevel[nbloggers] = p->loglev1;
220
239
                        nbloggers++;
221
240
                }
222
241
                if (p->logfac2 >= 0) {
223
 
                        sa[nbloggers] = &p->logsrv2;
 
242
                        logsrvs[nbloggers] = &p->logsrv2;
224
243
                        facilities[nbloggers] = p->logfac2;
225
244
                        loglevel[nbloggers] = p->loglev2;
226
245
                        nbloggers++;
227
246
                }
228
247
        }
229
248
 
230
 
        while (nbloggers-- > 0) {
 
249
        /* Lazily set up syslog sockets for protocol families of configured
 
250
         * syslog servers. */
 
251
        for (nblogger = 0; nblogger < nbloggers; nblogger++) {
 
252
                const struct logsrv *logsrv = logsrvs[nblogger];
 
253
                int proto, *plogfd;
 
254
                if (logsrv->u.addr.sa_family == AF_UNIX) {
 
255
                        proto = 0;
 
256
                        plogfd = &logfdunix;
 
257
                } else {
 
258
                        /* sa_family == AF_INET */
 
259
                        proto = IPPROTO_UDP;
 
260
                        plogfd = &logfdinet;
 
261
                }
 
262
                if (*plogfd >= 0) {
 
263
                        /* socket already created. */
 
264
                        continue;
 
265
                }
 
266
                if ((*plogfd = socket(logsrv->u.addr.sa_family, SOCK_DGRAM,
 
267
                                proto)) < 0) {
 
268
                        Alert("socket for logger #%d failed: %s (errno=%d)\n",
 
269
                                nblogger + 1, strerror(errno), errno);
 
270
                        return;
 
271
                }
 
272
                /* we don't want to receive anything on this socket */
 
273
                setsockopt(*plogfd, SOL_SOCKET, SO_RCVBUF, &zero, sizeof(zero));
 
274
                /* does nothing under Linux, maybe needed for others */
 
275
                shutdown(*plogfd, SHUT_RD);
 
276
        }
 
277
 
 
278
        /* Send log messages to syslog server. */
 
279
        for (nblogger = 0; nblogger < nbloggers; nblogger++) {
 
280
                const struct logsrv *logsrv = logsrvs[nblogger];
 
281
                int *plogfd = logsrv->u.addr.sa_family == AF_UNIX ?
 
282
                        &logfdunix : &logfdinet;
 
283
                int sent;
 
284
 
231
285
                /* we can filter the level of the messages that are sent to each logger */
232
 
                if (level > loglevel[nbloggers])
 
286
                if (level > loglevel[nblogger])
233
287
                        continue;
234
288
        
235
289
                /* For each target, we may have a different facility.
239
293
                 * time, we only change the facility in the pre-computed header,
240
294
                 * and we change the pointer to the header accordingly.
241
295
                 */
242
 
                fac_level = (facilities[nbloggers] << 3) + level;
 
296
                fac_level = (facilities[nblogger] << 3) + level;
243
297
                log_ptr = logmsg + 3; /* last digit of the log level */
244
298
                do {
245
299
                        *log_ptr = '0' + fac_level % 10;
249
303
                *log_ptr = '<';
250
304
        
251
305
                /* the total syslog message now starts at logptr, for dataptr+data_len-logptr */
252
 
 
253
 
#ifndef MSG_NOSIGNAL
254
 
                sendto(logfd, log_ptr, dataptr + data_len - log_ptr, MSG_DONTWAIT,
255
 
                       (struct sockaddr *)sa[nbloggers], sizeof(**sa));
256
 
#else
257
 
                sendto(logfd, log_ptr, dataptr + data_len - log_ptr, MSG_DONTWAIT | MSG_NOSIGNAL,
258
 
                       (struct sockaddr *)sa[nbloggers], sizeof(**sa));
259
 
#endif
 
306
                sent = sendto(*plogfd, log_ptr, dataptr + data_len - log_ptr,
 
307
                        MSG_DONTWAIT | MSG_NOSIGNAL, &logsrv->u.addr, logsrv_addrlen(logsrv));
 
308
                if (sent < 0) {
 
309
                        Alert("sendto logger #%d failed: %s (errno=%d)\n",
 
310
                                nblogger, strerror(errno), errno);
 
311
                }
260
312
        }
261
313
}
262
314
 
272
324
        struct proxy *prx_log;
273
325
        int tolog;
274
326
        char *svid;
275
 
        struct tm *tm;
 
327
        struct tm tm;
276
328
 
277
329
        if (s->cli_addr.ss_family == AF_INET)
278
330
                inet_ntop(AF_INET,
283
335
                          (const void *)&((struct sockaddr_in6 *)(&s->cli_addr))->sin6_addr,
284
336
                          pn, sizeof(pn));
285
337
 
286
 
        tm = localtime((time_t *)&s->logs.tv_accept.tv_sec);
 
338
        get_localtime(s->logs.tv_accept.tv_sec, &tm);
287
339
 
288
340
        if (fe->logfac1 >= 0)
289
341
                prx_log = fe;
309
361
                 (s->cli_addr.ss_family == AF_INET) ?
310
362
                 ntohs(((struct sockaddr_in *)&s->cli_addr)->sin_port) :
311
363
                 ntohs(((struct sockaddr_in6 *)&s->cli_addr)->sin6_port),
312
 
                 tm->tm_mday, monthname[tm->tm_mon], tm->tm_year+1900,
313
 
                 tm->tm_hour, tm->tm_min, tm->tm_sec, s->logs.tv_accept.tv_usec/1000,
 
364
                 tm.tm_mday, monthname[tm.tm_mon], tm.tm_year+1900,
 
365
                 tm.tm_hour, tm.tm_min, tm.tm_sec, s->logs.tv_accept.tv_usec/1000,
314
366
                 fe->id, be->id, svid,
315
367
                 (s->logs.t_queue >= 0) ? s->logs.t_queue : -1,
316
368
                 (s->logs.t_connect >= 0) ? s->logs.t_connect - s->logs.t_queue : -1,
317
369
                 (tolog & LW_BYTES) ? "" : "+", s->logs.t_close,
318
 
                 (tolog & LW_BYTES) ? "" : "+", s->logs.bytes_in,
 
370
                 (tolog & LW_BYTES) ? "" : "+", s->logs.bytes_out,
319
371
                 sess_term_cond[(s->flags & SN_ERR_MASK) >> SN_ERR_SHIFT],
320
372
                 sess_fin_state[(s->flags & SN_FINST_MASK) >> SN_FINST_SHIFT],
321
373
                 actconn, fe->feconn, be->beconn, s->srv ? s->srv->cur_sess : 0,