diff --git a/include/haproxy/log-t.h b/include/haproxy/log-t.h index 8768e10e7..bbfc7cdc2 100644 --- a/include/haproxy/log-t.h +++ b/include/haproxy/log-t.h @@ -247,6 +247,20 @@ struct logger { } conf; }; +/* integer used to provide some context about the log origin + * when sending log through logging functions + */ +enum log_orig { + LOG_ORIG_UNSPEC = 0, /* unspecified */ + LOG_ORIG_SESS_ERROR, /* general error during session handling */ + LOG_ORIG_SESS_KILL, /* during embryonic session kill */ + LOG_ORIG_TXN_ACCEPT, /* during stream accept handling */ + LOG_ORIG_TXN_REQUEST, /* during stream request handling */ + LOG_ORIG_TXN_CONNECT, /* during stream connect handling */ + LOG_ORIG_TXN_RESPONSE, /* during stream response handling */ + LOG_ORIG_TXN_CLOSE, /* during stream termination */ +}; + #endif /* _HAPROXY_LOG_T_H */ /* diff --git a/include/haproxy/log.h b/include/haproxy/log.h index eef7654f5..f842f7c14 100644 --- a/include/haproxy/log.h +++ b/include/haproxy/log.h @@ -86,7 +86,7 @@ int sess_build_logline(struct session *sess, struct stream *s, char *dst, size_t * send a log for the stream when we have enough info about it. * Will not log if the frontend has no log defined. */ -void strm_log(struct stream *s); +void strm_log(struct stream *s, int origin); /* send an error log for the session, embryonic version should be used * when the log is emitted for a session which is still in embryonic state diff --git a/include/haproxy/stream-t.h b/include/haproxy/stream-t.h index b96512e0c..9b8111c1e 100644 --- a/include/haproxy/stream-t.h +++ b/include/haproxy/stream-t.h @@ -265,7 +265,8 @@ struct stream { struct strm_logs logs; /* logs for this stream */ - void (*do_log)(struct stream *s); /* the function to call in order to log (or NULL) */ + void (*do_log)(struct stream *s, /* the function to call in order to log (or NULL) */ + int origin); void (*srv_error)(struct stream *s, /* the function to call upon unrecoverable server errors (or NULL) */ struct stconn *sc); diff --git a/src/cli.c b/src/cli.c index 9470d127a..a1c932363 100644 --- a/src/cli.c +++ b/src/cli.c @@ -3144,7 +3144,7 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit) if (!lf_expr_isempty(&fe->logformat) && s->logs.logwait && !(s->flags & SF_MONITOR) && (!(fe->options & PR_O_NULLNOLOG) || s->req.total)) { - s->do_log(s); + s->do_log(s, LOG_ORIG_TXN_CLOSE); } /* stop tracking content-based counters */ diff --git a/src/frontend.c b/src/frontend.c index 3b3bcbb16..861392663 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -59,7 +59,7 @@ int frontend_accept(struct stream *s) /* we have the client ip */ if (s->logs.logwait & LW_CLIP) if (!(s->logs.logwait &= ~(LW_CLIP|LW_INIT))) - s->do_log(s); + s->do_log(s, LOG_ORIG_TXN_ACCEPT); } else if (conn) { src = sc_src(s->scf); diff --git a/src/http_ana.c b/src/http_ana.c index 51963412e..391229523 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -273,7 +273,7 @@ int http_wait_for_request(struct stream *s, struct channel *req, int an_bit) txn->uri[len] = 0; if (!(s->logs.logwait &= ~(LW_REQ|LW_INIT))) - s->do_log(s); + s->do_log(s, LOG_ORIG_TXN_REQUEST); } else { ha_alert("HTTP logging : out of memory.\n"); } @@ -1910,7 +1910,7 @@ int http_process_res_common(struct stream *s, struct channel *rep, int an_bit, s if (!lf_expr_isempty(&sess->fe->logformat) && !(s->logs.logwait & LW_BYTES)) { s->logs.t_close = s->logs.t_data; /* to get a valid end date */ s->logs.bytes_out = htx->data; - s->do_log(s); + s->do_log(s, LOG_ORIG_TXN_RESPONSE); s->logs.bytes_out = 0; } diff --git a/src/log.c b/src/log.c index 189bfbd9c..100f0d689 100644 --- a/src/log.c +++ b/src/log.c @@ -2751,6 +2751,13 @@ static inline void __do_send_log_backend(struct proxy *be, struct log_header hdr _HA_ATOMIC_INC(&dropped_logs); } +/* provided to low-level process_send_log() helper, may be NULL */ +struct process_send_log_ctx { + struct session *sess; + struct stream *stream; + enum log_orig origin; +}; + /* * This function sends a syslog message. * It doesn't care about errors nor does it report them. @@ -2758,7 +2765,8 @@ static inline void __do_send_log_backend(struct proxy *be, struct log_header hdr * LOG_META_FIELDS*sizeof(struct ist) containing * data to build the header. */ -static void process_send_log(struct list *loggers, int level, int facility, +static void process_send_log(struct process_send_log_ctx *ctx, + struct list *loggers, int level, int facility, struct ist *metadata, char *message, size_t size) { struct logger *logger; @@ -2825,7 +2833,8 @@ static void process_send_log(struct list *loggers, int level, int facility, * The arguments and are used for the structured-data part * in RFC5424 formatted syslog messages. */ -static void __send_log(struct list *loggers, struct buffer *tagb, int level, +static void __send_log(struct process_send_log_ctx *ctx, + struct list *loggers, struct buffer *tagb, int level, char *message, size_t size, char *sd, size_t sd_size) { static THREAD_LOCAL pid_t curr_pid; @@ -2866,7 +2875,7 @@ static void __send_log(struct list *loggers, struct buffer *tagb, int level, while (metadata[LOG_META_STDATA].len && metadata[LOG_META_STDATA].ptr[metadata[LOG_META_STDATA].len-1] == ' ') metadata[LOG_META_STDATA].len--; - return process_send_log(loggers, level, -1, metadata, message, size); + return process_send_log(ctx, loggers, level, -1, metadata, message, size); } /* @@ -2887,7 +2896,8 @@ void send_log(struct proxy *p, int level, const char *format, ...) data_len = global.max_syslog_len; va_end(argp); - __send_log((p ? &p->loggers : NULL), (p ? &p->log_tag : NULL), level, + __send_log(NULL, (p ? &p->loggers : NULL), + (p ? &p->log_tag : NULL), level, logline, data_len, default_rfc5424_sd_log_format, 2); } @@ -4889,7 +4899,7 @@ out: * send a log for the stream when we have enough info about it. * Will not log if the frontend has no log defined. */ -void strm_log(struct stream *s) +void strm_log(struct stream *s, int origin) { struct session *sess = s->sess; int size, err, level; @@ -4932,8 +4942,13 @@ void strm_log(struct stream *s) size = build_logline(s, logline, global.max_syslog_len, &sess->fe->logformat); if (size > 0) { + struct process_send_log_ctx ctx; + _HA_ATOMIC_INC(&sess->fe->log_count); - __send_log(&sess->fe->loggers, &sess->fe->log_tag, level, + ctx.origin = origin; + ctx.sess = sess; + ctx.stream = s; + __send_log(&ctx, &sess->fe->loggers, &sess->fe->log_tag, level, logline, size + 1, logline_rfc5424, sd_size); s->logs.logwait = 0; } @@ -4985,8 +5000,14 @@ void _sess_log(struct session *sess, int embryonic) size = buf.data; } if (size > 0) { + struct process_send_log_ctx ctx; + _HA_ATOMIC_INC(&sess->fe->log_count); - __send_log(&sess->fe->loggers, &sess->fe->log_tag, level, + ctx.origin = (embryonic) ? LOG_ORIG_SESS_KILL : LOG_ORIG_SESS_ERROR; + ctx.sess = sess; + ctx.stream = NULL; + __send_log(&ctx, &sess->fe->loggers, + &sess->fe->log_tag, level, logline, size + 1, logline_rfc5424, sd_size); } } @@ -5005,7 +5026,7 @@ void app_log(struct list *loggers, struct buffer *tag, int level, const char *fo data_len = global.max_syslog_len; va_end(argp); - __send_log(loggers, tag, level, logline, data_len, default_rfc5424_sd_log_format, 2); + __send_log(NULL, loggers, tag, level, logline, data_len, default_rfc5424_sd_log_format, 2); } /* * This function parse a received log message , of size @@ -5379,7 +5400,7 @@ void syslog_fd_handler(int fd) parse_log_message(buf->area, buf->data, &level, &facility, metadata, &message, &size); - process_send_log(&l->bind_conf->frontend->loggers, level, facility, metadata, message, size); + process_send_log(NULL, &l->bind_conf->frontend->loggers, level, facility, metadata, message, size); } while (--max_accept); } @@ -5491,7 +5512,7 @@ static void syslog_io_handler(struct appctx *appctx) parse_log_message(buf->area, buf->data, &level, &facility, metadata, &message, &size); - process_send_log(&frontend->loggers, level, facility, metadata, message, size); + process_send_log(NULL, &frontend->loggers, level, facility, metadata, message, size); } diff --git a/src/stream.c b/src/stream.c index ed5c268b8..7c2160b22 100644 --- a/src/stream.c +++ b/src/stream.c @@ -924,7 +924,7 @@ void back_establish(struct stream *s) if (!lf_expr_isempty(&strm_fe(s)->logformat) && !(s->logs.logwait & LW_BYTES)) { /* note: no pend_pos here, session is established */ s->logs.t_close = s->logs.t_connect; /* to get a valid end date */ - s->do_log(s); + s->do_log(s, LOG_ORIG_TXN_CONNECT); } } else { @@ -2592,7 +2592,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state) pendconn_free(s); stream_cond_update_cpu_usage(s); - s->do_log(s); + s->do_log(s, LOG_ORIG_TXN_CLOSE); } /* update time stats for this stream */