instrument_client (instrument v0.6.1)
View SourceGeneric client span utilities for tracing client operations.
This module provides reusable utilities for creating client-kind spans for any type of client operation: databases, HTTP clients, message queues, RPC calls, etc.
Features
- Generic client span helpers with semantic convention support - Text sanitization (SQL, URLs, messages) - Trace context comment injection (SQLCommenter-style) - Resource pool monitoring helpers - Attribute builders following OTel conventions
Example Usage
%% Database query
instrument_client:with_client_span(postgresql, <<"SELECT">>, #{
target => <<"users">>,
statement => <<"SELECT * FROM users WHERE id = $1">>,
sanitize => true,
attributes => #{<<"db.name">> => <<"mydb">>}
}, fun() ->
epgsql:equery(Conn, SQL, Params)
end).
%% HTTP client call
instrument_client:with_client_span(http, <<"GET">>, #{
target => <<"/api/users">>,
attributes => #{<<"http.url">> => URL}
}, fun() ->
httpc:request(URL)
end).
%% Message queue publish
instrument_client:with_client_span(kafka, <<"publish">>, #{
target => <<"orders-topic">>,
attributes => #{<<"messaging.destination">> => <<"orders-topic">>}
}, fun() ->
brod:produce(Client, Topic, Key, Value)
end).
Summary
Functions
Builds standard attributes from client options.
Generates a span name following semantic conventions. Format: "system operation" or "system operation target"
Formats the current trace context as a comment string.
Formats trace context with options.
Injects trace context as a comment into text. Default format is SQL comment: /* traceparent='...' */
Injects trace context with custom format.
Creates a span for pool resource acquisition. The returned span should be ended AFTER the pool operation completes, not immediately after acquisition. Use pool_release_span/1 with the returned span to properly end it.
Records pool resource release and ends the pool span. When called with a span record, adds release event to the pool span and ends it. When called with just a pool name (legacy), adds release event to current span.
Sanitizes text by replacing common sensitive patterns. Removes string literals, numbers, and common sensitive patterns.
Sanitizes text with custom options. Patterns are matched and replaced with the placeholder.
Sets client attributes on the current span.
Sets response-related attributes on the current span. Accepts: rows_returned, rows_affected, response_size, status_code, etc.
Starts a client span without executing a function. Remember to call instrument_tracer:end_span/1 when done.
Starts a client span with options.
Executes a function within a client span. The span name is generated from system and operation.
Executes a function within a client span with options.
Executes a function with pool acquire/release events in a wrapper span. Creates a single span that contains both pool.acquire and pool.release events, properly capturing the full pool operation lifecycle.
Types
Functions
-spec build_attributes(client_opts()) -> map().
Builds standard attributes from client options.
-spec client_span_name(client_system(), operation()) -> binary().
Generates a span name following semantic conventions. Format: "system operation" or "system operation target"
-spec client_span_name(client_system(), operation(), client_opts()) -> binary().
-spec format_trace_comment() -> binary().
Formats the current trace context as a comment string.
-spec format_trace_comment(comment_opts()) -> binary().
Formats trace context with options.
Injects trace context as a comment into text. Default format is SQL comment: /* traceparent='...' */
-spec inject_trace_comment(binary(), comment_opts()) -> binary().
Injects trace context with custom format.
Options: - format: sql | url | custom (default: sql) - prefix/suffix: Custom delimiters for format => custom - include_span_id: Include span ID (default: false) - include_sampled: Include sampled flag (default: false)
-spec pool_acquire_span(binary(), client_system()) -> #span{name :: binary(), ctx :: #span_ctx{trace_id :: <<_:128>> | undefined, span_id :: <<_:64>> | undefined, trace_flags :: 0 | 1, trace_state :: [{binary(), binary()}], is_remote :: boolean()}, parent_ctx :: #span_ctx{trace_id :: <<_:128>> | undefined, span_id :: <<_:64>> | undefined, trace_flags :: 0 | 1, trace_state :: [{binary(), binary()}], is_remote :: boolean()} | undefined, tracer :: #tracer{name :: binary(), version :: binary() | undefined, schema_url :: binary() | undefined, resource :: #resource{attributes :: map(), schema_url :: binary() | undefined} | undefined} | undefined, kind :: client | server | producer | consumer | internal, start_time :: integer(), end_time :: integer() | undefined, attributes :: map(), events :: [#span_event{name :: binary(), timestamp :: integer(), attributes :: map()}], links :: [#span_link{ctx :: #span_ctx{trace_id :: <<_:128>> | undefined, span_id :: <<_:64>> | undefined, trace_flags :: 0 | 1, trace_state :: [{binary(), binary()}], is_remote :: boolean()}, attributes :: map()}], status :: unset | ok | {error, binary()}, is_recording :: boolean(), dropped_attributes_count :: non_neg_integer(), dropped_events_count :: non_neg_integer(), dropped_links_count :: non_neg_integer()}.
Creates a span for pool resource acquisition. The returned span should be ended AFTER the pool operation completes, not immediately after acquisition. Use pool_release_span/1 with the returned span to properly end it.
-spec pool_release_span(binary() | #span{name :: binary(), ctx :: #span_ctx{trace_id :: <<_:128>> | undefined, span_id :: <<_:64>> | undefined, trace_flags :: 0 | 1, trace_state :: [{binary(), binary()}], is_remote :: boolean()}, parent_ctx :: #span_ctx{trace_id :: <<_:128>> | undefined, span_id :: <<_:64>> | undefined, trace_flags :: 0 | 1, trace_state :: [{binary(), binary()}], is_remote :: boolean()} | undefined, tracer :: #tracer{name :: binary(), version :: binary() | undefined, schema_url :: binary() | undefined, resource :: #resource{attributes :: map(), schema_url :: binary() | undefined} | undefined} | undefined, kind :: client | server | producer | consumer | internal, start_time :: integer(), end_time :: integer() | undefined, attributes :: map(), events :: [#span_event{name :: binary(), timestamp :: integer(), attributes :: map()}], links :: [#span_link{ctx :: #span_ctx{trace_id :: <<_:128>> | undefined, span_id :: <<_:64>> | undefined, trace_flags :: 0 | 1, trace_state :: [{binary(), binary()}], is_remote :: boolean()}, attributes :: map()}], status :: unset | ok | {error, binary()}, is_recording :: boolean(), dropped_attributes_count :: non_neg_integer(), dropped_events_count :: non_neg_integer(), dropped_links_count :: non_neg_integer()}) -> ok.
Records pool resource release and ends the pool span. When called with a span record, adds release event to the pool span and ends it. When called with just a pool name (legacy), adds release event to current span.
Sanitizes text by replacing common sensitive patterns. Removes string literals, numbers, and common sensitive patterns.
-spec sanitize_text(binary(), sanitize_opts()) -> binary().
Sanitizes text with custom options. Patterns are matched and replaced with the placeholder.
Options: - patterns: List of regex patterns to replace (default: SQL literals and numbers) - placeholder: Replacement text (default: <<"?">>) - preserve: Patterns to preserve (e.g., <<"\\$\\d+">> for PostgreSQL placeholders)
-spec set_client_attributes(client_opts()) -> ok.
Sets client attributes on the current span.
-spec set_response_attributes(map()) -> ok.
Sets response-related attributes on the current span. Accepts: rows_returned, rows_affected, response_size, status_code, etc.
-spec start_client_span(client_system(), operation()) -> #span{name :: binary(), ctx :: #span_ctx{trace_id :: <<_:128>> | undefined, span_id :: <<_:64>> | undefined, trace_flags :: 0 | 1, trace_state :: [{binary(), binary()}], is_remote :: boolean()}, parent_ctx :: #span_ctx{trace_id :: <<_:128>> | undefined, span_id :: <<_:64>> | undefined, trace_flags :: 0 | 1, trace_state :: [{binary(), binary()}], is_remote :: boolean()} | undefined, tracer :: #tracer{name :: binary(), version :: binary() | undefined, schema_url :: binary() | undefined, resource :: #resource{attributes :: map(), schema_url :: binary() | undefined} | undefined} | undefined, kind :: client | server | producer | consumer | internal, start_time :: integer(), end_time :: integer() | undefined, attributes :: map(), events :: [#span_event{name :: binary(), timestamp :: integer(), attributes :: map()}], links :: [#span_link{ctx :: #span_ctx{trace_id :: <<_:128>> | undefined, span_id :: <<_:64>> | undefined, trace_flags :: 0 | 1, trace_state :: [{binary(), binary()}], is_remote :: boolean()}, attributes :: map()}], status :: unset | ok | {error, binary()}, is_recording :: boolean(), dropped_attributes_count :: non_neg_integer(), dropped_events_count :: non_neg_integer(), dropped_links_count :: non_neg_integer()}.
Starts a client span without executing a function. Remember to call instrument_tracer:end_span/1 when done.
-spec start_client_span(client_system(), operation(), client_opts()) -> #span{name :: binary(), ctx :: #span_ctx{trace_id :: <<_:128>> | undefined, span_id :: <<_:64>> | undefined, trace_flags :: 0 | 1, trace_state :: [{binary(), binary()}], is_remote :: boolean()}, parent_ctx :: #span_ctx{trace_id :: <<_:128>> | undefined, span_id :: <<_:64>> | undefined, trace_flags :: 0 | 1, trace_state :: [{binary(), binary()}], is_remote :: boolean()} | undefined, tracer :: #tracer{name :: binary(), version :: binary() | undefined, schema_url :: binary() | undefined, resource :: #resource{attributes :: map(), schema_url :: binary() | undefined} | undefined} | undefined, kind :: client | server | producer | consumer | internal, start_time :: integer(), end_time :: integer() | undefined, attributes :: map(), events :: [#span_event{name :: binary(), timestamp :: integer(), attributes :: map()}], links :: [#span_link{ctx :: #span_ctx{trace_id :: <<_:128>> | undefined, span_id :: <<_:64>> | undefined, trace_flags :: 0 | 1, trace_state :: [{binary(), binary()}], is_remote :: boolean()}, attributes :: map()}], status :: unset | ok | {error, binary()}, is_recording :: boolean(), dropped_attributes_count :: non_neg_integer(), dropped_events_count :: non_neg_integer(), dropped_links_count :: non_neg_integer()}.
Starts a client span with options.
-spec with_client_span(client_system(), operation(), fun(() -> Result)) -> Result when Result :: term().
Executes a function within a client span. The span name is generated from system and operation.
-spec with_client_span(client_system(), operation(), client_opts(), fun(() -> Result)) -> Result when Result :: term().
Executes a function within a client span with options.
-spec with_pool_span(binary(), client_system(), fun(() -> Result)) -> Result when Result :: term().
Executes a function with pool acquire/release events in a wrapper span. Creates a single span that contains both pool.acquire and pool.release events, properly capturing the full pool operation lifecycle.