MINOR: log: provide log origin in logformat expressions using '%OG'

'%OG' logformat alias may be used to report the log origin (when/where)
that triggered log generation using sess_build_logline().

Possible values are:
  - "sess_error": log was generated during session error handling
  - "sess_killed": log was generated during session abortion (killed
    embryonic session)
  - "txn_accept": log was generated right after frontend conn was accepted
  - "txn_request": log was generated after client request was received
  - "txn_connect": log was generated after backend connection establishment
  - "txn_response": log was generated during server response handling
  - "txn_close": log was generated at the final txn step, before closing
  - "unspec": unknown or not specified

Documentation was updated.
This commit is contained in:
Aurelien DARRAGON 2024-05-06 14:13:11 +02:00
parent b52862d401
commit 8f34320e15
3 changed files with 66 additions and 13 deletions

View File

@ -25948,6 +25948,22 @@ Special alias "%o" may be used to propagate its flags to all other
logformat items on the same format string. This is particularly handy with
quoted ("Q") and escaped ("E") string formats.
Special alias "%OG" may be used to retrieve the log origin (when / where
the log was generated) in a human readable format. It is particularly useful
with "option logasap" because some log variables or sample fetches could report
incomplete values or behave diffently depending on when / where the logformat
expression was evaluated. Possible values are:
- "sess_error": log was generated during session error handling
- "sess_killed": log was generated during session abortion (killed
embryonic session)
- "txn_accept": log was generated right after frontend conn was accepted
- "txn_request": log was generated after client request was received
- "txn_connect": log was generated after backend connection establishment
- "txn_response": log was generated during server response handling
- "txn_close": log was generated at the final txn step, before closing
- "unspec": unknown or not specified
"%OG" is only relevant in logging context.
Items can optionally be named using ('()'). The name must be provided right
after '%' (before arguments). It will automatically be used as key name when
encoding flag such as "json" or "cbor" is set. When no encoding flag is
@ -26174,6 +26190,8 @@ Please refer to the table below for currently defined aliases :
| | %hsl | captured_response_headers CLF style | string |
| | | | list |
+---+------+------------------------------------------------------+---------+
| L | %OG | human readable log origin | string |
+---+------+------------------------------------------------------+---------+
| | %pid | PID | |
| | | %[pid] | numeric |
+---+------+------------------------------------------------------+---------+
@ -26211,7 +26229,7 @@ Please refer to the table below for currently defined aliases :
| H | %tsc | termination_state with cookie status | string |
+---+------+------------------------------------------------------+---------+
R = Restrictions : H = mode http only ; S = SSL only
R = Restrictions : H = mode http only ; S = SSL only ; L = log only
8.3. Advanced logging options

View File

@ -82,7 +82,15 @@ void free_logformat_list(struct list *fmt);
void free_logformat_node(struct logformat_node *node);
/* build a log line for the session and an optional stream */
int sess_build_logline(struct session *sess, struct stream *s, char *dst, size_t maxsize, struct lf_expr *lf_expr);
int sess_build_logline_orig(struct session *sess, struct stream *s, char *dst, size_t maxsize,
struct lf_expr *lf_expr, enum log_orig orig);
/* wrapper for sess_build_logline_orig(), uses LOG_ORIG_UNSPEC log origin */
static inline int sess_build_logline(struct session *sess, struct stream *s, char *dst, size_t maxsize,
struct lf_expr *lf_expr)
{
return sess_build_logline_orig(sess, s, dst, maxsize, lf_expr, LOG_ORIG_UNSPEC);
}
/*
* send a log for the stream when we have enough info about it.
@ -163,9 +171,18 @@ char * get_format_pid_sep2(int format, size_t *len);
/*
* Builds a log line for the stream (must be valid).
*/
static inline int build_logline_orig(struct stream *s, char *dst, size_t maxsize,
struct lf_expr *lf_expr, enum log_orig orig)
{
return sess_build_logline_orig(strm_sess(s), s, dst, maxsize, lf_expr, orig);
}
/*
* Wrapper for build_logline_orig, uses LOG_ORIG_UNSPEC log origin
*/
static inline int build_logline(struct stream *s, char *dst, size_t maxsize, struct lf_expr *lf_expr)
{
return sess_build_logline(strm_sess(s), s, dst, maxsize, lf_expr);
return build_logline_orig(s, dst, maxsize, lf_expr, LOG_ORIG_UNSPEC);
}
struct ist *build_log_header(struct log_header hdr, size_t *nbelem);

View File

