OpenTelemetry filter -- function reference
==========================================================================

Functions are grouped by source file.  Functions marked with [D] are only
compiled when DEBUG_OTEL is defined.


src/filter.c
----------------------------------------------------------------------

Filter lifecycle callbacks and helpers registered in flt_otel_ops.

  flt_otel_mem_malloc
      Allocator callback for the OTel C wrapper library.  Uses the HAProxy
      pool_head_otel_span_context pool.

  flt_otel_mem_free
      Deallocator callback for the OTel C wrapper library.

  flt_otel_log_handler_cb
      Diagnostic callback for the OTel C wrapper library.  Counts SDK internal
      diagnostic messages.

  flt_otel_thread_id
      Returns the current HAProxy thread ID (tid).  A debug build with threads
      hands a thread the SDK created an ID of its own from an atomic offset.

  flt_otel_lib_init
      Initializes the OTel C wrapper library: verifies the library version,
      constructs the configuration path, calls otelc_init(), checks how the
      context name resolved per signal, and creates the tracer, meter and logger
      instances for the usable signals.

  flt_otel_is_disabled
      Checks whether the filter instance is disabled for the current stream.
      Logs the event name when DEBUG_OTEL is enabled.

  flt_otel_return_int
      Error handler for callbacks returning int.  Hard-error mode disables the
      filter, soft-error mode continues; the error is logged rate-limited and
      freed, and both modes return OK.

  flt_otel_return_void
      Error handler for callbacks returning void.  Same logic as
      flt_otel_return_int but without a return value.

  flt_otel_ops_init
      Filter init callback (flt_ops.init).  Called once per proxy to initialize
      the OTel library via flt_otel_lib_init() and register CLI keywords, and
      declares HTX filtering (FLT_CFG_FL_HTX) for an HTTP-mode proxy.

  flt_otel_ops_deinit
      Filter deinit callback (flt_ops.deinit).  Saves the context, tracer, meter
      and logger handles and force-flushes them within one shared budget (with
      'option noflush' it sets a zero flush budget instead, dropping the
      buffered telemetry), frees the configuration and the memory pools, then
      destroys the saved handles via otelc_deinit().

  flt_otel_ops_check
      Filter check callback (flt_ops.check).  Validates the parsed
      configuration: checks for duplicate filter IDs, resolves group/scope
      placeholder references, rejects a group no 'groups' line names, checks the
      root span rules, warns about the events the proxy's mode or the filter's
      placement keeps from firing, and sets analyzer bits.

  flt_otel_check_inject_foreign
      Checks a resolved inject context name against the other OTel filters of
      the proxy, which run on the same streams; a repeated name, one differing
      only in case included, or a second nameless-header context is rejected
      from both sides, the way a duplicated filter ID is.

  flt_otel_check_cond_loc
      Warns when a scope's 'if'/'unless' condition can never match at the
      processing point where the scope runs; a NULL condition is ignored.

  flt_otel_check_sample_list
      Warns when a sample used by a scope cannot be evaluated at the processing
      point where the scope runs; log-format expressions and fetches that
      declare no location are left unchecked.

  flt_otel_check_scope_loc
      Walks every sample-bearing directive and condition of a scope and warns
      about any fetch or condition that cannot be evaluated at the given
      processing point.  Shared by the event-bound and group action checks.

  flt_otel_str_differs
      Compares two optional strings, where NULL stands for an argument that the
      configuration line did not carry; two absent ones are equal.

  flt_otel_instrument_def_differs
      Compares the definition two create lines of one instrument name carry and
      names the first argument that differs.  The type is left to the caller,
      and the value and the condition are what the repeated lines vary.

  flt_otel_conf_ref_defined
      Looks a referenced name up among the spans of every otel-scope and, when
      an extracted context may stand there, among the contexts their 'extract'
      lines define.  A name no scope defines can never resolve at run time.

  flt_otel_conf_scope_in_group
      Tells whether one of the otel-groups that the instrumentation names holds
      the given scope, which is the way an 'otel-group' action reaches it.

  flt_otel_conf_scope_runs
      Tells whether a scope can ever run: the instrumentation has to name it,
      and it must then bind an event or be held by a group an action reaches.

  flt_otel_ops_init_per_thread
      Per-thread init callback (flt_ops.init_per_thread).  Starts the OTel
      tracer, meter and logger on the first call only, guarded by an atomic
      claim on the instrumentation's flag_started.

  flt_otel_ops_deinit_per_thread [D]
      Per-thread deinit callback (flt_ops.deinit_per_thread).

  flt_otel_idle_expire_set
      Floors the stream task expiry to the idle tick so the task wakes at the
      idle interval.  The idle timer is kept out of the channel's analyse_exp,
      which the analysers own and freely overwrite.  An already expired task
      expiry is replaced rather than merged.

  flt_otel_ops_attach
      Filter attach callback (flt_ops.attach).  Called when a filter instance is
      attached to a stream.  Applies rate limiting, creates the runtime context,
      sets analyzer bits and arms the idle timer from the precomputed minimum
      idle_timeout, scheduling the first wake-up on the stream task; a filter
      attached at backend selection gets its timer here as well.

  flt_otel_ops_stream_start
      Stream start callback (flt_ops.stream_start).  Fires the
      on-stream-start event before any channel processing begins.  The channel
      argument is NULL.  HAProxy runs it for the frontend filters alone.

  flt_otel_ops_stream_set_backend
      Stream set-backend callback (flt_ops.stream_set_backend).  Fires the
      on-backend-set event when a backend is assigned to the stream.

  flt_otel_ops_stream_stop
      Stream stop callback (flt_ops.stream_stop).  Fires the
      on-stream-stop event after all channel processing ends.  The channel
      argument is NULL.

  flt_otel_ops_detach
      Filter detach callback (flt_ops.detach).  Frees the runtime context when
      the filter is detached from a stream.

  flt_otel_ops_check_timeouts
      Timeout callback (flt_ops.check_timeouts).  When the idle-timeout timer
      has expired, fires the on-idle-timeout event and reschedules the timer,
      disarming it instead when the filter is or becomes disabled.  Sets the
      STRM_EVT_MSG pending event flag on the stream and re-asserts the idle
      wake-up on the stream task expiry on every invocation.

  flt_otel_ops_channel_start_analyze
      Channel start-analyze callback.  Records on the response channel that its
      analysis started, registers analyzers on the channel (an HTX stream only,
      and for a filter attached at backend selection only the ones past the
      backend start) and runs the client/server session start event.

  flt_otel_get_event
      Looks up an event index in the flt_otel_event_data table by its analyzer
      bit.

  flt_otel_ops_channel_pre_analyze
      Channel pre-analyze callback.  Maps the analyzer bit to an event index and
      runs the corresponding event.

  flt_otel_ops_channel_post_analyze
      Channel post-analyze callback.  Non-resumable; called once when a
      filterable analyzer finishes.

  flt_otel_ops_channel_end_analyze
      Channel end-analyze callback.  Runs the client/server session end event,
      and on the channel whose analysis ends last also the server-unavailable
      event, when the response channel never started its analysis.

  flt_otel_ops_http_headers
      HTTP headers callback (flt_ops.http_headers).  Fires
      on-http-headers-request or on-http-headers-response depending on the
      channel direction.

  flt_otel_ops_http_payload [D]
      HTTP payload callback (flt_ops.http_payload).

  flt_otel_ops_http_end
      HTTP end callback (flt_ops.http_end).  Fires on-http-end-request or
      on-http-end-response depending on the channel direction.

  flt_otel_ops_http_reset [D]
      HTTP reset callback (flt_ops.http_reset).

  flt_otel_ops_http_reply
      HTTP reply callback (flt_ops.http_reply).  Fires the on-http-reply event
      when HAProxy generates an internal reply.  HAProxy has not invoked this
      callback since 2.2-dev8 (2020), so the event never fires in practice.

  flt_otel_ops_tcp_payload
      TCP payload callback (flt_ops.tcp_payload).  Counts the bytes forwarded
      on a TCP-mode stream for the otel.bytes_in and otel.bytes_out fetches.


