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
| | %hsl | captured_response_headers CLF style | string |
| | | | list |
+---+------+------------------------------------------------------+---------+
+ | L | %OG | human readable log origin | string |
+ +---+------+------------------------------------------------------+---------+
| | %pid | PID | |
| | | %[pid] | numeric |
+---+------+------------------------------------------------------+---------+
| 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
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.
/*
* 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);
/* logformat alias types (internal use) */
enum logformat_alias_type {
LOG_FMT_GLOBAL,
+ LOG_FMT_ORIGIN,
LOG_FMT_CLIENTIP,
LOG_FMT_CLIENTPORT,
LOG_FMT_BACKENDIP,
/* 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 */
* 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;
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) {
}
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;
{
int size, level;
int sd_size = 0;
+ int orig = (embryonic) ? LOG_ORIG_SESS_KILL : LOG_ORIG_SESS_ERROR;
if (!sess)
return;
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;
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,