mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-04-18 12:14:56 +02:00
MINOR: otel: changed instrument attr to use sample expressions
Replaced the static key-value attribute storage in update-form instruments with sample-evaluated attributes, matching the log-record attr change. The 'attr' keyword now accepts a key and a HAProxy sample expression evaluated at runtime. 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 the meter. Updated documentation, debug macro and test configurations.
This commit is contained in:
parent
651e9fd8a7
commit
7c66bb5497
@ -628,7 +628,8 @@ instrument { update <name> [<attr>] | <type> <name> [<aggr>] [<desc>] [<unit>] <
|
||||
|
||||
To update an existing instrument (previously created in another scope), use
|
||||
'update' followed by the name of the instrument. Optional attributes can be
|
||||
added using the 'attr' keyword followed by key-value pairs.
|
||||
added using the 'attr' keyword followed by a key and a sample expression
|
||||
evaluated at runtime.
|
||||
|
||||
Supported instrument types:
|
||||
- cnt_int : counter (uint64)
|
||||
@ -656,7 +657,7 @@ instrument { update <name> [<attr>] | <type> <name> [<aggr>] [<desc>] [<unit>] <
|
||||
instrument cnt_int "my_counter" desc "Counter" value int(1)
|
||||
instrument hist_int "my_hist" aggr exp_histogram desc "Latency" value lat_ns_tot unit "ns"
|
||||
instrument hist_int "my_hist2" desc "Latency" value lat_ns_tot unit "ns" bounds "100 1000 10000 100000"
|
||||
instrument update "my_counter" attr "key1" "val1"
|
||||
instrument update "my_counter" attr "key1" str("val1")
|
||||
|
||||
Arguments :
|
||||
type - the instrument type (see list above)
|
||||
@ -666,7 +667,7 @@ instrument { update <name> [<attr>] | <type> <name> [<aggr>] [<desc>] [<unit>] <
|
||||
unit - optional unit string for the instrument
|
||||
value - sample expression providing the measurement value
|
||||
bounds - optional histogram bucket boundaries (hist_int only)
|
||||
attr - attribute key-value pairs (update form only)
|
||||
attr - attribute key and sample expression (update form only)
|
||||
|
||||
|
||||
log-record <severity> [id <integer>] [event <name>] [span <span-name>] [attr <key> <sample>] ... <sample> ...
|
||||
|
||||
@ -204,13 +204,13 @@ strings without list linkage.
|
||||
samples Sample expressions for the value.
|
||||
bounds Histogram bucket boundaries (create only).
|
||||
bounds_num Number of histogram bucket boundaries.
|
||||
attr Instrument attributes (update only).
|
||||
attr_len Number of instrument attributes.
|
||||
attributes Instrument attributes (update only, flt_otel_conf_sample).
|
||||
ref Resolved create-form instrument (update only).
|
||||
|
||||
Instruments come in two forms: create-form (defines a new metric with type,
|
||||
description, unit, and optional histogram bounds) and update-form (references
|
||||
an existing instrument via the ref pointer).
|
||||
an existing instrument via the ref pointer). Update-form attributes are stored
|
||||
as flt_otel_conf_sample entries and evaluated at runtime.
|
||||
|
||||
4.7 flt_otel_conf_log_record
|
||||
|
||||
|
||||
@ -320,7 +320,7 @@ Supported keywords:
|
||||
|
||||
|
||||
instrument <type> <name> [aggr <aggregation>] [desc <description>] [unit <unit>] value <sample> [bounds <bounds>]
|
||||
instrument update <name> [attr <key> <value> ...]
|
||||
instrument update <name> [attr <key> <sample> ...]
|
||||
Create or update a metric instrument.
|
||||
|
||||
Supported types:
|
||||
@ -358,7 +358,7 @@ Supported keywords:
|
||||
instrument cnt_int "name_cnt_int" desc "Integer Counter" value int(1),add(2) unit "unit"
|
||||
instrument hist_int "name_hist" aggr exp_histogram desc "Latency" value lat_ns_tot unit "ns"
|
||||
instrument hist_int "name_hist2" desc "Latency" value lat_ns_tot unit "ns" bounds "100 1000 10000"
|
||||
instrument update "name_cnt_int" attr "attr_1_key" "attr_1_value"
|
||||
instrument update "name_cnt_int" attr "attr_1_key" str("attr_1_value")
|
||||
|
||||
|
||||
log-record <severity> [id <integer>] [event <name>] [span <span-name>] [attr <key> <sample>] ... <sample> ...
|
||||
|
||||
@ -139,10 +139,11 @@ src/event.c
|
||||
Event dispatching, metrics recording and scope/span execution engine.
|
||||
|
||||
flt_otel_scope_run_instrument_record
|
||||
Records a measurement for a synchronous metric instrument. Evaluates the
|
||||
sample expression from the create-form instrument (instr_ref) and submits
|
||||
the value to the meter via update_instrument_kv_n(), using per-scope
|
||||
attributes from the update-form instrument (instr).
|
||||
Records a measurement for a synchronous metric instrument. Evaluates
|
||||
update-form attributes via flt_otel_sample_eval() and
|
||||
flt_otel_sample_add_kv(), evaluates the sample expression from the
|
||||
create-form instrument (instr_ref), and submits the value to the meter
|
||||
via update_instrument_kv_n().
|
||||
|
||||
flt_otel_scope_run_instrument
|
||||
Processes all metric instruments for a scope. Runs in two passes: the
|
||||
|
||||
@ -1052,8 +1052,7 @@ The flt_otel_conf_instrument structure (conf.h) holds:
|
||||
samples List of sample expressions for the instrument value.
|
||||
bounds Histogram bucket boundaries array (create-form only).
|
||||
bounds_num Number of histogram bucket boundaries.
|
||||
attr Key-value attribute array (update-form only).
|
||||
attr_len Number of attributes.
|
||||
attributes List of flt_otel_conf_sample entries (update-form only).
|
||||
ref Pointer to the create-form instrument (update-form only).
|
||||
|
||||
18.5.3 Meter Initialization and Startup
|
||||
|
||||
@ -85,10 +85,10 @@
|
||||
flt_otel_list_dump(&((p)->ph_scopes)))
|
||||
|
||||
#define FLT_OTEL_DBG_CONF_INSTRUMENT(h,p) \
|
||||
OTELC_DBG_STRUCT(DEBUG, h, h FLT_OTEL_CONF_HDR_FMT "%" PRId64 " %d %d '%s' '%s' %s %p %zu %p %zu %p }", (p), \
|
||||
OTELC_DBG_STRUCT(DEBUG, h, h FLT_OTEL_CONF_HDR_FMT "%" PRId64 " %d %d '%s' '%s' %s %s %p %zu %p }", (p), \
|
||||
FLT_OTEL_CONF_HDR_ARGS(p, id), (p)->idx, (p)->type, (p)->aggr_type, OTELC_STR_ARG((p)->description), \
|
||||
OTELC_STR_ARG((p)->unit), flt_otel_list_dump(&((p)->samples)), (p)->attr, (p)->attr_len, (p)->ref, \
|
||||
(p)->bounds_num, (p)->bounds)
|
||||
OTELC_STR_ARG((p)->unit), flt_otel_list_dump(&((p)->samples)), flt_otel_list_dump(&((p)->attributes)), \
|
||||
(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' %s %s }", (p), \
|
||||
@ -197,8 +197,7 @@ struct flt_otel_conf_instrument {
|
||||
struct list samples; /* Sample expressions for the value. */
|
||||
double *bounds; /* Histogram bucket boundaries (create only). */
|
||||
size_t bounds_num; /* Number of histogram bucket boundaries. */
|
||||
struct otelc_kv *attr; /* Instrument attributes (update only). */
|
||||
size_t attr_len; /* Number of instrument attributes. */
|
||||
struct list attributes; /* Instrument attributes (update only, flt_otel_conf_sample). */
|
||||
struct flt_otel_conf_instrument *ref; /* Resolved create-form instrument (update only). */
|
||||
};
|
||||
|
||||
|
||||
@ -502,8 +502,9 @@ FLT_OTEL_CONF_FUNC_FREE(span, id,
|
||||
* DESCRIPTION
|
||||
* Allocates and initializes a conf_instrument structure. Sets the instrument
|
||||
* type and meter index to OTELC_METRIC_INSTRUMENT_UNSET and initializes the
|
||||
* samples list. The <id> string is duplicated and stored as the instrument
|
||||
* name. If <head> is non-NULL, the structure is appended to the list.
|
||||
* samples and attributes lists. The <id> string is duplicated and stored as
|
||||
* the instrument name. If <head> is non-NULL, the structure is appended to
|
||||
* the list.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* Returns a pointer to the initialized structure, or NULL on failure.
|
||||
@ -513,6 +514,7 @@ FLT_OTEL_CONF_FUNC_INIT(instrument, id,
|
||||
retptr->type = OTELC_METRIC_INSTRUMENT_UNSET;
|
||||
retptr->aggr_type = OTELC_METRIC_AGGREGATION_UNSET;
|
||||
LIST_INIT(&(retptr->samples));
|
||||
LIST_INIT(&(retptr->attributes));
|
||||
)
|
||||
|
||||
|
||||
@ -540,7 +542,7 @@ FLT_OTEL_CONF_FUNC_FREE(instrument, id,
|
||||
OTELC_SFREE((*ptr)->unit);
|
||||
FLT_OTEL_LIST_DESTROY(sample, &((*ptr)->samples));
|
||||
OTELC_SFREE((*ptr)->bounds);
|
||||
otelc_kv_destroy(&((*ptr)->attr), (*ptr)->attr_len);
|
||||
FLT_OTEL_LIST_DESTROY(sample, &((*ptr)->attributes));
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -40,10 +40,33 @@ static int flt_otel_scope_run_instrument_record(struct stream *s, uint dir, stru
|
||||
struct flt_otel_conf_sample_expr *expr;
|
||||
struct sample smp;
|
||||
struct otelc_value value;
|
||||
struct flt_otel_scope_data_kv instr_attr;
|
||||
int retval = FLT_OTEL_RET_OK;
|
||||
|
||||
OTELC_FUNC("%p, %u, %p, %p, %p, %p:%p", s, dir, meter, instr_ref, instr, OTELC_DPTR_ARGS(err));
|
||||
|
||||
/* Evaluate instrument attributes from sample expressions. */
|
||||
(void)memset(&instr_attr, 0, sizeof(instr_attr));
|
||||
|
||||
list_for_each_entry(sample, &(instr->attributes), list) {
|
||||
struct otelc_value attr_value;
|
||||
|
||||
OTELC_DBG(DEBUG, "adding instrument attribute '%s' -> '%s'", sample->key, sample->fmt_string);
|
||||
|
||||
if (flt_otel_sample_eval(s, dir, sample, true, &attr_value, err) == FLT_OTEL_RET_ERROR) {
|
||||
retval = FLT_OTEL_RET_ERROR;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (flt_otel_sample_add_kv(&instr_attr, sample->key, &attr_value) == FLT_OTEL_RET_ERROR) {
|
||||
if (attr_value.u_type == OTELC_VALUE_DATA)
|
||||
OTELC_SFREE(attr_value.u.value_data);
|
||||
|
||||
retval = FLT_OTEL_RET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* The samples list always contains exactly one entry. */
|
||||
sample = LIST_NEXT(&(instr_ref->samples), struct flt_otel_conf_sample *, list);
|
||||
|
||||
@ -58,6 +81,8 @@ static int flt_otel_scope_run_instrument_record(struct stream *s, uint dir, stru
|
||||
if (smp.data.u.str.area == NULL) {
|
||||
FLT_OTEL_ERR("out of memory");
|
||||
|
||||
otelc_kv_destroy(&(instr_attr.attr), instr_attr.cnt);
|
||||
|
||||
OTELC_RETURN_INT(FLT_OTEL_RET_ERROR);
|
||||
}
|
||||
|
||||
@ -104,10 +129,12 @@ static int flt_otel_scope_run_instrument_record(struct stream *s, uint dir, stru
|
||||
}
|
||||
|
||||
if (retval != FLT_OTEL_RET_ERROR)
|
||||
if (OTELC_OPS(meter, update_instrument_kv_n, HA_ATOMIC_LOAD(&(instr_ref->idx)), &value, instr->attr, instr->attr_len) == OTELC_RET_ERROR)
|
||||
if (OTELC_OPS(meter, update_instrument_kv_n, HA_ATOMIC_LOAD(&(instr_ref->idx)), &value, instr_attr.attr, instr_attr.cnt) == OTELC_RET_ERROR)
|
||||
retval = FLT_OTEL_RET_ERROR;
|
||||
}
|
||||
|
||||
otelc_kv_destroy(&(instr_attr.attr), instr_attr.cnt);
|
||||
|
||||
if (sample->lf_used)
|
||||
OTELC_SFREE(smp.data.u.str.area);
|
||||
|
||||
|
||||
@ -1060,10 +1060,11 @@ static int flt_otel_parse_cfg_instrument(const char *file, int line, char **args
|
||||
if (flag_add_attr) {
|
||||
if (!FLT_OTEL_ARG_ISVALID(i) || !FLT_OTEL_ARG_ISVALID(i + 1))
|
||||
FLT_OTEL_PARSE_ERR(err, "'%s' : too few arguments (use '%s%s')", args[i], pdata->name, pdata->usage);
|
||||
else if (otelc_kv_add(&(instr->attr), &(instr->attr_len), args[i], args[i + 1], strlen(args[i + 1])) == OTELC_RET_ERROR)
|
||||
FLT_OTEL_PARSE_ERR(err, "'%s' : out of memory", args[0]);
|
||||
else
|
||||
i++;
|
||||
else {
|
||||
retval = flt_otel_parse_cfg_sample(file, line, args, i + 1, 1, NULL, &(instr->attributes), err);
|
||||
if (!(retval & ERR_CODE))
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else if (FLT_OTEL_PARSE_KEYWORD(i, FLT_OTEL_PARSE_INSTRUMENT_ATTR)) {
|
||||
flag_add_attr = true;
|
||||
@ -1073,7 +1074,7 @@ static int flt_otel_parse_cfg_instrument(const char *file, int line, char **args
|
||||
}
|
||||
}
|
||||
|
||||
if (flag_add_attr && (instr->attr_len == 0))
|
||||
if (flag_add_attr && LIST_ISEMPTY(&(instr->attributes)))
|
||||
FLT_OTEL_PARSE_ERR(err, "'%s' : too few arguments (use '%s%s')", args[i], pdata->name, pdata->usage);
|
||||
}
|
||||
else {
|
||||
|
||||
@ -125,7 +125,7 @@
|
||||
otel-scope frontend_http_request
|
||||
instrument cnt_int "haproxy.http.requests" desc "HTTP request count" value int(1) unit "{request}"
|
||||
instrument hist_int "haproxy.http.latency" desc "HTTP request latency" value lat_ns_tot unit "ns" aggr "histogram" bounds "1000 1000000 1000000000"
|
||||
instrument update "haproxy.http.latency" attr "phase" "request"
|
||||
instrument update "haproxy.http.latency" attr "phase" str("request")
|
||||
instrument update "haproxy.tcp.request.fe"
|
||||
span "Frontend HTTP request" parent "HTTP body request" link "HAProxy session"
|
||||
attribute "http.method" method
|
||||
@ -235,8 +235,8 @@
|
||||
otel-event on-process-store-rules-response
|
||||
|
||||
otel-scope http_response
|
||||
instrument update "haproxy.http.requests" attr "phase" "response"
|
||||
instrument update "haproxy.http.latency" attr "phase" "response"
|
||||
instrument update "haproxy.http.requests" attr "phase" str("response")
|
||||
instrument update "haproxy.http.latency" attr "phase" str("response")
|
||||
instrument update "haproxy.fe.connections"
|
||||
span "HTTP response" parent "Process store rules response"
|
||||
attribute "http.status_code" status
|
||||
|
||||
@ -103,7 +103,7 @@
|
||||
otel-scope frontend_http_request
|
||||
instrument cnt_int "haproxy.http.requests" desc "HTTP request count" value int(1) unit "{request}"
|
||||
instrument hist_int "haproxy.http.latency" desc "HTTP request latency" value lat_ns_tot unit "ns"
|
||||
instrument update "haproxy.http.latency" attr "phase" "request"
|
||||
instrument update "haproxy.http.latency" attr "phase" str("request")
|
||||
span "Frontend HTTP request" parent "HTTP body request" link "HAProxy session"
|
||||
attribute "http.method" method
|
||||
attribute "http.url" url
|
||||
@ -177,8 +177,8 @@
|
||||
otel-event on-process-store-rules-response
|
||||
|
||||
otel-scope http_response
|
||||
instrument update "haproxy.http.requests" attr "phase" "response"
|
||||
instrument update "haproxy.http.latency" attr "phase" "response"
|
||||
instrument update "haproxy.http.requests" attr "phase" str("response")
|
||||
instrument update "haproxy.http.latency" attr "phase" str("response")
|
||||
instrument update "haproxy.fe.connections"
|
||||
span "HTTP response" parent "Process store rules response"
|
||||
attribute "http.status_code" status
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user