src/event.c
----------------------------------------------------------------------

Event dispatching, metrics recording and scope/span execution engine.

  flt_otel_session_disable
      Sets the disabled flag of the stream's runtime context, so that the stream
      produces no further telemetry; the debug build logs the reason and counts
      the disabling.

  flt_otel_cond_pass
      Evaluates an optional if/unless ACL condition against the stream,
      honouring the 'unless' polarity; a NULL condition always passes.

  flt_otel_cond_taken
      Implements the first-match rule for a sample key that is written on more
      than one line: it scans the lines preceding the given one and reports
      whether an earlier line of the same key has already taken it, in which
      case the given line is skipped by the caller.  Event lines are compared
      within one event name only, that name being carried in the extra data.

  flt_otel_unset_var_taken
      Implements the first-match rule for a variable name that is written on
      more than one unset-var line: it scans the lines preceding the given one
      and reports whether an earlier line whose condition holds already names
      the variable, in which case the name is skipped by the caller.

  flt_otel_scope_run_instrument_record
      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_instrument_create
      Creates a create-form metric instrument on its first use.  The index is
      held by the create line that owns the name, so all the create lines of one
      name share one instrument; exactly one otel-scope creates it, and a create
      line of another otel-scope that finds it already created is refused.  The
      instrument index is claimed with HA_ATOMIC_CAS so that a single thread
      performs the creation: the winning thread registers the bucket-bounds
      view, when the instrument defines one, and then the instrument itself,
      storing the index that it gets back; a losing thread returns at once and
      its caller waits out the PENDING index.  A failure stores UNSET so that a
      transient failure can be retried, but only up to FLT_OTEL_INSTR_FAIL_MAX
      attempts, after which the index becomes FAILED and the instrument is given
      up.  A view or an instrument that cannot be created is reported through
      the rate-limited runtime log.

  flt_otel_scope_run_instrument
      Processes all metric instruments for a scope.  Runs in two passes: the
      first lazily creates the create-form instruments whose condition passes,
      via the meter, using HA_ATOMIC_CAS to guarantee thread-safe one-time
      initialization; the second iterates update-form instruments and records
      measurements via flt_otel_scope_run_instrument_record().  An update takes
      the create chain of its own scope when a create line stands there,
      otherwise the one of the scope the instrument is in.  An instrument
      another thread is creating right now (PENDING index) is waited for until
      that creation completes rather than skipped, so a concurrent first use
      does not lose its measurement; one not created at all (UNSET index) or
      given up after too many failed creation attempts (FAILED index) is
      skipped.  A measurement is recorded only when the update-form if/unless
      condition passes, taking the value from the first line of the chain whose
      condition holds; instrument creation produces no data point of its own.

  flt_otel_scope_run_log_record
      Emits log records for a scope.  Iterates over the configured log-record
      list, skipping entries whose severity is below the logger threshold.
      Evaluates the body from sample fetch expressions or a log-format string,
      optionally resolves a span reference against the runtime context, and
      emits the record via the logger.  The event timestamp comes from the
      'time' expression (scaled by the configured unit) when the record sets one
      and it evaluates, and otherwise from the caller's wall-clock value; that
      wall-clock value is always passed as the observed timestamp.  A missing
      span is non-fatal -- the record is emitted without span correlation.
      A record whose 'if'/'unless' condition does not pass is skipped.

  flt_otel_scope_run_set_var
      Processes a scope's set-var directives: evaluates each sample expression
      in string form and stores the result into the named HAProxy variable via
      flt_otel_var_set_byname().

  flt_otel_scope_run_set_var_ctx
      Processes a scope's set-var-ctx directives: resolves the referenced span
      or extracted context, renders the requested field via
      flt_otel_ctx_field_to_str(), and stores it into the named HAProxy
      variable.  An unresolved reference is skipped.

  flt_otel_scope_span_start
      Creates the OTel span through the tracer, with the parent span or context
      that flt_otel_scope_span_init() resolved and the span kind of the span
      configuration.  A span an earlier scope created is left alone, and one
      the sampler leaves out is marked so that its samples are not evaluated.

  flt_otel_scope_span_samples
      Evaluates the attribute, event and status samples of a span whose own
      condition holds, and collects the results for the span applier.  A span
      has a single status, so the first status line whose condition holds is
      the one applied; the baggage samples are evaluated by the caller, which
      needs them whatever the sampling decision was.

  flt_otel_scope_run_span
      Executes a single span: creates the OTel span on first call, adds links,
      baggage, attributes, events and status, then injects the context into HTTP
      headers or HAProxy variables.

  flt_otel_scope_run
      Executes a complete scope: evaluates ACL conditions, extracts contexts,
      iterates over configured spans (resolving links, evaluating sample
      expressions), calls flt_otel_scope_run_span for each, processes metric
      instruments via flt_otel_scope_run_instrument(), emits log records via
      flt_otel_scope_run_log_record(), then marks and finishes completed spans.

  flt_otel_event_run
      Top-level event dispatcher.  Called from filter callbacks, iterates over
      all scopes matching the event index and calls flt_otel_scope_run() for
      each.


