From 081a8fd5cfc602ac3f8286347d30905fea366fed Mon Sep 17 00:00:00 2001 From: Miroslav Zagorac Date: Sat, 21 Mar 2026 18:39:52 +0100 Subject: [PATCH] DOC: otel: test: added test README-* files Added README documentation for each test configuration (sa, cmp, ctx, fe-be, empty, full) describing event coverage, signal usage, instrument tables, span hierarchies and run instructions. --- addons/otel/test/README-cmp | 85 ++++++++++++++++++ addons/otel/test/README-ctx | 149 ++++++++++++++++++++++++++++++++ addons/otel/test/README-empty | 53 ++++++++++++ addons/otel/test/README-fe-be | 124 ++++++++++++++++++++++++++ addons/otel/test/README-full | 158 ++++++++++++++++++++++++++++++++++ addons/otel/test/README-sa | 134 ++++++++++++++++++++++++++++ 6 files changed, 703 insertions(+) create mode 100644 addons/otel/test/README-cmp create mode 100644 addons/otel/test/README-ctx create mode 100644 addons/otel/test/README-empty create mode 100644 addons/otel/test/README-fe-be create mode 100644 addons/otel/test/README-full create mode 100644 addons/otel/test/README-sa diff --git a/addons/otel/test/README-cmp b/addons/otel/test/README-cmp new file mode 100644 index 000000000..ab1b6d74f --- /dev/null +++ b/addons/otel/test/README-cmp @@ -0,0 +1,85 @@ +Comparison test configuration (cmp/) +==================================== + +The 'cmp' test is a simplified standalone configuration made for comparison with +other tracing implementations. It uses a reduced set of events and a compact +span hierarchy without context propagation, groups or metrics. This +configuration is closer to a typical production deployment. + +All response-side scopes (http_response, http_response-error, server_session_end +and client_session_end) share the on-http-response event, which means they fire +in a single batch at response time. + + +Files +----- + + cmp/otel.cfg OTel filter configuration (scopes) + cmp/haproxy.cfg HAProxy frontend/backend configuration + cmp/otel.yml Exporter, processor, reader and provider definitions + run-cmp.sh Convenience script to launch HAProxy with this config + + +Events +------ + + T = Trace (span) + + This configuration produces traces only -- no metrics or log-records. + + Request analyzer events: + + Event Scope T + -------------------------------------------------------- + on-client-session-start client_session_start x + on-frontend-tcp-request frontend_tcp_request x + on-frontend-http-request frontend_http_request x + on-backend-tcp-request backend_tcp_request x + on-backend-http-request backend_http_request x + on-server-unavailable server_unavailable x + + Response analyzer events: + + Event Scope T + -------------------------------------------------------- + on-server-session-start server_session_start x + on-tcp-response tcp_response x + on-http-response http_response x + on-http-response http_response-error x (conditional) + on-http-response server_session_end - (finish only) + on-http-response client_session_end - (finish only) + + The http_response-error scope fires conditionally when the ACL + acl-http-status-ok (status 100:399) does not match, setting an error status + on the "HTTP response" span. + + The server_session_end and client_session_end scopes are bound to the + on-http-response event and only perform finish operations. + + +Span hierarchy +-------------- + + "HAProxy session" (root) + +-- "Client session" + +-- "Frontend TCP request" + +-- "Frontend HTTP request" + +-- "Backend TCP request" + +-- "Backend HTTP request" + + "HAProxy session" (root) + +-- "Server session" + +-- "TCP response" + +-- "HTTP response" + + +Running the test +---------------- + +From the test/ directory: + + % ./run-cmp.sh [/path/to/haproxy] [pidfile] + +If no arguments are given, the script looks for the haproxy binary three +directories up from the current working directory. The backend origin server +must be running on 127.0.0.1:8000. diff --git a/addons/otel/test/README-ctx b/addons/otel/test/README-ctx new file mode 100644 index 000000000..512706ef6 --- /dev/null +++ b/addons/otel/test/README-ctx @@ -0,0 +1,149 @@ +Context propagation test configuration (ctx/) +============================================= + +The 'ctx' test is a standalone configuration that uses inject/extract context +propagation on every scope. Spans are opened using extracted span contexts +stored in HAProxy variables as parent references instead of direct span names. +This adds the overhead of context serialization, variable storage and +deserialization on every scope execution. + +The event coverage matches the 'sa' configuration. The key difference is the +propagation mechanism: each scope injects its context into a numbered variable +(otel_ctx_1 through otel_ctx_17) and the next scope extracts from that variable +to establish the parent relationship. + +The client_session_start event is split into two scopes (client_session_start_1 +and client_session_start_2) to demonstrate inject/extract between scopes +handling the same event. + + +Files +----- + + ctx/otel.cfg OTel filter configuration (scopes, groups, contexts) + ctx/haproxy.cfg HAProxy frontend/backend configuration + ctx/otel.yml Exporter, processor, reader and provider definitions + run-ctx.sh Convenience script to launch HAProxy with this config + + +Events +------ + + T = Trace (span) + + This configuration produces traces only -- no metrics or log-records. + + Stream lifecycle events: + + Event Scope T + ---------------------------------------------------------- + on-client-session-start client_session_start_1 x + on-client-session-start client_session_start_2 x + + Request analyzer events: + + Event Scope T + -------------------------------------------------------------------- + on-frontend-tcp-request frontend_tcp_request x + on-http-wait-request http_wait_request x + on-http-body-request http_body_request x + on-frontend-http-request frontend_http_request x + on-switching-rules-request switching_rules_request x + on-backend-tcp-request backend_tcp_request x + on-backend-http-request backend_http_request x + on-process-server-rules-request process_server_rules_request x + on-http-process-request http_process_request x + on-tcp-rdp-cookie-request tcp_rdp_cookie_request x + on-process-sticking-rules-request process_sticking_rules_request x + on-client-session-end client_session_end - + on-server-unavailable server_unavailable - + + Response analyzer events: + + Event Scope T + -------------------------------------------------------------------- + on-server-session-start server_session_start x + on-tcp-response tcp_response x + on-http-wait-response http_wait_response x + on-process-store-rules-response process_store_rules_response x + on-http-response http_response x + on-http-response http_response-error x (conditional) + on-server-session-end server_session_end - + + The http_response_group (http_response_1, http_response_2) and + http_after_response_group (http_after_response) are invoked via http-response + and http-after-response directives in haproxy.cfg. + + +Context propagation chain +------------------------- + + Each scope injects its span context into a HAProxy variable and the next scope + extracts it. The variable names and their flow: + + otel_ctx_1 "HAProxy session" -> client_session_start_2 + otel_ctx_2 "Client session" -> frontend_tcp_request + otel_ctx_3 "Frontend TCP request" -> http_wait_request + otel_ctx_4 "HTTP wait request" -> http_body_request + otel_ctx_5 "HTTP body request" -> frontend_http_request + otel_ctx_6 "Frontend HTTP request" -> switching_rules_request + otel_ctx_7 "Switching rules request" -> backend_tcp_request + otel_ctx_8 "Backend TCP request" -> backend_http_request + otel_ctx_9 "Backend HTTP request" -> process_server_rules_request + otel_ctx_10 "Process server rules request" -> http_process_request + otel_ctx_11 "HTTP process request" -> tcp_rdp_cookie_request + otel_ctx_12 "TCP RDP cookie request" -> process_sticking_rules_request + otel_ctx_13 "Process sticking rules req." -> server_session_start + otel_ctx_14 "Server session" -> tcp_response + otel_ctx_15 "TCP response" -> http_wait_response + otel_ctx_16 "HTTP wait response" -> process_store_rules_response + otel_ctx_17 "Process store rules response" -> http_response + + All contexts use both use-headers and use-vars injection modes, except + otel_ctx_14 and otel_ctx_15 which use use-vars only. + + +Span hierarchy +-------------- + + The span hierarchy is identical to the 'sa' configuration, but parent + relationships are established through extracted contexts rather than direct + span name references. + + Request path: + + "HAProxy session" (root) [otel_ctx_1] + +-- "Client session" [otel_ctx_2] + +-- "Frontend TCP request" [otel_ctx_3] + +-- "HTTP wait request" [otel_ctx_4] + +-- "HTTP body request" [otel_ctx_5] + +-- "Frontend HTTP request" [otel_ctx_6] + +-- "Switching rules request" [otel_ctx_7] + +-- "Backend TCP request" [otel_ctx_8] + +-- (continues to process_sticking_rules_request) + + Response path: + + "HAProxy session" [otel_ctx_1] + +-- "Server session" [otel_ctx_14] + +-- "TCP response" [otel_ctx_15] + +-- "HTTP wait response" [otel_ctx_16] + +-- "Process store rules response" [otel_ctx_17] + +-- "HTTP response" + + Auxiliary spans: + + "HAProxy session" + +-- "HAProxy response" (http_after_response_group, on error) + + +Running the test +---------------- + +From the test/ directory: + + % ./run-ctx.sh [/path/to/haproxy] [pidfile] + +If no arguments are given, the script looks for the haproxy binary three +directories up from the current working directory. The backend origin server +must be running on 127.0.0.1:8000. diff --git a/addons/otel/test/README-empty b/addons/otel/test/README-empty new file mode 100644 index 000000000..5f19651db --- /dev/null +++ b/addons/otel/test/README-empty @@ -0,0 +1,53 @@ +Empty test configuration (empty/) +================================= + +The 'empty' test is a minimal configuration that loads the OTel filter without +defining any scopes, events or groups. The instrumentation block contains only +the config directive pointing to the YAML pipeline definition. + +This configuration verifies that the filter initializes and shuts down cleanly +when no telemetry is configured. It exercises the full YAML parsing path +(exporters, processors, readers, samplers, providers and signals) without +producing any trace, metric or log-record data. + + +Files +----- + + empty/otel.cfg OTel filter configuration (instrumentation only) + empty/haproxy.cfg HAProxy frontend/backend configuration + empty/otel.yml Exporter, processor, reader and provider definitions + + +Events +------ + + No events are registered. The filter is loaded and attached to the frontend + but performs no per-stream processing. + + +YAML pipeline +------------- + + Despite the empty filter configuration, the otel.yml file defines a complete + pipeline with all three signal types to verify that the YAML parser handles + the full configuration without errors: + + Signal Exporter Processor / Reader + ----------------------------------------------------------- + traces exporter_traces_otlp_http processor_traces_batch + metrics exporter_metrics_otlp_http reader_metrics + logs exporter_logs_otlp_http processor_logs_batch + + Additional exporter definitions (otlp_file, otlp_grpc, ostream, memory, + zipkin, elasticsearch) are present in the YAML but are not wired into the + active signal pipelines. + + +Running the test +---------------- + +There is no dedicated run script for the empty configuration. To run it +manually from the test/ directory: + + % /path/to/haproxy -f haproxy-common.cfg -f empty/haproxy.cfg diff --git a/addons/otel/test/README-fe-be b/addons/otel/test/README-fe-be new file mode 100644 index 000000000..647a21cd9 --- /dev/null +++ b/addons/otel/test/README-fe-be @@ -0,0 +1,124 @@ +Frontend / backend test configuration (fe/ + be/) +================================================= + +The 'fe-be' test uses two cascaded HAProxy instances to demonstrate +inter-process trace context propagation via HTTP headers. The frontend instance +(fe/) creates the root trace and injects span context into the HTTP request +headers. The backend instance (be/) extracts that context and continues the +trace as a child of the frontend's span. + +The two instances run as separate processes: the frontend listens on port 10080 +and proxies to the backend on port 11080, which in turn proxies to the origin +server on port 8000. + + +Files +----- + + fe/otel.cfg OTel filter configuration for the frontend instance + fe/haproxy.cfg HAProxy configuration for the frontend instance + be/otel.cfg OTel filter configuration for the backend instance + be/haproxy.cfg HAProxy configuration for the backend instance + run-fe-be.sh Convenience script to launch both instances + + +Events +------ + + T = Trace (span) + + Both instances produce traces only -- no metrics or log-records. + + Frontend (fe/) events: + + Event Scope T + -------------------------------------------------------- + on-client-session-start client_session_start x + on-frontend-tcp-request frontend_tcp_request x + on-frontend-http-request frontend_http_request x + on-backend-tcp-request backend_tcp_request x + on-backend-http-request backend_http_request x + on-client-session-end client_session_end - + on-server-session-start server_session_start x + on-tcp-response tcp_response x + on-http-response http_response x + on-server-session-end server_session_end - + + Backend (be/) events: + + Event Scope T + -------------------------------------------------------- + on-frontend-http-request frontend_http_request x + on-backend-tcp-request backend_tcp_request x + on-backend-http-request backend_http_request x + on-client-session-end client_session_end - + on-server-session-start server_session_start x + on-tcp-response tcp_response x + on-http-response http_response x + on-server-session-end server_session_end - + + The backend starts its trace at on-frontend-http-request where it extracts + the span context injected by the frontend. Earlier request events + (on-client-session-start, on-frontend-tcp-request) are not needed because + the context is not yet available in the HTTP headers at that point. + + +Context propagation +------------------- + + The frontend injects context into HTTP headers in the backend_http_request + scope: + + span "HAProxy session" + inject "otel-ctx" use-headers + + The backend extracts that context in its frontend_http_request scope: + + extract "otel-ctx" use-headers + span "HAProxy session" parent "otel-ctx" root + + +Span hierarchy +-------------- + + Frontend (fe/): + + "HAProxy session" (root) + +-- "Client session" + +-- "Frontend TCP request" + +-- "Frontend HTTP request" + +-- "Backend TCP request" + +-- "Backend HTTP request" + + "HAProxy session" (root) + +-- "Server session" + +-- "TCP response" + +-- "HTTP response" + + Backend (be/): + + "HAProxy session" (root, parent: frontend's "HAProxy session") + +-- "Client session" + +-- "Frontend HTTP request" + +-- "Backend TCP request" + +-- "Backend HTTP request" + + "HAProxy session" (root) + +-- "Server session" + +-- "TCP response" + +-- "HTTP response" + + +Running the test +---------------- + +From the test/ directory: + + % ./run-fe-be.sh [/path/to/haproxy] [pidfile] + +If no arguments are given, the script looks for the haproxy binary three +directories up from the current working directory. The backend origin server +must be running on 127.0.0.1:8000. + +The script launches both HAProxy instances in the background and waits. +Press CTRL-C to stop both instances. diff --git a/addons/otel/test/README-full b/addons/otel/test/README-full new file mode 100644 index 000000000..a93d932ab --- /dev/null +++ b/addons/otel/test/README-full @@ -0,0 +1,158 @@ +Full event coverage test configuration (full/) +============================================== + +The 'full' test is a standalone single-instance configuration that exercises +every supported OTel filter event with all three signal types: traces (spans), +metrics (instruments) and logs (log-records). + +It extends the 'sa' (standalone) configuration by adding the events that 'sa' +does not cover and by attaching log-records to every scope. + + +Files +----- + + full/otel.cfg OTel filter configuration (scopes, groups, instruments) + full/haproxy.cfg HAProxy frontend/backend configuration + full/otel.yml Exporter, processor, reader and provider definitions + run-full.sh Convenience script to launch HAProxy with this config + + +Events +------ + +The table below lists every event defined in include/event.h together with the +scope that handles it and the signals produced by that scope. + + T = Trace (span) M = Metric (instrument) L = Log (log-record) + + Stream lifecycle events: + + Event Scope T M L + --------------------------------------------------------------- + on-stream-start on_stream_start x x x + on-stream-stop on_stream_stop - - x + on-idle-timeout on_idle_timeout x x x + on-backend-set on_backend_set x x x + + Request analyzer events: + + Event Scope T M L + -------------------------------------------------------------------------- + on-client-session-start client_session_start x x x + on-frontend-tcp-request frontend_tcp_request x x x + on-http-wait-request http_wait_request x - x + on-http-body-request http_body_request x - x + on-frontend-http-request frontend_http_request x x x + on-switching-rules-request switching_rules_request x - x + on-backend-tcp-request backend_tcp_request x x x + on-backend-http-request backend_http_request x - x + on-process-server-rules-request process_server_rules_request x - x + on-http-process-request http_process_request x - x + on-tcp-rdp-cookie-request tcp_rdp_cookie_request x - x + on-process-sticking-rules-request process_sticking_rules_request x - x + on-http-headers-request http_headers_request x x x + on-http-end-request http_end_request x x x + on-client-session-end client_session_end - x x + on-server-unavailable server_unavailable - - x + + Response analyzer events: + + Event Scope T M L + -------------------------------------------------------------------------- + on-server-session-start server_session_start x x x + on-tcp-response tcp_response x x x + on-http-wait-response http_wait_response x - x + on-process-store-rules-response process_store_rules_response x - x + on-http-response http_response x x x + on-http-headers-response http_headers_response x x x + on-http-end-response http_end_response x x x + on-http-reply http_reply x x x + on-server-session-end server_session_end - x x + + Additionally, the http_response-error scope fires conditionally on the + on-http-response event when the response status is outside the 100-399 range, + setting an error status on the "HTTP response" span. + + The http_response_group (http_response_1, http_response_2) and + http_after_response_group (http_after_response) are invoked via http-response + and http-after-response directives in haproxy.cfg. + + +Instruments +----------- + +Every instrument definition has at least one corresponding update. + + Instrument name Type Defined in Updated in + ------------------------------------------------------------------------------- + haproxy.sessions.active udcnt_int on_stream_start client_session_end + haproxy.fe.connections gauge_int on_stream_start http_response + idle.count cnt_int on_idle_timeout on_idle_timeout + haproxy.backend.set cnt_int on_backend_set on_backend_set + haproxy.client.session.start cnt_int client_session_start client_session_end + haproxy.tcp.request.fe cnt_int frontend_tcp_request frontend_http_request + haproxy.http.requests cnt_int frontend_http_request http_response + haproxy.http.latency hist_int frontend_http_request frontend_http_request, + http_response + haproxy.tcp.request.be cnt_int backend_tcp_request backend_http_request + haproxy.http.headers.request cnt_int http_headers_request http_end_request + haproxy.http.end.request cnt_int http_end_request client_session_end + haproxy.server.session.start cnt_int server_session_start server_session_end + haproxy.tcp.response cnt_int tcp_response http_wait_response + haproxy.http.headers.response cnt_int http_headers_response http_end_response + haproxy.http.end.response cnt_int http_end_response http_reply + haproxy.http.reply cnt_int http_reply server_session_end + + +Span hierarchy +-------------- + + Request path: + + "HAProxy session" (root) + +-- "Client session" + +-- "Frontend TCP request" + +-- "HTTP wait request" + +-- "HTTP body request" + +-- "Frontend HTTP request" [link: "HAProxy session"] + +-- "Switching rules request" + +-- "Backend TCP request" + +-- "Backend HTTP request" + +-- "Process server rules request" + +-- "HTTP process request" + +-- "TCP RDP cookie request" + +-- "Process sticking rules request" + +-- "HTTP headers request" + +-- "HTTP end request" + + Response path: + + "HAProxy session" (root) + +-- "Server session" [link: "HAProxy session", "Client session"] + +-- "TCP response" + +-- "HTTP wait response" + +-- "Process store rules response" + +-- "HTTP response" + +-- "HTTP headers response" + +-- "HTTP end response" + +-- "HTTP reply" + + Auxiliary spans: + + "HAProxy session" + +-- "Backend set" + +-- "heartbeat" (on-idle-timeout, periodic) + +-- "HAProxy response" (http_after_response_group, on error) + + +Running the test +---------------- + +From the test/ directory: + + % ./run-full.sh [/path/to/haproxy] [pidfile] + +If no arguments are given, the script looks for the haproxy binary three +directories up from the current working directory. The backend origin server +must be running on 127.0.0.1:8000. diff --git a/addons/otel/test/README-sa b/addons/otel/test/README-sa new file mode 100644 index 000000000..f5a1c1275 --- /dev/null +++ b/addons/otel/test/README-sa @@ -0,0 +1,134 @@ +Standalone test configuration (sa/) +===================================== + +The 'sa' test is a standalone single-instance configuration that +exercises most HAProxy filter events with spans, attributes, events, +links, baggage, status, metrics, logs and groups. It represents the +most comprehensive single-instance configuration and is used as the +worst-case scenario in speed tests. + +Six events are not covered by this configuration: on-backend-set, +on-http-headers-request, on-http-end-request, on-http-headers-response, +on-http-end-response and on-http-reply. The 'full' configuration +extends 'sa' with those events. + + +Files +------ + + sa/otel.cfg OTel filter configuration (scopes, groups, instruments) + sa/haproxy.cfg HAProxy frontend/backend configuration + sa/otel.yml Exporter, processor, reader and provider definitions + run-sa.sh Convenience script to launch HAProxy with this config + + +Events +------- + + T = Trace (span) M = Metric (instrument) L = Log (log-record) + + Stream lifecycle events: + + Event Scope T M L + --------------------------------------------------------------- + on-stream-start on_stream_start x x x + on-stream-stop on_stream_stop - - - + on-idle-timeout on_idle_timeout x x x + + Request analyzer events: + + Event Scope T M L + -------------------------------------------------------------------------- + on-client-session-start client_session_start x - - + on-frontend-tcp-request frontend_tcp_request x - - + on-http-wait-request http_wait_request x - - + on-http-body-request http_body_request x - - + on-frontend-http-request frontend_http_request x x x + on-switching-rules-request switching_rules_request x - - + on-backend-tcp-request backend_tcp_request x - - + on-backend-http-request backend_http_request x - - + on-process-server-rules-request process_server_rules_request x - - + on-http-process-request http_process_request x - - + on-tcp-rdp-cookie-request tcp_rdp_cookie_request x - - + on-process-sticking-rules-request process_sticking_rules_request x - - + on-client-session-end client_session_end - x - + on-server-unavailable server_unavailable - - - + + Response analyzer events: + + Event Scope T M L + -------------------------------------------------------------------------- + on-server-session-start server_session_start x - - + on-tcp-response tcp_response x - - + on-http-wait-response http_wait_response x - - + on-process-store-rules-response process_store_rules_response x - - + on-http-response http_response x x - + on-server-session-end server_session_end - - - + + Additionally, the http_response-error scope fires conditionally on the + on-http-response event when the response status is outside the 100-399 + range, setting an error status on the "HTTP response" span. + + The http_response_group (http_response_1, http_response_2) and + http_after_response_group (http_after_response) are invoked via + http-response and http-after-response directives in haproxy.cfg. + + +Instruments +------------ + + Instrument name Type Defined in Updated in + -------------------------------------------------------------------------- + haproxy.sessions.active udcnt_int on_stream_start client_session_end + haproxy.fe.connections gauge_int on_stream_start http_response + idle.count cnt_int on_idle_timeout on_idle_timeout + haproxy.http.requests cnt_int frontend_http_request http_response + haproxy.http.latency hist_int frontend_http_request frontend_http_request, + http_response + + +Span hierarchy +--------------- + + Request path: + + "HAProxy session" (root) + +-- "Client session" + +-- "Frontend TCP request" + +-- "HTTP wait request" + +-- "HTTP body request" + +-- "Frontend HTTP request" [link: "HAProxy session"] + +-- "Switching rules request" + +-- "Backend TCP request" + +-- "Backend HTTP request" + +-- "Process server rules request" + +-- "HTTP process request" + +-- "TCP RDP cookie request" + +-- "Process sticking rules request" + + Response path: + + "HAProxy session" (root) + +-- "Server session" [link: "HAProxy session", "Client session"] + +-- "TCP response" + +-- "HTTP wait response" + +-- "Process store rules response" + +-- "HTTP response" + + Auxiliary spans: + + "HAProxy session" + +-- "heartbeat" (on-idle-timeout, periodic) + +-- "HAProxy response" (http_after_response_group, on error) + + +Running the test +----------------- + +From the test/ directory: + + % ./run-sa.sh [/path/to/haproxy] [pidfile] + +If no arguments are given, the script looks for the haproxy binary three +directories up from the current working directory. The backend origin +server must be running on 127.0.0.1:8000.