Instrument Features

View Source

Overview

Instrument is an Erlang library providing high-performance metrics and tracing capabilities with OpenTelemetry compatibility.

Feature Support Matrix

Metrics

FeatureStatusDescription
CounterStableMonotonically increasing cumulative metric
GaugeStablePoint-in-time measurement
HistogramStableDistribution of values with configurable buckets
UpDownCounterStableCounter that can increase or decrease
Observable CounterStableAsync counter with callback
Observable GaugeStableAsync gauge with callback
Observable UpDownCounterStableAsync up/down counter with callback
Metric ViewsStableTransform and filter metrics during export
Attribute SupportStableKey-value dimensions for metrics

Tracing

FeatureStatusDescription
Span CreationStableCreate and manage trace spans
Context PropagationStableW3C TraceContext, B3, B3Multi propagation
BaggageStableW3C Baggage propagation
SamplersStableAlwaysOn, AlwaysOff, Probability, ParentBased
Span ProcessorsStableSimple and Batch processors
Span AttributesStableIndexable key-value metadata on spans
Span EventsStableTimestamped events within spans
Span LinksStableConnect causally related spans

Export

FeatureStatusDescription
Console ExporterStableExport to stdout for debugging
OTLP ExporterStableExport via OTLP/HTTP (protobuf)
File ExporterStableExport logs to file
Prometheus FormatStableCompatible with Prometheus scraping

Context

FeatureStatusDescription
Process Dictionary ContextStableContext storage per process
Context ValuesStableGet/set arbitrary context values
Context PropagationStableInject/extract across service boundaries

OpenTelemetry Specification Compliance

Tracing API (v1.0)

ComponentComplianceNotes
TracerProviderPartialSingle global tracer
TracerFullStart/end spans with attributes
SpanFullName, attributes, events, links, status
SpanContextFullTraceId, SpanId, TraceFlags, TraceState
SpanKindFullInternal, Server, Client, Producer, Consumer
SpanProcessorFullSimple and Batch implementations
SamplerFullAlwaysOn, AlwaysOff, TraceIdRatio, ParentBased

Metrics API (v1.0)

ComponentComplianceNotes
MeterProviderPartialSingle global meter provider
MeterFullCreate instruments with options
CounterFullMonotonic increment only
UpDownCounterFullBidirectional counter
HistogramFullConfigurable bucket boundaries
GaugeFullPoint-in-time values
Observable InstrumentsFullCallback-based async instruments
AttributesFullKey-value dimensions
ViewsFullTransform metrics during collection

Context and Propagation (v1.0)

ComponentComplianceNotes
ContextFullProcess dictionary based
Propagator APIFullInject/extract interface
W3C TraceContextFulltraceparent and tracestate headers
W3C BaggageFullbaggage header
B3 Single HeaderFullZipkin b3 header format
B3 Multi HeaderFullX-B3-* headers format
Composite PropagatorFullChain multiple propagators

Resource (v1.0)

ComponentComplianceNotes
ResourceFullService name, version, etc.
Resource DetectorsFullAuto-detect environment
Resource MergingFullCombine multiple resource sources

API Reference Summary

Metrics API

%% Create instruments
Meter = instrument_meter:get_meter(<<"service_name">>).
Counter = instrument_meter:create_counter(Meter, <<"requests_total">>, #{
  description => <<"Total requests">>,
  unit => <<"1">>
}).