src/scope.c
----------------------------------------------------------------------

Runtime context, span and context lifecycle management.

  flt_otel_runtime_context_init
      Allocates and initializes the per-stream runtime context.  Generates a
      UUID and, in a build with OTEL_USE_VARS=1, stores it in the
      sess.otel.uuid HAProxy variable.

  flt_otel_runtime_context_free
      Frees the runtime context: ends all active spans, destroys all extracted
      contexts, and releases pool memory.

  flt_otel_scope_span_init
      Finds an existing scope span by name or creates a new one.  Resolves the
      parent reference (span or extracted context).  A defining line that finds
      the span created by another line is refused, so exactly one line creates
      it; a bare line only re-activates the span it names.

  flt_otel_scope_span_free
      Frees a scope span entry if its OTel span has been ended.  Refuses to free
      an active (non-NULL) span.

  flt_otel_scope_context_init
      Finds an existing scope context by name or creates a new one by extracting
      the span context from a text map.

  flt_otel_scope_context_free
      Frees a scope context entry and destroys the underlying OTel span context.

  flt_otel_scope_data_dump [D]
      Dumps scope data contents (baggage, attributes, events, links, status) for
      debugging.

  flt_otel_scope_data_init
      Zero-initializes a scope data structure and its event/link lists.

  flt_otel_scope_data_free
      Frees all scope data contents: key-value arrays, event entries, link
      entries, and status description.

  flt_otel_scope_finish_mark
      Marks spans and contexts for finishing.  Supports wildcard ("*"),
      channel-specific ("*req*"/"*res*"), and named targets.

  flt_otel_scope_finish_marked
      Ends all spans and destroys all contexts that have been marked for
      finishing by flt_otel_scope_finish_mark().  An entry whose span creation
      failed carries no OTel span and is skipped.

  flt_otel_scope_free_unused
      Removes scope spans with NULL OTel span and scope contexts with NULL OTel
      context.  Cleans up associated HTTP headers and variables.


src/parser.c
----------------------------------------------------------------------