@ -151,6 +151,7 @@ int prepare_addrsource(struct logformat_node *node, struct proxy *curproxy);
/* logformat alias types (internal use) */
enum logformat_alias_type {
LOG_FMT_GLOBAL,
LOG_FMT_ORIGIN,
LOG_FMT_CLIENTIP,
LOG_FMT_CLIENTPORT,
LOG_FMT_BACKENDIP,
@ -219,6 +220,7 @@ enum logformat_alias_type {
/* log_format alias names */
static const struct logformat_alias logformat_aliases[] = {
{ "o", LOG_FMT_GLOBAL, PR_MODE_TCP, 0, NULL }, /* global option */
{ "OG", LOG_FMT_ORIGIN, PR_MODE_TCP, 0, NULL }, /* human readable log origin */
/* please keep these lines sorted ! */
{ "B", LOG_FMT_BYTES, PR_MODE_TCP, LW_BYTES, NULL }, /* bytes from server to client */
@ -3603,7 +3605,9 @@ int lf_expr_dup(const struct lf_expr *orig, struct lf_expr *dest)
* is not zero. It requires a valid session and optionally a stream. If the
* stream is NULL, default values will be assumed for the stream part.
*/
int sess_build_logline(struct session *sess, struct stream *s, char *dst, size_t maxsize, struct lf_expr *lf_expr)
int sess_build_logline_orig(struct session *sess, struct stream *s,
char *dst, size_t maxsize, struct lf_expr *lf_expr,
enum log_orig log_orig)
{
struct lf_buildctx *ctx = &lf_buildctx;
struct proxy *fe = sess->fe;
@ -4865,6 +4869,14 @@ int sess_build_logline(struct session *sess, struct stream *s, char *dst, size_t
tmplog = ret;
break;
case LOG_FMT_ORIGIN: // %OG
ret = lf_text(tmplog, log_orig_to_str(log_orig),
dst + maxsize - tmplog, ctx);
if (ret == NULL)
goto out;
tmplog = ret;
break;
}
next_fmt:
if (value_beg == tmplog) {
@ -4960,11 +4972,11 @@ void strm_log(struct stream *s, int origin)
}
if (!lf_expr_isempty(&sess->fe->logformat_sd)) {
sd_size = build_logline(s, logline_rfc5424, global.max_syslog_len,
&sess->fe->logformat_sd);
sd_size = build_logline_orig(s, logline_rfc5424, global.max_syslog_len,
&sess->fe->logformat_sd, origin);
}
size = build_logline(s, logline, global.max_syslog_len, &sess->fe->logformat);
size = build_logline_orig(s, logline, global.max_syslog_len, &sess->fe->logformat, origin);
if (size > 0) {
struct process_send_log_ctx ctx;
@ -4995,6 +5007,7 @@ void _sess_log(struct session *sess, int embryonic)
{
int size, level;
int sd_size = 0;
int orig = (embryonic) ? LOG_ORIG_SESS_KILL : LOG_ORIG_SESS_ERROR;
if (!sess)
return;
@ -5007,15 +5020,20 @@ void _sess_log(struct session *sess, int embryonic)
level = LOG_ERR;
if (!lf_expr_isempty(&sess->fe->logformat_sd)) {
sd_size = sess_build_logline(sess, NULL,
logline_rfc5424, global.max_syslog_len,
&sess->fe->logformat_sd);
sd_size = sess_build_logline_orig(sess, NULL,
logline_rfc5424, global.max_syslog_len,
&sess->fe->logformat_sd,
orig);
}
if (!lf_expr_isempty(&sess->fe->logformat_error))
size = sess_build_logline(sess, NULL, logline, global.max_syslog_len, &sess->fe->logformat_error);
size = sess_build_logline_orig(sess, NULL, logline,
global.max_syslog_len, &sess->fe->logformat_error,
orig);
else if (!embryonic)
size = sess_build_logline(sess, NULL, logline, global.max_syslog_len, &sess->fe->logformat);
size = sess_build_logline_orig(sess, NULL, logline,
global.max_syslog_len, &sess->fe->logformat,
orig);
else { /* no logformat_error and embryonic==1 */
struct buffer buf;
@ -5027,7 +5045,7 @@ void _sess_log(struct session *sess, int embryonic)
struct process_send_log_ctx ctx;
_HA_ATOMIC_INC(&sess->fe->log_count);
ctx.origin = (embryonic) ? LOG_ORIG_SESS_KILL : LOG_ORIG_SESS_ERROR;
ctx.origin = orig;
ctx.sess = sess;
ctx.stream = NULL;
__send_log(&ctx, &sess->fe->loggers,