MEDIUM: log: optimizing tmp->type handling in sess_build_logline()

Instead of chaining 2 switchcases and performing encoding checks for all
nodes let's actually split the logic in 2: first handle simple node types
(text/separator), and then handle dynamic node types (tag, expr). Encoding
options are only evaluated for dynamic node types.

Also, last_isspace is always set to 0 after next_fmt label, since next_fmt
label is only used for dynamic nodes, thus != LOG_FMT_SEPARATOR.

Since LF_NODE_WITH_OPT() macro (which was introduced recently) is now
unused, let's get rid of it.

No functional change should be expected.

(Use diff -w to check patch changes since reindentation makes the patch
look heavy, but in fact it remains fairly small)
This commit is contained in:
Aurelien DARRAGON 2024-04-30 15:52:57 +02:00
parent 437062255e
commit 48e0efb00b
2 changed files with 107 additions and 104 deletions

View File

@ -174,10 +174,6 @@ struct logformat_node {
const struct logformat_tag *tag; // set if ->type == LOG_FMT_TAG
};
/* returns true if the node options may be set (according to it's type) */
#define LF_NODE_WITH_OPT(node) \
(node->type == LOG_FMT_EXPR || node->type == LOG_FMT_TAG)
enum lf_expr_flags {
LF_FL_NONE = 0x00,
LF_FL_COMPILED = 0x01

View File

@ -3644,16 +3644,43 @@ int sess_build_logline(struct session *sess, struct stream *s, char *dst, size_t
struct sample *key;
const struct buffer empty = { };
/* first start with basic types (use continue statement to skip
* the current node)
*/
if (tmp->type == LOG_FMT_SEPARATOR) {
if (g_options & LOG_OPT_ENCODE) {
/* ignored when global encoding is set */
continue;
}
if (!last_isspace) {
LOGCHAR(' ');
last_isspace = 1;
}
continue;
}
else if (tmp->type == LOG_FMT_TEXT) {
/* text */
if (g_options & LOG_OPT_ENCODE) {
/* ignored when global encoding is set */
continue;
}
src = tmp->arg;
iret = strlcpy2(tmplog, src, dst + maxsize - tmplog);
if (iret == 0)
goto out;
tmplog += iret;
last_isspace = 0; /* data was written */
continue;
}
/* dynamic types handling (use "goto next_fmt" statement to skip
* the current node)
*/
if (g_options & LOG_OPT_ENCODE) {
/* only consider global ctx for key encoding */
lf_buildctx_prepare(&ctx, g_options, NULL);
/* types that cannot be named such as text or separator are ignored
* when encoding is set
*/
if (!LF_NODE_WITH_OPT(tmp))
goto next_fmt;
if (!tmp->name)
goto next_fmt; /* cannot represent anonymous field, ignore */
@ -3692,24 +3719,8 @@ int sess_build_logline(struct session *sess, struct stream *s, char *dst, size_t
*/
lf_buildctx_prepare(&ctx, g_options, tmp);
switch (tmp->type) {
case LOG_FMT_SEPARATOR:
if (!last_isspace) {
LOGCHAR(' ');
last_isspace = 1;
}
break;
case LOG_FMT_TEXT: // text
src = tmp->arg;
iret = strlcpy2(tmplog, src, dst + maxsize - tmplog);
if (iret == 0)
goto out;
tmplog += iret;
break;
case LOG_FMT_EXPR: // sample expression, may be request or response
{
if (tmp->type == LOG_FMT_EXPR) {
/* sample expression, may be request or response */
int type;
key = NULL;
@ -3761,7 +3772,6 @@ int sess_build_logline(struct session *sess, struct stream *s, char *dst, size_t
if (key && !sample_convert(key, type))
key = NULL;
if (ctx.options & LOG_OPT_HTTP)
ret = lf_encode_chunk(tmplog, dst + maxsize,
'%', http_encode_map, key ? &key->data.u.str : &empty, &ctx);
@ -3787,12 +3797,10 @@ int sess_build_logline(struct session *sess, struct stream *s, char *dst, size_t
if (ret == NULL)
goto out;
tmplog = ret;
break;
}
goto next_fmt;
}
if (tmp->type != LOG_FMT_TAG)
goto next_fmt;
BUG_ON(tmp->type != LOG_FMT_TAG);
/* logformat tag */
switch (tmp->tag->type) {
@ -4748,8 +4756,7 @@ int sess_build_logline(struct session *sess, struct stream *s, char *dst, size_t
}
next_fmt:
if (tmp->type != LOG_FMT_SEPARATOR)
last_isspace = 0; // not a separator, hence not a space
last_isspace = 0;
if (value_beg == tmplog) {
/* handle the case where no data was generated for the value after