]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: log: handle log-profile in process_send_log()
authorAurelien DARRAGON <adarragon@haproxy.com>
Thu, 30 May 2024 15:14:58 +0000 (17:14 +0200)
committerAurelien DARRAGON <adarragon@haproxy.com>
Thu, 13 Jun 2024 13:43:09 +0000 (15:43 +0200)
In previous commit we implemented log-profile parsing logic. Now let's
actually make use of available log-profile information from logger struct
to decide whether we need to rebuild the logline under process_send_log()
according to log profile settings. Nothing is done if the logger didn't
specify a log-profile.

src/log.c

index a2086454565984b945ef6977559ebd4876b928b1..42b5acad5c5dfd8ca83f2714925a04ed7441d023 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -2855,6 +2855,101 @@ struct process_send_log_ctx {
        enum log_orig origin;
 };
 
+static inline void _process_send_log_final(struct logger *logger, struct log_header hdr,
+                                           char *message, size_t size, int nblogger)
+{
+       if (logger->target.type == LOG_TARGET_BACKEND) {
+               __do_send_log_backend(logger->target.be, hdr, nblogger, logger->maxlen, message, size);
+       }
+       else {
+               /* normal target */
+               __do_send_log(&logger->target, hdr, nblogger, logger->maxlen, message, size);
+       }
+}
+
+static inline void _process_send_log_override(struct process_send_log_ctx *ctx,
+                                              struct logger *logger, struct log_header hdr,
+                                              char *message, size_t size, int nblogger)
+{
+       struct log_profile *prof = logger->prof;
+       struct log_profile_step *step = NULL;
+       struct ist orig_tag = hdr.metadata[LOG_META_TAG];
+       struct ist orig_sd = hdr.metadata[LOG_META_STDATA];
+       enum log_orig orig = (ctx) ? ctx->origin : LOG_ORIG_UNSPEC;
+
+       BUG_ON(!prof);
+
+       if (!b_is_null(&prof->log_tag))
+               hdr.metadata[LOG_META_TAG] = ist2(prof->log_tag.area, prof->log_tag.data);
+
+       /* check if there is a profile step override matching
+        * current logging step
+        */
+       switch (orig) {
+               case LOG_ORIG_SESS_ERROR:
+               case LOG_ORIG_SESS_KILL:
+                       if (prof->error)
+                               step = prof->error;
+                       break;
+               case LOG_ORIG_TXN_ACCEPT:
+                       if (prof->accept)
+                               step = prof->accept;
+                       break;
+               case LOG_ORIG_TXN_REQUEST:
+                       if (prof->request)
+                               step = prof->request;
+                       break;
+               case LOG_ORIG_TXN_CONNECT:
+                       if (prof->connect)
+                               step = prof->connect;
+                       break;
+               case LOG_ORIG_TXN_RESPONSE:
+                       if (prof->response)
+                               step = prof->response;
+                       break;
+               case LOG_ORIG_TXN_CLOSE:
+                       if (prof->close)
+                               step = prof->close;
+                       break;
+               default:
+                       break;
+       }
+
+       if (!step && prof->any)
+               step = prof->any;
+
+       if (ctx && ctx->sess && step) {
+               /* we may need to rebuild message using lf_expr from profile
+                * step and possibly sd metadata if provided on the profile
+                */
+               if (!lf_expr_isempty(&step->logformat)) {
+                       size = sess_build_logline_orig(ctx->sess, ctx->stream,
+                                                      logline_lpf, global.max_syslog_len,
+                                                      &step->logformat,
+                                                      ctx->origin);
+                       if (size == 0)
+                               goto end;
+                       message = logline_lpf;
+               }
+               if (!lf_expr_isempty(&step->logformat_sd)) {
+                       size_t sd_size;
+
+                       sd_size = sess_build_logline_orig(ctx->sess, ctx->stream,
+                                                         logline_rfc5424_lpf, global.max_syslog_len,
+                                                         &step->logformat_sd,
+                                                         ctx->origin);
+                       __send_log_set_metadata_sd(hdr.metadata, logline_rfc5424_lpf, sd_size);
+               }
+       }
+
+       _process_send_log_final(logger, hdr, message, size, nblogger);
+
+ end:
+       /* restore original metadata values */
+       hdr.metadata[LOG_META_TAG] = orig_tag;
+       hdr.metadata[LOG_META_STDATA] = orig_sd;
+}
+
 /*
  * This function sends a syslog message.
  * It doesn't care about errors nor does it report them.
@@ -2913,13 +3008,12 @@ static void process_send_log(struct process_send_log_ctx *ctx,
                        hdr.metadata = metadata;
 
                        nblogger += 1;
-                       if (logger->target.type == LOG_TARGET_BACKEND) {
-                               __do_send_log_backend(logger->target.be, hdr, nblogger, logger->maxlen, message, size);
-                       }
-                       else {
-                               /* normal target */
-                               __do_send_log(&logger->target, hdr, nblogger, logger->maxlen, message, size);
-                       }
+
+                       /* logger may use a profile to override a few things */
+                       if (unlikely(logger->prof))
+                               _process_send_log_override(ctx, logger, hdr, message, size, nblogger);
+                       else
+                               _process_send_log_final(logger, hdr, message, size, nblogger);
                }
        }
 }