]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: log: provide sending log context to process_send_log() when available
authorAurelien DARRAGON <adarragon@haproxy.com>
Thu, 22 Feb 2024 10:29:20 +0000 (11:29 +0100)
committerAurelien DARRAGON <adarragon@haproxy.com>
Thu, 13 Jun 2024 13:43:09 +0000 (15:43 +0200)
This is another prerequisite work in preparation for log-profiles: in this
patch we make process_send_log() aware of the log origin, primarily aiming
for sess and txn logging steps such as error, accept, connect, close, as
well as relevant sess and stream pointers.

include/haproxy/log-t.h
include/haproxy/log.h
include/haproxy/stream-t.h
src/cli.c
src/frontend.c
src/http_ana.c
src/log.c
src/stream.c

index 8768e10e7efc67d21cf77211cc28e4c24a16c265..bbfc7cdc28720cf6d43feb34698e553a88f6e9fd 100644 (file)
@@ -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 */
 
 /*
index eef7654f519a208bdb3161a1c91e435df96fd023..f842f7c145c77aa6492d23ac31156cf6464b3497 100644 (file)
@@ -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
index b96512e0c9a818272e634c4bc1db9900bb512212..9b8111c1e232d4268a6909413617d482c1784f72 100644 (file)
@@ -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);
 
index 9470d127ad9777ad47047ea2f33005740b7e7c00..a1c9323631eddd39a815e59cb473a4ec12e95c87 100644 (file)
--- 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 */
index 3b3bcbb1631e58338168abd703921487f0d9c7e6..8613926639029bf952408ee8eb48b7a985fdc2df 100644 (file)
@@ -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);
index 51963412e1b71a5d4be09daa4be3a589dcc0da6b..3912295239c9aa14808381751570131c975221f9 100644 (file)
@@ -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;
        }
 
index 189bfbd9cdde626f66a1be299a7342a8b9b7ee92..100f0d689a7dda82d987523950a5d1231fcfadbd 100644 (file)
--- 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 <sd> and <sd_size> 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 <buf>, of size <buflen>
@@ -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);
 
        }
 
index ed5c268b855c97bf94c280561c17f2aa2ecaf0e0..7c2160b222cf33b1c95cfea098e5b5dbe29a8809 100644 (file)
@@ -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 */