Configuration file parsing for otel-instrumentation, otel-group and otel-scope
sections.

  flt_otel_parse_strdup
      Duplicates a string with error handling; when requested, stores the
      duplicated length on success or 0 on failure.

  flt_otel_parse_keyword
      Parses a single keyword argument: checks for duplicates and missing
      values, then stores via flt_otel_parse_strdup().

  flt_otel_parse_invalid_char
      Validates characters in a name according to the specified type
      (identifier, domain, context prefix, metric instrument name).

  flt_otel_parse_ctx_name_warn
      Warns when a variable-stored span context name has '-' or an uppercase
      letter, which the generated HAProxy variable normalizes.

  flt_otel_parse_cfg_check
      Common validation for config keywords: looks up the keyword, checks the
      argument count bounds and validates the name's characters.

  flt_otel_parse_cfg_sample_expr
      Parses a single HAProxy sample expression within a sample definition.
      Calls sample_parse_expr().

  flt_otel_parse_cfg_sample
      Parses a complete sample definition (key plus one or more sample
      expressions).  The key is the argument before the value, or the one the
      caller names where the value stands on its own.

  flt_otel_parse_cfg_sample_cond
      Parses a sample definition optionally followed by an 'if'/'unless' ACL
      condition, building the condition onto the parsed sample.

  flt_otel_parse_check_sample_open
      Enforces the placement of the condition-less line of a repeated sample
      key: that line is the default and has to come last, so once the list it
      is appended to holds one, a further line with the same key is rejected.
      Event lines are compared within one event name only, so a key repeats
      freely across the names; the name is carried in the sample's extra data.

  flt_otel_find_cond_pos
      Locates the first 'if' or 'unless' keyword that introduces an optional
      trailing ACL condition in an argument array.

  flt_otel_parse_attach_cond
      Builds the ACL condition found at a given argument position and stores
      it into a destination pointer; at runtime the directive carrying it is
      applied only when the condition holds.  The scope's, instrumentation's
      and proxy's ACL lists are merged for the build, so each name resolves
      against them in that order; an instrumentation parsed later in the file
      contributes no list.

  flt_otel_parse_cfg_time
      Parses the value part of an optional 'time [s|ms|us|ns] <sample>' clause
      into a single-sample list, with the unit stored in the sample's extra.

  flt_otel_parse_cfg_str
      Parses one or more string arguments into a conf_str list (used for the
      "finish" keyword).

  flt_otel_cfg_file_check
      Checks that a configuration file path is readable and names a regular
      file; used both for the filter's own configuration file and for the YAML
      file that the 'config' keyword names.

  flt_otel_parse_cfg_file
      Parses and validates a file path argument; checks that the file exists and
      is readable and that no trailing condition follows it.

  flt_otel_parse_scope_name
      Recognizes a '[<name>]' OTel scope declaration in the raw content of the
      configuration file, reporting the name as a pointer and a length.

  flt_otel_parse_check_scope_names
      Rejects a top-level OTel scope name that opens for a second time, matching
      every declaration of the loaded file against the ones before it, and a
      scope called 'if' or 'unless', which the general name rule forbids.

  flt_otel_parse_check_scope
      Checks whether the current config line is within the correct OTel scope
      (cfg_scope filtering); rejects a line outside of any scope.

  flt_otel_kw_lookup
      Scans a keyword/code mapping table for the entry whose keyword equals the
      given string, returning the matching entry or NULL.

  flt_otel_parse_cfg_acl
      Parses the 'acl' keyword shared by the otel-instrumentation and otel-scope
      sections, rejecting 'if', 'unless' and 'or' as a name before calling
      parse_acl().

  flt_otel_parse_cfg_instr
      Section parser for the otel-instrumentation block.  Handles keywords:
      otel-instrumentation ID, log, config, groups, scopes, acl, rate-limit,
      option, debug-level.

  flt_otel_post_parse_cfg_instr
      Post-parse callback for otel-instrumentation.  Links the instrumentation
      to the config and checks that a config file is specified.

  flt_otel_parse_cfg_group
      Section parser for the otel-group block.  Handles keywords: otel-group ID,
      scopes.

  flt_otel_post_parse_cfg_group
      Post-parse callback for otel-group.  Checks that at least one scope is
      defined.

  flt_otel_parse_ctx_flag
      Recognizes a context storage type token ("use-headers" or "use-vars") and
      returns the matching flag; shared by the inject and extract keywords.

  flt_otel_parse_cfg_scope_ctx
      Parses the context storage type argument ("use-headers" or "use-vars") for
      the inject keyword, recording it on the current span.

  flt_otel_parse_acl_borrow
      Moves every entry of an ACL list to the tail of another, keeping their
      order, so the ACL lists can be merged for a single build_acl_cond() call.

  flt_otel_parse_acl_restore
      Returns the borrowed ACL entries to their list in their original order,
      undoing flt_otel_parse_acl_borrow() once the condition has been built.

  flt_otel_parse_trailing_cond
      Builds a mandatory trailing 'if'/'unless' condition; used by exception,
      set-var-ctx, otel-stop and otel-event.

  flt_otel_parse_reject_cond
      Rejects the trailing 'if'/'unless' condition on a keyword whose definition
      does not allow one and that would otherwise swallow it as a name or as a
      value; used by config, groups, scopes and finish.

  flt_otel_parse_reject_name
      Rejects 'if' or 'unless' where a keyword defines a name that other lines
      refer to.  Those two words open a condition wherever a reference stands,
      so such a name could never be written again.

  flt_otel_parse_check_name_len
      Measures a referenced name against the length limit every name keeps, so
      a reference too long to name anything is reported on its own line.

  flt_otel_parse_bounds
      Parses a space-separated string of numbers into a dynamically allocated
      array of doubles for histogram bucket boundaries.  Sorts the values
      internally.

  flt_otel_parse_check_unit
      Checks a metric unit against the rule of the OTel SDK, which takes fewer
      than FLT_OTEL_UNIT_MAXLEN characters and only ASCII ones.  A unit the SDK
      refuses costs the whole instrument, so the line is rejected at parse time.

  flt_otel_parse_cfg_instrument
      Parses the "instrument" keyword inside an otel-scope section.  Supports
      both "update" form (referencing an existing instrument) and "create" form
      (defining a new metric instrument with type, name, optional aggregation
      type, description, unit, value, and optional histogram bounds).  Either
      form may end with an optional if/unless condition controlling the recorded
      measurement.

  flt_otel_parse_cfg_log_record
      Parses the "log-record" keyword: a required severity, the optional "id",
      "event", "time", "span" and "attr" clauses in any order, the trailing
      body expressions, and an optional if/unless condition.

  flt_otel_parse_cfg_exception
      Parses the "exception" keyword: the required type, the optional "message"
      sample expressions, repeatable "attr" clauses and an optional if/unless
      condition.

  flt_otel_parse_check_field_key
      Checks the key inside a 'baggage' or a 'tracestate' field of set-var-ctx
      against the rule the W3C document gives it: an HTTP token for baggage,
      and for tracestate a lower-case name or a tenant and a system id around
      one '@'.  A key those rules refuse cannot stand in the carrier the field
      is read from, so the line naming it is rejected at parse time.

  flt_otel_parse_cfg_set_var_ctx
      Parses the set-var-ctx reference and field selector (a field name with an
      optional parenthesised key, such as 'baggage(userId)'), plus an optional
      if/unless condition.

  flt_otel_parse_cfg_unset_var
      Parses an unset-var directive: one or more validated variable names with
      an optional if/unless condition controlling their removal as a unit.

  flt_otel_parse_cfg_scope
      Section parser for the otel-scope block.  Handles keywords: otel-scope ID,
      span, link, attribute, event, baggage, status, exception, inject, extract,
      finish, otel-stop, instrument, log-record, idle-timeout, acl, otel-event,
      set-var, set-var-ctx, unset-var.

  flt_otel_post_parse_ctx_autoname
      Resolves a span context name that 'inject' deferred at parse time with
      the '-' autoname: prefers the scope's event name, falls back to the span
      name, and keeps the leading '-' so the injected headers stay bare.

  flt_otel_post_parse_cfg_scope
      Post-parse callback for otel-scope.  Checks that HTTP header injection is
      only used on events that support it.  Also validates the idle-timeout
      pairing: an idle-timeout is required for the on-idle-timeout event and
      rejected with any other event.

  flt_otel_parse_cfg
      Parses the OTel filter configuration file.  Backs up current sections,
      registers temporary otel-instrumentation/group/scope section parsers,
      loads and parses the file, then restores the original sections and clears
      the section state, so a parse that stopped at an error leaves no pointer
      of this file behind for the next filter line.  Rejects a selected scope
      that holds no otel-instrumentation section, naming the 'filter' line in
      the alert.

  flt_otel_parse
      Main filter parser entry point, registered for the "opentelemetry" filter
      keyword.  Parses the filter ID and configuration file path from the
      HAProxy config line.


