mirror of
https://github.com/haproxy/haproxy.git
synced 2026-04-15 21:59:41 -04:00
Replaced the static key-value attribute storage in log-record with sample-evaluated attributes. The 'attr' keyword now accepts a key and a HAProxy sample expression evaluated at runtime, instead of a static string value. The struct (conf.h) changed from otelc_kv/attr_len to a list of flt_otel_conf_sample entries. The parser (parser.c) calls flt_otel_parse_cfg_sample() with n=1 per attr keyword. At runtime (event.c) each attribute is evaluated via flt_otel_sample_eval() and added via flt_otel_sample_add_kv() to a bare flt_otel_scope_data_kv, which is passed to logger->log_span(). Updated documentation, debug macro and test configurations.
221 lines
12 KiB
C
221 lines
12 KiB
C
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
|
|
#ifndef _OTEL_PARSER_H_
|
|
#define _OTEL_PARSER_H_
|
|
|
|
#define FLT_OTEL_SCOPE "OTEL"
|
|
|
|
/*
|
|
* filter FLT_OTEL_OPT_NAME FLT_OTEL_OPT_FILTER_ID <FLT_OTEL_OPT_FILTER_ID_DEFAULT> FLT_OTEL_OPT_CONFIG <file>
|
|
*/
|
|
#define FLT_OTEL_OPT_NAME "opentelemetry"
|
|
#define FLT_OTEL_OPT_FILTER_ID "id"
|
|
#define FLT_OTEL_OPT_FILTER_ID_DEFAULT "otel-filter"
|
|
#define FLT_OTEL_OPT_CONFIG "config"
|
|
|
|
#define FLT_OTEL_PARSE_SECTION_INSTR_ID "otel-instrumentation"
|
|
#define FLT_OTEL_PARSE_SECTION_GROUP_ID "otel-group"
|
|
#define FLT_OTEL_PARSE_SECTION_SCOPE_ID "otel-scope"
|
|
|
|
#define FLT_OTEL_PARSE_SPAN_ROOT "root"
|
|
#define FLT_OTEL_PARSE_SPAN_PARENT "parent"
|
|
#define FLT_OTEL_PARSE_SPAN_LINK "link"
|
|
#define FLT_OTEL_PARSE_INSTRUMENT_DESC "desc"
|
|
#define FLT_OTEL_PARSE_INSTRUMENT_VALUE "value"
|
|
#define FLT_OTEL_PARSE_INSTRUMENT_ATTR "attr"
|
|
#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"
|
|
#define FLT_OTEL_PARSE_CTX_USE_VARS "use-vars"
|
|
#define FLT_OTEL_PARSE_OPTION_HARDERR "hard-errors"
|
|
#define FLT_OTEL_PARSE_OPTION_DISABLED "disabled"
|
|
#define FLT_OTEL_PARSE_OPTION_NOLOGNORM "dontlog-normal"
|
|
|
|
/*
|
|
* A description of the macro arguments can be found in the structure
|
|
* flt_otel_parse_data definition
|
|
*/
|
|
#define FLT_OTEL_PARSE_INSTR_DEFINES \
|
|
FLT_OTEL_PARSE_INSTR_DEF( ID, 0, CHAR, 2, 2, "otel-instrumentation", " <name>") \
|
|
FLT_OTEL_PARSE_INSTR_DEF( ACL, 0, CHAR, 3, 0, "acl", " <name> <criterion> [flags] [operator] <value> ...") \
|
|
FLT_OTEL_PARSE_INSTR_DEF( LOG, 0, CHAR, 2, 0, "log", " { global | <addr> [len <len>] [format <fmt>] <facility> [<level> [<minlevel>]] }") \
|
|
FLT_OTEL_PARSE_INSTR_DEF( CONFIG, 0, NONE, 2, 2, "config", " <file>") \
|
|
FLT_OTEL_PARSE_INSTR_DEF( GROUPS, 0, NONE, 2, 0, "groups", " <name> ...") \
|
|
FLT_OTEL_PARSE_INSTR_DEF( SCOPES, 0, NONE, 2, 0, "scopes", " <name> ...") \
|
|
FLT_OTEL_PARSE_INSTR_DEF( RATE_LIMIT, 0, NONE, 2, 2, "rate-limit", " <value>") \
|
|
FLT_OTEL_PARSE_INSTR_DEF( OPTION, 0, NONE, 2, 2, "option", " { disabled | dontlog-normal | hard-errors }") \
|
|
FLT_OTEL_PARSE_INSTR_DEF(DEBUG_LEVEL, 0, NONE, 2, 2, "debug-level", " <value>")
|
|
|
|
#define FLT_OTEL_PARSE_GROUP_DEFINES \
|
|
FLT_OTEL_PARSE_GROUP_DEF( ID, 0, CHAR, 2, 2, "otel-group", " <name>") \
|
|
FLT_OTEL_PARSE_GROUP_DEF(SCOPES, 0, NONE, 2, 0, "scopes", " <name> ...")
|
|
|
|
#ifdef USE_OTEL_VARS
|
|
# define FLT_OTEL_PARSE_SCOPE_INJECT_HELP " <name-prefix> [use-vars] [use-headers]"
|
|
# define FLT_OTEL_PARSE_SCOPE_EXTRACT_HELP " <name-prefix> [use-vars | use-headers]"
|
|
#else
|
|
# define FLT_OTEL_PARSE_SCOPE_INJECT_HELP " <name-prefix> [use-headers]"
|
|
# define FLT_OTEL_PARSE_SCOPE_EXTRACT_HELP " <name-prefix> [use-headers]"
|
|
#endif
|
|
|
|
/*
|
|
* The first argument of the FLT_OTEL_PARSE_SCOPE_STATUS_DEF() macro is defined
|
|
* as otelc_span_status_t in <opentelemetry-c-wrapper/span.h> .
|
|
*/
|
|
#define FLT_OTEL_PARSE_SCOPE_STATUS_DEFINES \
|
|
FLT_OTEL_PARSE_SCOPE_STATUS_DEF(IGNORE, "ignore") \
|
|
FLT_OTEL_PARSE_SCOPE_STATUS_DEF( UNSET, "unset" ) \
|
|
FLT_OTEL_PARSE_SCOPE_STATUS_DEF( OK, "ok" ) \
|
|
FLT_OTEL_PARSE_SCOPE_STATUS_DEF( ERROR, "error" )
|
|
|
|
/* Sentinel: instrument has not been created yet. */
|
|
#define OTELC_METRIC_INSTRUMENT_UNSET -1
|
|
|
|
/* Sentinel: instrument creation is in progress by another thread. */
|
|
#define OTELC_METRIC_INSTRUMENT_PENDING -2
|
|
|
|
/* Sentinel: update-form instrument (re-evaluates an existing one). */
|
|
#define OTELC_METRIC_INSTRUMENT_UPDATE 0xff
|
|
|
|
#define OTELC_METRIC_AGGREGATION_UNSET -1
|
|
|
|
/*
|
|
* Observable (asynchronous) instruments are not supported. The OTel SDK
|
|
* invokes their callbacks from an external background thread that is not a
|
|
* HAProxy thread. HAProxy sample fetches rely on internal per-thread-group
|
|
* state and return incorrect results when called from a non-HAProxy thread.
|
|
*
|
|
* Double-precision instruments are not supported because HAProxy sample fetches
|
|
* do not return double values.
|
|
*/
|
|
#define FLT_OTEL_PARSE_SCOPE_INSTRUMENT_DEFINES \
|
|
FLT_OTEL_PARSE_SCOPE_INSTRUMENT_DEF(UPDATE, "update" ) \
|
|
FLT_OTEL_PARSE_SCOPE_INSTRUMENT_DEF(COUNTER_UINT64, "cnt_int" ) \
|
|
FLT_OTEL_PARSE_SCOPE_INSTRUMENT_DEF(HISTOGRAM_UINT64, "hist_int" ) \
|
|
FLT_OTEL_PARSE_SCOPE_INSTRUMENT_DEF(UDCOUNTER_INT64, "udcnt_int") \
|
|
FLT_OTEL_PARSE_SCOPE_INSTRUMENT_DEF(GAUGE_INT64, "gauge_int")
|
|
|
|
/*
|
|
* In case the possibility of working with OpenTelemetry context via HAProxy
|
|
* variables is not used, args_max member of the structure flt_otel_parse_data
|
|
* should be reduced for 'inject' keyword. However, this is not critical
|
|
* because in this case the 'use-vars' argument cannot be entered anyway,
|
|
* so I will not complicate it here with additional definitions.
|
|
*/
|
|
#define FLT_OTEL_PARSE_SCOPE_DEFINES \
|
|
FLT_OTEL_PARSE_SCOPE_DEF( ID, 0, CHAR, 2, 2, "otel-scope", " <name>") \
|
|
FLT_OTEL_PARSE_SCOPE_DEF( SPAN, 0, NONE, 2, 7, "span", " <name> [<reference>] [<link>] [root]") \
|
|
FLT_OTEL_PARSE_SCOPE_DEF( LINK, 1, NONE, 2, 0, "link", " <span> ...") \
|
|
FLT_OTEL_PARSE_SCOPE_DEF( ATTRIBUTE, 1, NONE, 3, 0, "attribute", " <key> <sample> ...") \
|
|
FLT_OTEL_PARSE_SCOPE_DEF( EVENT, 1, NONE, 4, 0, "event", " <name> <key> <sample> ...") \
|
|
FLT_OTEL_PARSE_SCOPE_DEF( BAGGAGE, 1, VAR, 3, 0, "baggage", " <key> <sample> ...") \
|
|
FLT_OTEL_PARSE_SCOPE_DEF( INJECT, 1, CTX, 2, 4, "inject", FLT_OTEL_PARSE_SCOPE_INJECT_HELP) \
|
|
FLT_OTEL_PARSE_SCOPE_DEF( EXTRACT, 0, CTX, 2, 3, "extract", FLT_OTEL_PARSE_SCOPE_EXTRACT_HELP) \
|
|
FLT_OTEL_PARSE_SCOPE_DEF( STATUS, 1, NONE, 2, 0, "status", " <code> [<sample> ...]") \
|
|
FLT_OTEL_PARSE_SCOPE_DEF( FINISH, 0, NONE, 2, 0, "finish", " <name> ...") \
|
|
FLT_OTEL_PARSE_SCOPE_DEF( INSTRUMENT, 0, NONE, 3, 0, "instrument", " { update <name> [<attr> ...] | <type> <name> [<aggr>] [<desc>] [<unit>] <value> [<bounds>] }") \
|
|
FLT_OTEL_PARSE_SCOPE_DEF( LOG_RECORD, 0, NONE, 3, 0, "log-record", " <severity> [<id>] [<event>] [<span>] [<attr>] <sample> ...") \
|
|
FLT_OTEL_PARSE_SCOPE_DEF(IDLE_TIMEOUT, 0, NONE, 2, 2, "idle-timeout", " <time>") \
|
|
FLT_OTEL_PARSE_SCOPE_DEF( ACL, 0, CHAR, 3, 0, "acl", " <name> <criterion> [flags] [operator] <value> ...") \
|
|
FLT_OTEL_PARSE_SCOPE_DEF( ON_EVENT, 0, NONE, 2, 0, "otel-event", " <name> [{ if | unless } <condition>]")
|
|
|
|
/* Invalid character check modes for identifier validation. */
|
|
enum FLT_OTEL_PARSE_INVCHAR_enum {
|
|
FLT_OTEL_PARSE_INVALID_NONE,
|
|
FLT_OTEL_PARSE_INVALID_CHAR,
|
|
FLT_OTEL_PARSE_INVALID_DOM,
|
|
FLT_OTEL_PARSE_INVALID_CTX,
|
|
FLT_OTEL_PARSE_INVALID_VAR,
|
|
};
|
|
|
|
enum FLT_OTEL_PARSE_INSTR_enum {
|
|
#define FLT_OTEL_PARSE_INSTR_DEF(a,b,c,d,e,f,g) FLT_OTEL_PARSE_INSTR_##a,
|
|
FLT_OTEL_PARSE_INSTR_DEFINES
|
|
#undef FLT_OTEL_PARSE_INSTR_DEF
|
|
};
|
|
|
|
enum FLT_OTEL_PARSE_GROUP_enum {
|
|
#define FLT_OTEL_PARSE_GROUP_DEF(a,b,c,d,e,f,g) FLT_OTEL_PARSE_GROUP_##a,
|
|
FLT_OTEL_PARSE_GROUP_DEFINES
|
|
#undef FLT_OTEL_PARSE_GROUP_DEF
|
|
};
|
|
|
|
enum FLT_OTEL_PARSE_SCOPE_enum {
|
|
#define FLT_OTEL_PARSE_SCOPE_DEF(a,b,c,d,e,f,g) FLT_OTEL_PARSE_SCOPE_##a,
|
|
FLT_OTEL_PARSE_SCOPE_DEFINES
|
|
#undef FLT_OTEL_PARSE_SCOPE_DEF
|
|
};
|
|
|
|
/* Context storage type flags for inject/extract operations. */
|
|
enum FLT_OTEL_CTX_USE_enum {
|
|
FLT_OTEL_CTX_USE_VARS = 1 << 0,
|
|
FLT_OTEL_CTX_USE_HEADERS = 1 << 1,
|
|
};
|
|
|
|
/* Logging state flags for the OTel filter. */
|
|
enum FLT_OTEL_LOGGING_enum {
|
|
FLT_OTEL_LOGGING_OFF = 0,
|
|
FLT_OTEL_LOGGING_ON = 1 << 0,
|
|
FLT_OTEL_LOGGING_NOLOGNORM = 1 << 1,
|
|
};
|
|
|
|
/* Keyword metadata used by the configuration section parsers. */
|
|
struct flt_otel_parse_data {
|
|
int keyword; /* Keyword index. */
|
|
bool flag_check_id; /* Whether the group ID must be defined for the keyword. */
|
|
int check_name; /* Checking allowed characters in the name. */
|
|
int args_min; /* The minimum number of arguments required. */
|
|
int args_max; /* The maximum number of arguments allowed. */
|
|
const char *name; /* Keyword name. */
|
|
const char *usage; /* Usage text to be printed in case of an error. */
|
|
};
|
|
|
|
#define FLT_OTEL_PARSE_KEYWORD(n,s) (strcmp(args[n], (s)) == 0)
|
|
|
|
#define FLT_OTEL_PARSE_WARNING(f, ...) \
|
|
ha_warning("parsing [%s:%d] : " FLT_OTEL_FMT_TYPE FLT_OTEL_FMT_NAME "'" f "'\n", ##__VA_ARGS__);
|
|
|
|
#define FLT_OTEL_PARSE_ALERT(f, ...) \
|
|
do { \
|
|
ha_alert("parsing [%s:%d] : " FLT_OTEL_FMT_TYPE FLT_OTEL_FMT_NAME "'" f "'\n", ##__VA_ARGS__); \
|
|
\
|
|
retval |= ERR_ABORT | ERR_ALERT; \
|
|
} while (0)
|
|
|
|
#define FLT_OTEL_POST_PARSE_ALERT(f, ...) \
|
|
FLT_OTEL_PARSE_ALERT(f, flt_otel_current_config->cfg_file, ##__VA_ARGS__)
|
|
|
|
#define FLT_OTEL_PARSE_ERR(e,f, ...) \
|
|
do { \
|
|
if (*(e) == NULL) \
|
|
(void)memprintf((e), f, ##__VA_ARGS__); \
|
|
\
|
|
retval |= ERR_ABORT | ERR_ALERT; \
|
|
} while (0)
|
|
|
|
#define FLT_OTEL_PARSE_IFERR_ALERT() \
|
|
do { \
|
|
if (err == NULL) \
|
|
break; \
|
|
\
|
|
FLT_OTEL_PARSE_ALERT("%s", file, line, err); \
|
|
FLT_OTEL_ERR_FREE(err); \
|
|
} while (0)
|
|
|
|
#endif /* _OTEL_PARSER_H_ */
|
|
|
|
/*
|
|
* Local variables:
|
|
* c-indent-level: 8
|
|
* c-basic-offset: 8
|
|
* End:
|
|
*
|
|
* vi: noexpandtab shiftwidth=8 tabstop=8
|
|
*/
|