From 6f177cd01e63259c37488de88b451fc50a3e9d71 Mon Sep 17 00:00:00 2001 From: Miroslav Zagorac Date: Sat, 7 Mar 2026 15:28:10 +0100 Subject: [PATCH] MINOR: otel: added log-record signal support Added "log-record" as the third OpenTelemetry signal alongside traces (span) and metrics (instrument). This includes the flt_otel_conf_log_record structure definition, parser keyword defines, the otel-scope section parser with optional "id", "event", "span", and "attr" keywords followed by sample fetch expressions or a log-format string, init/free lifecycle, scope list wiring, log-format evaluation in flt_otel_scope_run_instrument_record(), a test configuration example, log-record span reference validation in flt_otel_check(), and logger handle creation, startup, and teardown in the filter lifecycle. --- addons/otel/include/conf.h | 45 ++++++++-- addons/otel/include/conf_funcs.h | 7 ++ addons/otel/include/parser.h | 5 ++ addons/otel/src/cli.c | 1 + addons/otel/src/conf.c | 56 +++++++++++++ addons/otel/src/event.c | 139 ++++++++++++++++++++++++++++++- addons/otel/src/filter.c | 57 ++++++++++++- addons/otel/src/parser.c | 108 +++++++++++++++++++++++- addons/otel/test/sa/otel.cfg | 3 + 9 files changed, 410 insertions(+), 11 deletions(-) diff --git a/addons/otel/include/conf.h b/addons/otel/include/conf.h index 5441666ee..9549957f8 100644 --- a/addons/otel/include/conf.h +++ b/addons/otel/include/conf.h @@ -31,6 +31,13 @@ #define FLT_OTEL_CONF_HDR_FMT "%p:{ { '%.*s' %zu %d } " #define FLT_OTEL_CONF_HDR_ARGS(p,m) (int)(p)->m##_len, (p)->m, (p)->m##_len, (p)->cfg_line +/* + * Special two-byte prefix that triggers automatic id generation in + * FLT_OTEL_CONF_FUNC_INIT(): the text after the prefix is combined + * with the configuration line number to form a unique identifier. + */ +#define FLT_OTEL_CONF_HDR_SPECIAL "\x1e\x1f" + #define FLT_OTEL_CONF_STR_CMP(s,S) ((s##_len == S##_len) && (memcmp(s, S, S##_len) == 0)) #define FLT_OTEL_DBG_CONF_SAMPLE_EXPR(h,p) \ @@ -56,11 +63,11 @@ flt_otel_list_dump(&((p)->statuses))) #define FLT_OTEL_DBG_CONF_SCOPE(h,p) \ - OTELC_DBG_STRUCT(DEBUG, h, h FLT_OTEL_CONF_HDR_FMT "%hhu %d %u %s %p %s %s %s %s }", (p), \ + OTELC_DBG_STRUCT(DEBUG, h, h FLT_OTEL_CONF_HDR_FMT "%hhu %d %u %s %p %s %s %s %s %s }", (p), \ FLT_OTEL_CONF_HDR_ARGS(p, id), (p)->flag_used, (p)->event, (p)->idle_timeout, \ flt_otel_list_dump(&((p)->acls)), (p)->cond, flt_otel_list_dump(&((p)->contexts)), \ flt_otel_list_dump(&((p)->spans)), flt_otel_list_dump(&((p)->spans_to_finish)), \ - flt_otel_list_dump(&((p)->instruments))) + flt_otel_list_dump(&((p)->instruments)), flt_otel_list_dump(&((p)->log_records))) #define FLT_OTEL_DBG_CONF_GROUP(h,p) \ OTELC_DBG_STRUCT(DEBUG, h, h FLT_OTEL_CONF_HDR_FMT "%hhu %s }", (p), \ @@ -69,11 +76,12 @@ #define FLT_OTEL_DBG_CONF_PH(h,p) \ OTELC_DBG_STRUCT(DEBUG, h, h FLT_OTEL_CONF_HDR_FMT "%p }", (p), FLT_OTEL_CONF_HDR_ARGS(p, id), (p)->ptr) -#define FLT_OTEL_DBG_CONF_INSTR(h,p) \ - OTELC_DBG_STRUCT(DEBUG, h, h FLT_OTEL_CONF_HDR_FMT "'%s' %p %p %u %hhu %hhu 0x%02hhx %p:%s 0x%08x %u %s %s %s }", (p), \ - FLT_OTEL_CONF_HDR_ARGS(p, id), (p)->config, (p)->tracer, (p)->meter, (p)->rate_limit, (p)->flag_harderr, \ - (p)->flag_disabled, (p)->logging, &((p)->proxy_log), flt_otel_list_dump(&((p)->proxy_log.loggers)), \ - (p)->analyzers, (p)->idle_timeout, flt_otel_list_dump(&((p)->acls)), flt_otel_list_dump(&((p)->ph_groups)), \ +#define FLT_OTEL_DBG_CONF_INSTR(h,p) \ + OTELC_DBG_STRUCT(DEBUG, h, h FLT_OTEL_CONF_HDR_FMT "'%s' %p %p %p %u %hhu %hhu 0x%02hhx %p:%s 0x%08x %u %s %s %s }", \ + (p), FLT_OTEL_CONF_HDR_ARGS(p, id), (p)->config, (p)->tracer, (p)->meter, (p)->logger, \ + (p)->rate_limit, (p)->flag_harderr, (p)->flag_disabled, (p)->logging, &((p)->proxy_log), \ + flt_otel_list_dump(&((p)->proxy_log.loggers)), (p)->analyzers, (p)->idle_timeout, \ + flt_otel_list_dump(&((p)->acls)), flt_otel_list_dump(&((p)->ph_groups)), \ flt_otel_list_dump(&((p)->ph_scopes))) #define FLT_OTEL_DBG_CONF_INSTRUMENT(h,p) \ @@ -82,6 +90,11 @@ OTELC_STR_ARG((p)->unit), flt_otel_list_dump(&((p)->samples)), (p)->attr, (p)->attr_len, (p)->ref, \ (p)->bounds_num, (p)->bounds) +#define FLT_OTEL_DBG_CONF_LOG_RECORD(h,p) \ + OTELC_DBG_STRUCT(DEBUG, h, h FLT_OTEL_CONF_HDR_FMT "%d %" PRId64 " '%s' '%s' %p %zu %p }", (p), \ + FLT_OTEL_CONF_HDR_ARGS(p, id), (p)->severity, (p)->event_id, OTELC_STR_ARG((p)->event_name), \ + OTELC_STR_ARG((p)->span), (p)->attr, (p)->attr_len, flt_otel_list_dump(&((p)->samples))) + #define FLT_OTEL_DBG_CONF(h,p) \ OTELC_DBG(DEBUG, h "%p:{ %p '%s' '%s' %p %s %s }", (p), \ (p)->proxy, (p)->id, (p)->cfg_file, (p)->instr, \ @@ -120,6 +133,7 @@ struct flt_otel_conf_sample_expr { * flt_otel_conf_span->baggages * flt_otel_conf_span->statuses (status_code -> extra.u.value_int32) * flt_otel_conf_instrument->samples + * flt_otel_conf_log_record->samples */ struct flt_otel_conf_sample { FLT_OTEL_CONF_HDR(key); /* The list containing sample names. */ @@ -188,6 +202,21 @@ struct flt_otel_conf_instrument { struct flt_otel_conf_instrument *ref; /* Resolved create-form instrument (update only). */ }; +/* + * Log record configuration within a scope. + * flt_otel_conf_scope->log_records + */ +struct flt_otel_conf_log_record { + FLT_OTEL_CONF_HDR(id); /* Required by macro; member is not used directly. */ + otelc_log_severity_t severity; /* The severity level. */ + int64_t event_id; /* Optional event identifier. */ + char *event_name; /* Optional event name. */ + char *span; /* Optional span reference. */ + struct otelc_kv *attr; /* Log record attributes. */ + size_t attr_len; /* Number of log record attributes. */ + struct list samples; /* Sample expressions for the body. */ +}; + /* Configuration for a single event scope. */ struct flt_otel_conf_scope { FLT_OTEL_CONF_HDR(id); /* The scope name. */ @@ -200,6 +229,7 @@ struct flt_otel_conf_scope { struct list spans; /* Declared spans. */ struct list spans_to_finish; /* The list of spans scheduled for finishing. */ struct list instruments; /* The list of metric instruments. */ + struct list log_records; /* The list of log records. */ }; /* Configuration for a named group of scopes. */ @@ -223,6 +253,7 @@ struct flt_otel_conf_instr { char *config; /* The OpenTelemetry configuration file name. */ struct otelc_tracer *tracer; /* The OpenTelemetry tracer handle. */ struct otelc_meter *meter; /* The OpenTelemetry meter handle. */ + struct otelc_logger *logger; /* The OpenTelemetry logger handle. */ uint32_t rate_limit; /* [0 2^32-1] <-> [0.0 100.0] */ bool flag_harderr; /* [0 1] */ bool flag_disabled; /* [0 1] */ diff --git a/addons/otel/include/conf_funcs.h b/addons/otel/include/conf_funcs.h index 4459e02bb..6e11bac35 100644 --- a/addons/otel/include/conf_funcs.h +++ b/addons/otel/include/conf_funcs.h @@ -14,6 +14,7 @@ { \ struct flt_otel_conf_##_type_ *retptr = NULL; \ struct flt_otel_conf_##_type_ *ptr; \ + char id_buffer[FLT_OTEL_ID_MAXLEN + 16]; \ size_t _id_##_len; \ \ OTELC_FUNC("\"%s\", %d, %p, %p:%p", OTELC_STR_ARG(id), line, head, OTELC_DPTR_ARGS(err)); \ @@ -22,6 +23,11 @@ FLT_OTEL_ERR("name not set"); \ \ OTELC_RETURN_PTR(retptr); \ + } \ + else if ((id[0] == FLT_OTEL_CONF_HDR_SPECIAL[0]) && (id[1] == FLT_OTEL_CONF_HDR_SPECIAL[1])) { \ + (void)snprintf(id_buffer, sizeof(id_buffer), "%s:%d", id + 2, line); \ + \ + id = id_buffer; \ } \ \ _id_##_len = strlen(id); \ @@ -106,6 +112,7 @@ FLT_OTEL_CONF_FUNC_DECL(context) FLT_OTEL_CONF_FUNC_DECL(span) FLT_OTEL_CONF_FUNC_DECL(scope) FLT_OTEL_CONF_FUNC_DECL(instrument) +FLT_OTEL_CONF_FUNC_DECL(log_record) FLT_OTEL_CONF_FUNC_DECL(group) FLT_OTEL_CONF_FUNC_DECL(instr) diff --git a/addons/otel/include/parser.h b/addons/otel/include/parser.h index dde98aa47..8e4a79a1c 100644 --- a/addons/otel/include/parser.h +++ b/addons/otel/include/parser.h @@ -26,6 +26,10 @@ #define FLT_OTEL_PARSE_INSTRUMENT_UNIT "unit" #define FLT_OTEL_PARSE_INSTRUMENT_BOUNDS "bounds" #define FLT_OTEL_PARSE_INSTRUMENT_AGGR "aggr" +#define FLT_OTEL_PARSE_LOG_RECORD_ID "id" +#define FLT_OTEL_PARSE_LOG_RECORD_EVENT "event" +#define FLT_OTEL_PARSE_LOG_RECORD_SPAN "span" +#define FLT_OTEL_PARSE_LOG_RECORD_ATTR "attr" #define FLT_OTEL_PARSE_CTX_AUTONAME "-" #define FLT_OTEL_PARSE_CTX_IGNORE_NAME '-' #define FLT_OTEL_PARSE_CTX_USE_HEADERS "use-headers" @@ -117,6 +121,7 @@ FLT_OTEL_PARSE_SCOPE_DEF( STATUS, 1, NONE, 2, 0, "status", " [ ...]") \ FLT_OTEL_PARSE_SCOPE_DEF( FINISH, 0, NONE, 2, 0, "finish", " ...") \ FLT_OTEL_PARSE_SCOPE_DEF( INSTRUMENT, 0, NONE, 3, 0, "instrument", " { update [ ...] | [] [] [] [] }") \ + FLT_OTEL_PARSE_SCOPE_DEF( LOG_RECORD, 0, NONE, 3, 0, "log-record", " [] [] [] [] ") \ FLT_OTEL_PARSE_SCOPE_DEF(IDLE_TIMEOUT, 0, NONE, 2, 2, "idle-timeout", "