src/conf.c
----------------------------------------------------------------------

Configuration structure allocation and deallocation.  Most init/free pairs are
generated by the FLT_OTEL_CONF_FUNC_INIT and FLT_OTEL_CONF_FUNC_FREE macros.

  flt_otel_conf_hdr_init
      Allocates and initializes a conf_hdr structure.

  flt_otel_conf_hdr_free
      Frees a conf_hdr structure and removes it from its list.

  flt_otel_conf_str_init
      Allocates and initializes a conf_str structure.

  flt_otel_conf_str_free
      Frees a conf_str structure and removes it from its list.

  flt_otel_conf_link_init
      Allocates and initializes a conf_link structure (span link).

  flt_otel_conf_link_free
      Frees a conf_link structure and removes it from its list.

  flt_otel_conf_ph_init
      Allocates and initializes a conf_ph (placeholder) structure.

  flt_otel_conf_ph_free
      Frees a conf_ph structure and removes it from its list.

  flt_otel_conf_sample_expr_init
      Allocates and initializes a conf_sample_expr structure.

  flt_otel_conf_sample_expr_free
      Frees a conf_sample_expr structure and releases the parsed sample
      expression.

  flt_otel_conf_sample_init
      Allocates and initializes a conf_sample structure.

  flt_otel_conf_sample_init_ex
      Extended sample initialization: sets the key, taken from the argument
      before the value unless the caller names one, the extra data (event name
      or status code), the concatenated value string and the expression count.

  flt_otel_conf_sample_init_code
      Allocates a conf_sample that carries only an int32 status code in its
      extra data and holds no sample expressions; used for a span status
      without a description.

  flt_otel_conf_sample_free
      Frees a conf_sample structure including its value, extra data, and all
      sample expressions.

  flt_otel_conf_context_init
      Allocates and initializes a conf_context structure.

  flt_otel_conf_context_free
      Frees a conf_context structure and removes it from its list.

  flt_otel_conf_span_init
      Allocates and initializes a conf_span structure with empty lists for
      links, attributes, events, baggages, statuses and exceptions, and the
      span kind defaulted to server.

  flt_otel_conf_span_free
      Frees a conf_span structure and all its child lists.

  flt_otel_conf_exception_init
      Allocates and initializes a conf_exception structure and its message and
      attribute lists.

  flt_otel_conf_exception_free
      Frees a conf_exception structure: the type string, the message and
      attributes lists, and the optional ACL condition.

  flt_otel_conf_instrument_init
      Allocates and initializes a conf_instrument structure.

  flt_otel_conf_instrument_free
      Frees a conf_instrument structure and removes it from its list.

  flt_otel_conf_log_record_init
      Allocates and initializes a conf_log_record structure with empty
      time, attributes and samples lists.

  flt_otel_conf_log_record_free
      Frees a conf_log_record structure: event_name, span, time, attributes and
      samples lists, plus the optional ACL condition.

  flt_otel_conf_set_var_ctx_init
      Allocates and initializes a conf_set_var_ctx structure with the target
      variable name.

  flt_otel_conf_set_var_ctx_free
      Frees a conf_set_var_ctx structure: the ref and field_key strings and the
      optional ACL condition.

  flt_otel_conf_unset_var_init
      Allocates and initializes a conf_unset_var structure with an empty list
      of variable names.

  flt_otel_conf_unset_var_free
      Frees a conf_unset_var structure: its variable-name list and the optional
      ACL condition.

  flt_otel_conf_stop_init
      Allocates and initializes a conf_stop structure holding one otel-stop
      directive.

  flt_otel_conf_stop_free
      Frees a conf_stop structure and its optional ACL condition.

  flt_otel_conf_scope_init
      Allocates and initializes a conf_scope structure with empty lists for
      ACLs, stops, contexts, spans, spans_to_finish, instruments, log_records,
      set_vars, set_var_ctxs and unset_vars.

  flt_otel_conf_scope_free
      Frees a conf_scope structure, ACLs, conditions, and all child lists.

  flt_otel_conf_group_init
      Allocates and initializes a conf_group structure with an empty placeholder
      scope list.

  flt_otel_conf_group_free
      Frees a conf_group structure and its placeholder scope list.

  flt_otel_conf_instr_init
      Allocates and initializes a conf_instr structure.  Sets the default rate
      limit to 100%, initializes the runtime-log proxy (log.proxy), and creates
      empty ACL and placeholder lists.

  flt_otel_conf_instr_free
      Frees a conf_instr structure including ACLs, loggers, config path, and
      placeholder lists.

  flt_otel_conf_init
      Allocates and initializes the top-level flt_otel_conf structure with empty
      group and scope lists.

  flt_otel_conf_free
      Frees the top-level flt_otel_conf structure and all of its children
      (instrumentation, groups, scopes).