%% Record values
instrument_meter:add(Counter, 1).
instrument_meter:add(Counter, 1, #{method => <<"GET">>}).

Tracing API

%% Create spans (with_span is preferred)
instrument_tracer:with_span(<<"operation_name">>, fun() ->
    instrument_tracer:set_attributes(#{key => value}),
    instrument_tracer:add_event(<<"event_name">>, #{}),
    do_work()
end).

%% Or manual span management
Span = instrument_tracer:start_span(<<"operation_name">>),
instrument_tracer:set_attributes(#{key => value}),
instrument_tracer:add_event(<<"event_name">>, #{}),
instrument_tracer:end_span(Span).

Context API

%% Propagation (W3C TraceContext is default)
Carrier = instrument_propagator:inject(Context, #{}).
Context = instrument_propagator:extract(Carrier).

%% Configure B3 propagation (Zipkin compatibility)
instrument_propagator:set_propagators([instrument_propagator_b3]).

%% Or B3 multi-header format
instrument_propagator:set_propagators([instrument_propagator_b3_multi]).

Span Attributes (Indexable Metadata)

Span attributes are key-value pairs that provide searchable context:

instrument_tracer:with_span(<<"process_order">>, fun() ->
    %% Set indexable attributes - queryable in backends like Jaeger, Tempo, etc.
    instrument_tracer:set_attributes(#{
        %% String attributes
        <<"order.id">> => <<"ORD-12345">>,
        <<"customer.tier">> => <<"premium">>,

        %% Numeric attributes (for aggregation/filtering)
        <<"order.total">> => 149.99,
        <<"order.item_count">> => 3,

        %% Boolean attributes
        <<"order.express_shipping">> => true
    }),

    %% These attributes enable:
    %% - Filtering traces by customer.tier = "premium"
    %% - Aggregating latencies by order.item_count
    %% - Alerting when order.total > threshold
    process(Order)
end).

Legacy API

%% Direct counter/gauge/histogram
Counter = instrument_metric:new_counter(name, <<"help">>).
instrument_metric:inc_counter(Counter).

%% Vector metrics (labeled)
instrument_metric:new_counter_vec(name, <<"help">>, [method, status]).
instrument_metric:inc_counter_vec(name, [<<"GET">>, <<"200">>]).

Configuration Options

Application Environment

%% In sys.config or application:set_env/3
[
  {instrument, [
    %% Resource configuration
    {resource, #{
      service_name => <<"my_service">>,
      service_version => <<"1.0.0">>
    }},

    %% Sampler configuration
    {sampler, {instrument_sampler_probability, #{ratio => 0.1}}},

    %% Span processor configuration
    {span_processor, {instrument_span_processor_batch, #{
      max_queue_size => 2048,
      schedule_delay_millis => 5000,
      max_export_batch_size => 512
    }}},

    %% Exporter configuration
    {span_exporter, {instrument_exporter_otlp, #{
      endpoint => <<"http://localhost:4318/v1/traces">>
    }}},

    {metrics_exporter, {instrument_metrics_exporter_otlp, #{
      endpoint => <<"http://localhost:4318/v1/metrics">>
    }}}
  ]}
].

Environment Variables

VariableDescriptionDefault
OTEL_SERVICE_NAMEService name for resourceunknown_service
OTEL_RESOURCE_ATTRIBUTESAdditional resource attributes-
OTEL_TRACES_SAMPLERSampler typeparentbased_always_on
OTEL_TRACES_SAMPLER_ARGSampler argument (e.g., ratio)-
OTEL_PROPAGATORSPropagators: tracecontext, baggage, b3, b3multitracecontext,baggage
OTEL_EXPORTER_OTLP_ENDPOINTOTLP endpoint URLhttp://localhost:4318
OTEL_EXPORTER_OTLP_HEADERSAdditional headers-

Programmatic Configuration

%% Set sampler at runtime
instrument_sampler:set_sampler(instrument_sampler_probability, #{ratio => 0.5}).

%% Register span processor
instrument_span_processor:register(instrument_span_processor_batch, #{
  exporter => instrument_exporter_otlp,
  exporter_config => #{endpoint => <<"http://collector:4318/v1/traces">>}
}).

%% Register propagators
instrument_propagator:set_propagators([
  instrument_propagator_tracecontext,
  instrument_propagator_baggage
]).

%% Register metric views
instrument_metric_view:register(#metric_view{
  instrument_name => <<"http_request_duration">>,
  name => <<"http.server.duration">>,
  attribute_keys => [<<"http.method">>, <<"http.status_code">>]
}).

Performance Characteristics

  • NIF-based atomic operations for counters and gauges
  • Lock-free concurrent access to metrics
  • Efficient histogram bucket updates with linear search (optimized for typical 10-15 buckets)
  • Batch span processing to reduce export overhead
  • Process dictionary context for zero-overhead context access

Dependencies

  • Erlang/OTP 24+
  • crypto application for ID generation
  • Optional: jsx or jiffy for JSON encoding (OTLP export)