MEDIUM: log/session: handle embryonic session log within sess_log()

Move the embryonic session logging logic down to sess_log() in preparation
for log-profiles because then log preferences will be set per logger and
not per proxy. Indeed, as each logger may come with its own log-profile
that possibly overrides proxy logformat preferences, the check will need
to be performed at a central place by lower sending functions.

To ensure the change doesn't break existing behavior, a dedicated
sess_log_embryonic() wrapper was added and is exclusively used by
session_kill_embryonic() to indicate that a special logging logic must
be performed under sess_log().

Also, thanks to this change, log-format-sd will now be taken into account
for legacy embryonic session logging.
This commit is contained in:
Aurelien DARRAGON 2024-02-21 17:26:52 +01:00
parent 79a0a7b4d8
commit 0b7a5a64eb
3 changed files with 28 additions and 15 deletions

View File

@ -87,7 +87,20 @@ int sess_build_logline(struct session *sess, struct stream *s, char *dst, size_t
* Will not log if the frontend has no log defined.
*/
void strm_log(struct stream *s);
void sess_log(struct session *sess);
/* 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
* (originating from a connection) and requires special handling.
*/
void _sess_log(struct session *sess, int embryonic);
static inline void sess_log(struct session *sess)
{
_sess_log(sess, 0);
}
static inline void sess_log_embryonic(struct session *sess)
{
_sess_log(sess, 1);
}
/* send a applicative log with custom list of loggers */
void app_log(struct list *loggers, struct buffer *tag, int level, const char *format, ...)

View File

@ -4947,8 +4947,12 @@ void strm_log(struct stream *s)
* in the frontend. The caller must simply know that it should not call this
* function to report unimportant events. It is safe to call this function with
* sess==NULL (will not do anything).
*
* if <embryonic> is set, then legacy error log payload will be generated unless
* logformat_error is specified (ie: normal logformat is ignored in this case).
*
*/
void sess_log(struct session *sess)
void _sess_log(struct session *sess, int embryonic)
{
int size, level;
int sd_size = 0;
@ -4971,8 +4975,15 @@ void sess_log(struct session *sess)
if (!lf_expr_isempty(&sess->fe->logformat_error))
size = sess_build_logline(sess, NULL, logline, global.max_syslog_len, &sess->fe->logformat_error);
else
else if (!embryonic)
size = sess_build_logline(sess, NULL, logline, global.max_syslog_len, &sess->fe->logformat);
else { /* no logformat_error and embryonic==1 */
struct buffer buf;
buf = b_make(logline, global.max_syslog_len, 0, 0);
session_embryonic_build_legacy_err(sess, &buf);
size = buf.data;
}
if (size > 0) {
_HA_ATOMIC_INC(&sess->fe->log_count);
__send_log(&sess->fe->loggers, &sess->fe->log_tag, level,

View File

@ -422,14 +422,10 @@ void session_embryonic_build_legacy_err(struct session *sess, struct buffer *out
*/
static void session_kill_embryonic(struct session *sess, unsigned int state)
{
int level = LOG_INFO;
struct connection *conn = __objt_conn(sess->origin);
struct task *task = sess->task;
unsigned int log = sess->fe->to_log;
if (sess->fe->options2 & PR_O2_LOGERRORS)
level = LOG_ERR;
if (log && (sess->fe->options & PR_O_NULLNOLOG)) {
/* with "option dontlognull", we don't log connections with no transfer */
if (!conn->err_code ||
@ -449,14 +445,7 @@ static void session_kill_embryonic(struct session *sess, unsigned int state)
conn->err_code = CO_ER_SSL_TIMEOUT;
}
if(!lf_expr_isempty(&sess->fe->logformat_error)) {
/* Display a log line following the configured error-log-format. */
sess_log(sess);
}
else {
session_embryonic_build_legacy_err(sess, &trash);
send_log(sess->fe, level, "%s", trash.area);
}
sess_log_embryonic(sess);
}
/* kill the connection now */