src/cli.c
----------------------------------------------------------------------

HAProxy CLI command handlers for runtime filter management.

  flt_otel_cli_set_msg
      Sets the CLI appctx response message and state.

  flt_otel_cli_args_target
      Extracts the optional "@<filter>" target token that follows a CLI
      subcommand keyword, reports the position of the value argument and rejects
      a surplus argument.

  flt_otel_cli_target_missing
      Builds a "no such filter" error message when a target was given but no
      instance matched.

  flt_otel_cli_target_count
      Counts the OTel filter instances whose filter id matches a target.

  flt_otel_cli_parse_debug [D]
      CLI handler for "flt-otel debug [level]".  Gets or sets the debug level.

  flt_otel_cli_parse_disabled
      CLI handler for "flt-otel enable" and "flt-otel disable".

  flt_otel_cli_parse_option
      CLI handler for "flt-otel soft-errors" and "flt-otel hard-errors".

  flt_otel_cli_parse_reset_errors
      CLI handler for "flt-otel reset-errors".  Clears the runtime-error
      counters and the log rate-limiter state for all OTel filter instances,
      or for the targeted one only.  The lifetime total of suppressed lines is
      retained.

  flt_otel_cli_parse_logging
      CLI handler for "flt-otel logging [state]".  Gets or sets the logging
      state (off/on/dontlog-normal).

  flt_otel_cli_parse_noflush
      CLI handler for "flt-otel noflush [state]".  Gets or sets the noflush
      mode (off/on).

  flt_otel_cli_parse_rate
      CLI handler for "flt-otel rate [value]".  Gets or sets the rate limit
      percentage.

  flt_otel_cli_px_first
      Positions the proxy cursor of a CLI dump context on the first proxy,
      attached through a watcher on HAProxy versions with the main_proxies
      list.

  flt_otel_cli_px_next
      Advances the proxy cursor of a CLI dump context to the next proxy.

  flt_otel_cli_conf_next
      Advances a CLI dump context to the next OTel filter configuration,
      moving across proxies as needed and skipping instances that do not
      match the dump target.

  flt_otel_cli_instr_cur
      Resolves the metric instrument row designated by a CLI dump context,
      moving the cursor to the next scope with instruments as needed.

  flt_otel_cli_dump_init
      Reserves and initializes the CLI dump context in the applet service
      context storage.

  flt_otel_cli_dump_resume
      Recovers the filter configuration cursor of an interrupted dump and
      restarts at the successor proxy after a deletion.

  flt_otel_cli_dump_release
      io_release handler of the dump commands; detaches the proxy watcher and
      frees the target filter id copy.

  flt_otel_cli_dump_target
      Common parse-callback body of the dump commands; resolves the optional
      "@<filter>" target token and initializes the CLI dump context.

  flt_otel_cli_parse_status
      CLI handler for "flt-otel status".  Initializes the CLI dump context;
      the report is built by the flt_otel_cli_io_status() io_handler.

  flt_otel_cli_io_status
      io_handler that iteratively dumps the filter configuration and runtime
      state for all OTel filter instances, or the targeted one, resuming when
      the output buffer fills.

  flt_otel_cli_parse_flush
      CLI handler for "flt-otel flush".  Force-exports the buffered telemetry
      for all OTel filter instances, or for the targeted one only, with all the
      force_flush calls sharing one time budget.

  flt_otel_cli_parse_instruments
      CLI handler for "flt-otel instruments".  Initializes the CLI dump
      context; the report is built by the flt_otel_cli_io_instruments()
      io_handler.

  flt_otel_cli_io_instruments
      io_handler that iteratively lists the configured metric instruments in
      each scope for all OTel filter instances, or the targeted one, resuming
      when the output buffer fills.

  flt_otel_cli_parse_scopes
      CLI handler for "flt-otel scopes".  Initializes the CLI dump context;
      the report is built by the flt_otel_cli_io_scopes() io_handler.

  flt_otel_cli_io_scopes
      io_handler that iteratively lists the configured scopes and groups for
      all OTel filter instances, or the targeted one, resuming when the output
      buffer fills.

  flt_otel_cli_init
      Registers the OTel CLI keywords with HAProxy.


src/otelc.c
----------------------------------------------------------------------

OpenTelemetry context propagation bridge (inject/extract) between HAProxy and
the OTel C wrapper library.

  flt_otel_text_map_writer_set_cb
      Writer callback for text map injection.  Appends a key-value pair to the
      text map.

  flt_otel_http_headers_writer_set_cb
      Writer callback for HTTP headers injection.  Appends a key-value pair to
      the text map.

  flt_otel_inject_text_map
      Injects span context into a text map carrier.

  flt_otel_inject_http_headers
      Injects span context into an HTTP headers carrier.

  flt_otel_text_map_reader_foreach_key_cb
      Reader callback for text map extraction.  Iterates over all key-value
      pairs in the text map.

  flt_otel_http_headers_reader_foreach_key_cb
      Reader callback for HTTP headers extraction.  Iterates over all key-value
      pairs in the text map.

  flt_otel_extract_text_map
      Extracts a span context from a text map carrier via the tracer.

  flt_otel_extract_http_headers
      Extracts a span context from an HTTP headers carrier via the tracer.


src/http.c
----------------------------------------------------------------------

HTTP header manipulation for context propagation.

  flt_otel_http_headers_dump [D]
      Dumps all HTTP headers from the channel's HTX buffer.  Channels that do
      not belong to an HTX stream are skipped.

  flt_otel_http_headers_get
      Extracts HTTP headers matching a prefix into a text map.  A header whose
      name is only the prefix is skipped, as the stripped name would be empty.
      Used by the "extract" keyword to read span context from incoming request
      headers.

  flt_otel_http_header_set
      Sets or removes an HTTP header.  Combines prefix and name into the full
      header name, removes all existing occurrences, then adds the new value
      (if non-NULL).

  flt_otel_http_headers_remove
      Removes all HTTP headers matching a prefix.  Wrapper around
      flt_otel_http_header_set() with NULL name and value.


src/vars.c
----------------------------------------------------------------------

HAProxy variable integration for context propagation and storage.  The
*_byname helpers at the top of the file are always compiled (they back the
set-var, set-var-ctx and unset-var directives); the remainder of the file is
compiled only when USE_OTEL_VARS is defined.

  flt_otel_var_register_byname
      Registers a HAProxy variable by its full name so it can be set at
      runtime.

  flt_otel_var_set_byname
      Sets the named HAProxy variable to a string value; a NULL value is
      treated as an empty string.

  flt_otel_var_unset_byname
      Removes the named HAProxy variable from the stream; a variable that is
      not set is silently ignored.

  flt_otel_vars_scope_dump [D]
      Dumps all variables for a single HAProxy variable scope.

  flt_otel_vars_dump [D]
      Dumps all variables across all scopes (PROC, SESS, TXN, REQ/RES).

  flt_otel_smp_init
      Initializes a sample structure with stream ownership and optional string
      data.

  flt_otel_smp_add
      Appends a context variable name to the binary sample data buffer used for
      tracking registered context variables.

  flt_otel_normalize_name
      Normalizes a variable name: replaces dashes with 'D' and spaces with 'S',
      converts to lowercase.

  flt_otel_denormalize_name
      Reverses the normalization applied by flt_otel_normalize_name().  Restores
      dashes from 'D' and spaces from 'S'.

  flt_otel_var_name
      Constructs a full variable name from scope, prefix and name components,
      separated by dots.

  flt_otel_ctx_loop
      Iterates over all context variable names stored in the binary sample data,
      calling a callback for each.

  flt_otel_ctx_set_cb
      Callback for flt_otel_ctx_loop() that checks whether a context variable
      name already exists.

  flt_otel_ctx_set
      Registers a context variable name in the binary tracking buffer if it is
      not already present.

  flt_otel_var_register
      Registers a HAProxy variable via vars_check_arg() so it can be used at
      runtime.

  flt_otel_var_set
      Sets a HAProxy variable value.  For context-scope variables, also
      registers the name in the context tracking buffer.

  flt_otel_vars_unset_cb
      Callback for flt_otel_ctx_loop() that unsets each context variable.

  flt_otel_vars_unset
      Unsets all context variables for a given prefix and removes the tracking
      variable itself.

  flt_otel_vars_get_scope
      Resolves a scope name string ("proc", "sess", "txn", "req", "res") to the
      corresponding HAProxy variable store.

  flt_otel_vars_get_cb
      Callback for flt_otel_ctx_loop() that reads each context variable value
      and adds it to a text map.

  flt_otel_vars_get
      Reads all context variables for a prefix into a text map.  Used by the
      "extract" keyword with variable storage.


src/sample.c
----------------------------------------------------------------------

HAProxy sample fetches exposing OTel runtime state to ACLs and rules.

  flt_otel_fetch_context
      Reports whether the named span context was extracted on the stream and
      is valid.  Backs the "otel.context" sample fetch.

  smp_fetch_otel_bytes
      Reports the raw payload byte count accounted on the stream.  Backs the
      "otel.bytes_in" and "otel.bytes_out" sample fetches.


src/pool.c
----------------------------------------------------------------------

Memory pool and trash buffer helpers.

  flt_otel_pool_init
      Initializes all memory pools used by the OTel filter.  Each pool is
      created only when the corresponding USE_POOL_OTEL_* macro is defined.

  flt_otel_pool_destroy
      Destroys all memory pools used by the OTel filter.  Each pool is destroyed
      only when the corresponding USE_POOL_OTEL_* macro is defined.

  flt_otel_pool_info [D]
      Logs the sizes of all registered HAProxy memory pools used by the OTel
      filter.

  flt_otel_pool_alloc
      Allocates memory from a HAProxy pool (if available) or from the heap.
      Optionally zero-fills the allocated block.

  flt_otel_pool_free
      Returns memory to a HAProxy pool or frees it from the heap.

  flt_otel_trash_alloc
      Allocates a trash buffer chunk, optionally zero-filled.

  flt_otel_trash_free
      Frees a trash buffer chunk.


src/util.c
----------------------------------------------------------------------

Utility and conversion functions.

  flt_otel_args_dump [D]
      Dumps configuration arguments array to stderr.

  flt_otel_filters_dump [D]
      Dumps all OTel filter instances across all proxies.

  flt_otel_chn_label [D]
      Returns "REQuest" or "RESponse" based on channel flags.

  flt_otel_pr_mode [D]
      Returns "HTTP" or "TCP" based on proxy mode.

  flt_otel_stream_pos [D]
      Returns "frontend" or "backend" based on stream flags.

  flt_otel_type [D]
      Returns "frontend" or "backend" based on filter flags.

  flt_otel_analyzer [D]
      Returns the analyzer name string for a given analyzer bit.

  flt_otel_list_dump [D]
      Returns a summary string for a list (empty, single, count).

  flt_otel_args_count
      Counts the number of valid (non-NULL) arguments in an args array, handling
      gaps from blank arguments.

  flt_otel_args_concat
      Concatenates arguments starting from a given index into a single
      space-separated string.

  flt_otel_flush_budget
      Fills a timeout with the time left until a telemetry flush deadline and
      reports whether any budget remains; a spent budget must skip the flush,
      as the SDK reads a non-positive timeout as no timeout at all.

  flt_otel_str_escape
      Escapes the non-printable characters of a string into a bounded buffer,
      in HAProxy's '#XX' form, for logging text that may carry raw sample bytes.

  flt_otel_strtod
      Parses a string to double with range validation.

  flt_otel_strtoll
      Parses a string to int64 with range validation.

  flt_otel_qsort_compar_double
      qsort() comparator ordering doubles ascending with a strict, transitive
      comparison; near-equal values are left to the boundary duplicate check.

  flt_otel_sample_to_str
      Converts sample data to its string representation.  Handles bool, sint,
      IPv4, IPv6, str, and HTTP method types.

  flt_otel_sample_to_value
      Converts sample data to an otelc_value.  Preserves native types (bool,
      int64) where possible; falls back to string.

  flt_otel_sample_add_event
      Adds a sample value as a span event attribute.  Groups attributes by event
      name; dynamically grows the attribute array.

  flt_otel_sample_set_status
      Sets the span status code and description from sample data.

  flt_otel_sample_add_kv
      Adds a sample value as a key-value attribute or baggage entry.
      Dynamically grows the key-value array.

  flt_otel_sample_add_attr
      Evaluates a sample definition and appends the result to a given key-value
      array.  Used for attributes not held in the scope data directly, such as
      span link attributes.

  flt_otel_sample_eval
      Evaluates all sample expressions for a configured sample definition and
      stores the result in an otelc_value.  Supports both log-format and bare
      sample expression paths.  When flag_native is true and the sample has
      exactly one expression, the native HAProxy sample type is preserved;
      otherwise results are concatenated into a string.

  flt_otel_sample_eval_time
      Evaluates a 'time' sample and converts the numeric result into a struct
      timespec using the unit in the sample's extra data.  Returns 1 when a
      valid timestamp was produced, 0 otherwise.

  flt_otel_sample_add
      Top-level sample evaluator and dispatcher.  Calls flt_otel_sample_eval()
      to evaluate the sample, then dispatches the result to the appropriate
      handler (attribute, event, baggage, status).  A baggage pair whose sample
      produced an empty value is left out, the wrapper refusing such a value and
      dropping the pairs of the span already set with it.

  flt_otel_baggage_value
      Scans a comma-separated W3C baggage carrier for the entry with the given
      key and copies its value out, trimming spaces and dropping properties.

  flt_otel_ctx_field_to_str
      Renders the requested field of a referenced span or context as a string:
      hex identifiers, the W3C traceparent form, tracestate entries and keyed
      or keyless baggage.  A field that cannot be resolved yields an empty
      string.

  flt_otel_table_init
      Allocates an empty aligned table; columns are appended one at a time and
      no dimensions are fixed in advance.

  flt_otel_table_add_column_n
      Appends a column built from an array of cell values, duplicating the
      title and cells; a NULL entry is kept as an empty cell.  A flag selects
      left or right alignment.

  flt_otel_table_add_column
      Variadic wrapper around flt_otel_table_add_column_n(): gathers the cell
      values up to a NULL terminator into an array and forwards them.

  flt_otel_table_format
      Lays the columns out into aligned, right-trimmed text lines: a header row
      built from the column titles followed by the cell rows, each column
      padded to its widest value and separated by two spaces.

  flt_otel_table_free
      Releases the table and everything it owns: duplicated titles and cells,
      the column array, and the formatted output lines.


src/group.c
----------------------------------------------------------------------

Group action support for http-request / http-response / http-after-response /
tcp-request / tcp-response rules.

  flt_otel_group_action
      Action callback (action_ptr) for the otel-group rule.  Finds the filter
      instance on the current stream and runs all scopes defined in the group.

  flt_otel_group_check
      Check callback (check_ptr) for the otel-group rule.  Resolves filter ID
      and group ID references against the proxy's filter configuration.

  flt_otel_group_check_loc
      Validates every scope of a group against the processing point of the
      otel-group action, resolving the scopes by name and passing each to
      flt_otel_check_scope_loc().

  flt_otel_group_release
      Release callback (release_ptr) for the otel-group rule.

  flt_otel_group_parse
      Parses the "otel-group" action keyword from HAProxy config rules.
      Registered for tcp-request, tcp-response, http-request, http-response and
      http-after-response action contexts.
