HelidonHelidon4.5.0

OpenTelemetry

Helidon OpenTelemetry Support
Helidon SE support for OpenTelemetry configuration and semantic conventions as described below is currently a preview feature. We intend to support it going forward, but we might change its external API and behavior in backward-incompatible ways across dot releases.

Overview

Helidon SE supports OpenTelemetry in several important ways:

  • Implements the neutral Helidon tracing API using OpenTelemetry
  • Allows users to assign OpenTelemetry settings as follows:
    • Declaratively, using Helidon config under the top-level telemetry config key
    • Programmatically, using the OpenTelemetry SDK API and the Helidon OpenTelemetry API
  • Conforms to the OpenTelemetry semantic conventions for automatically-created spans and metrics for HTTP requests
  • Allows publishing Helidon metrics to backend systems using OTLP.

OpenTelemetry models observability as a set of signals.

Each signal—for example metrics, tracing, and logging—is an origin of monitoring data, and each has configurable settings which control its behavior.

Helidon’s config support for OpenTelemetry has certain config attributes which apply to OpenTelemetry as a whole, others which pertain to individual signals, and still more which describe lower-level elements within a signal.

The Helidon OpenTelemetry configuration format, the Helidon OpenTelemetry API, and this documentation all follow this hierarchy:

This document describes how to configure each level in the hierarchy and covers general topics related to Helidon’s support of OpenTelemetry.

API

There are two APIs that might be useful to developers working with OpenTelemetry:

  • The Helidon OpenTelemetry API - useful for mapping configuration sources to Helidon builders and, ultimately, OpenTelemetry objects.
  • The OpenTelemetry API - useful for creating OpenTelemetry objects apart from Helidon configuration sources.

The types in the Helidon OpenTelemetry API correspond closely to the configuration structures described in later sections of this document. Application code can use Helidon OpenTelemetry builders to prepare and construct each of the configurable entities to ultimately prepare an OpenTelemetry instance set up according to the application’s needs.

That said, application code can equally well use the OpenTelemetry API and its builders to prepare the OpenTelemetry instance.

Applications could even use both APIs together, reading configuration to construct a Helidon builder and then adding to that builder OpenTelemetry objects created separately using the OpenTelemetry API.

The Helidon OpenTelemetry API Javadoc page lists the various types developers can use to prepare OpenTelemetry objects programmatically. As a starting point, the OpenTelemetryConfig interface and its Builder represents the top-level configuration for OpenTelemetry. Their Javadoc contains links to other types that compose the top-level object, and so on.

Later sections in this document also describe the configuration settings available.

The OpenTelemetry SDK documentation explains its API.

Many applications do not need to use either the Helidon OpenTelemetry API or the OpenTelemetry API directly. They can instead rely completely on declarative Helidon configuration of OpenTelemetry.

Global Instance

Typically, an application uses the same OpenTelemetry instance throughout its execution. OpenTelemetry offers a global OpenTelemetry instance to make it easy for application code to set and obtain the global instance.

Similarly, the Helidon tracing API has a global Tracer.

In most cases, an application that prepares OpenTelemetry programmatically should initialize both of those by including code as shown in the following example.

Setting the global OpenTelemetry and Tracer instances in Helidon:

import java.util.Map;
import io.helidon.telemetry.otelconfig.HelidonOpenTelemetry;

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.context.Scope;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;

// Application code using the OpenTelemetry API or the Helidon OpenTelemetry API or both.
OpenTelemetry customOpenTelemetry = prepareOpenTelemetry();

// App code to build any tags to be applied to every span.
Map<String, String> tags = prepareTags();

HelidonOpenTelemetry.global(customOpenTelemetry, "your-service-name", tags);

Assigning the Global Instance

Using Helidon to set the global OpenTelemetry instance has these effects:

  • Assigns the instance as the OpenTelemetry global instance.
  • Creates a Helidon Tracer using the OpenTelemetry instance and makes that the Helidon global Tracer.
Helidon is deprecating its use of "global" Helidon objects in favor of retrieving the correct instance from the Helidon service registry. Applications should migrate toward using, for example, Services.get(Tracer.class) instead of Tracer.global().

Maven Coordinates

To enable various aspects of OpenTelemetry Support add one or more of the following dependencies to your project’s pom.xml (see Managing Dependencies).

Helidon Tracing provider:

pom.xml
<dependency>
  <groupId>io.helidon.tracing.providers</groupId>
  <artifactId>helidon-tracing-providers-opentelemetry</artifactId>
</dependency>

Helidon Config and programmatic builder support:

pom.xml
<dependency>
  <groupId>io.helidon.telemetry</groupId>
  <artifactId>helidon-telemetry-opentelemetry-config</artifactId>
</dependency>

Helidon WebServer OpenTelemetry Tracing semantics:

pom.xml
<dependency>
  <groupId>io.helidon.webserver.observe</groupId>
  <artifactId>helidon-webserver-observe-telemetry-tracing</artifactId>
  <scope>runtime</scope>
</dependency>

Helidon WebServer OpenTelemetry Metrics semantics:

pom.xml
<dependency>
  <groupId>io.helidon.webserver.observe</groupId>
  <artifactId>helidon-webserver-observe-telemetry-metrics</artifactId>
  <scope>runtime</scope>
</dependency>

WebClient Support

Helidon supports the OpenTelemetry semantic conventions for outgoing traffic which uses the Helidon WebClient. See the Helidon WebClient documentation.

Additional Dependencies

Most applications need to declare other runtime dependencies on OpenTelemetry artifacts because the configuration specifies—or the application code uses—particular OpenTelemetry types packaged in other artifacts.

For example, OpenTelemetry exporters are packaged individually or as related groups. See this section below for some specific dependencies to consider adding for particular exporters.

These exporters transmit telemetry data using a different protocol. (See this OpenTelemetry page.)

Configuration options

KeyTypeDefaultDescription
enabledBooleantrueWhether the OpenTelemetry support is enabled
globalBooleantrueWhether the io.opentelemetry.api.OpenTelemetry instance created from this configuration should be made the global one
propagatorsList<String>OpenTelemetry io.opentelemetry.context.propagation.TextMapPropagator instances added explicitly by the app
serviceStringService name used in sending telemetry data to the collector
signalsConfiguration for signals

Notes:

  • OpenTelemetry uses default propagators of tracecontext and baggage. (See the otel.propagators property in this OpenTelemetry guide.)
  • Setting global to true has the effect described in the section about global instances.

Signal Attributes

Attributes are key/value pairs that OpenTelemetry attaches to each transmission of a signal.

OpenTelemetry supports attributes of type String, long, double, and boolean.

The Helidon configuration structure groups attributes by type so Helidon can indicate precisely to OpenTelemetry what type you intend for each attribute.

Configuration options

You can add attributes to the configuration for any of the signals under the signal’s attributes section.

KeyTypeDescription
longsMap<String, Long>Long attributes
stringsMap<String, String>String attributes
doublesMap<String, Double>Double attributes
booleansMap<String, Boolean>Boolean attributes

The following example shows attribute settings for the tracing signal.

Configuration Example

telemetry:
  service: my-helidon-service
  tracing:
    attributes:
      strings:
        attr1: 12
        attr5: "any old thing"
        attr7: something
      longs:
        attr2: 12
      doubles:
        attr3: 24.5
        attr6: 12
      booleans:
        attr4: true

Processors & Readers

Two types of processors and readers are provided:

  • simple: sends observations upon receive
  • batch: groups observations into batches

In the table below only the type and exporters setting apply to simple processors; the other settings are for batch processors.

Configuration options

KeyTypeDescription
schedule-delayDurationDelay between consecutive exports
max-export-batch-sizeIntegerMaximum number of items batched for export together
typeProcessorTypeProcessor type
max-queue-sizeIntegerMaximum number of items retained before discarding excess unexported ones
timeoutDurationMaximum time an export can run before being cancelled
exportersList<String>Name(s) of the exporter(s) this processor should use; specifying no names uses all configured exporters (or if no exporters are configured, the default OpenTelemetry exporter(s))

Exporters

Exporter objects in OpenTelemetry are specific to both how they transmit telemetry data and what signal they work with. Even so, many exporter settings are very similar across different signals. This section describes the behavior and configuration that is common among exporters. Refer to the sections below that describe each signal to see what additional exporter settings, if any, each signal adds.

Helidon configuration supports several of the most popular exporters, discussed below.

Configuration options

KeyTypeDefaultDescription
connect-timeoutDurationConnection timeout
headersMap<String, String>Headers added to each export message
endpointURIEndpoint of the collector to which the exporter should transmit
memory-modeMemoryModeMemory mode
protocolStringDEFAULTExporter protocol type
internal-telemetry-versionInternalTelemetryVersionSelf-monitoring telemetry OpenTelemetry should collect
certificateResourceTrusted certificates
client.keyResourceTLS client key
client.certificateResourceTLS certificate
compressionCompressionTypeCompression the exporter uses
retry-policyRetryPolicyConfigRetry policy
timeoutDurationExporter timeout

Common Configuration for OTLP exporters:

SettingProtocolOpenTelemetry default
compressionnone
endpointgrpchttp://localhost:4317
http/protohttp://localhost:4318
protocolgrpc
retry-policynone
timeout10 seconds

OTLP Retry Policy

You can control how each exporter retries if a transmission to a backend fails.

Configuration options

KeyTypeDescription
max-backoffDurationMaximum backoff time
initial-backoffDurationInitial backoff time
max-backoff-multiplierDoubleMaximum backoff multiplier
max-attemptsIntegerMaximum number of retry attempts

OpenTelemetry also supports a Zipkin exporter which it has recently deprecated.

Zipkin Exporter

Configuration options

KeyTypeDescription
endpointURICollector endpoint to which this exporter should transmit
compressionCompressionTypeCompression type
encoderSpanBytesEncoderEncoder type
timeoutDurationExporter timeout

Configuration for Zipkin exporters

The OpenTelemetry documentation describes the defaults; see the "Properties for Zipkin span exporters" section there.

OpenTelemetry defaults for Zipkin exporters:

SettingOpenTelemetry default value
compressionnone
encoderJSON_V2
endpointhttp://localhost:9411/api/v2/spans
timeout10 seconds

OpenTelemetry provides other exporters, often used for debugging:

  • console
    Writes telemetry data at the INFO level using the java.util.logging.Logger for io.opentelemetry.exporter.logging.Logging{signal}Expoerter
  • logging-otlp
    Writes telemetry data in JSON format to the logger for the particular OpenTelemetry implementation class (e.g., OtlpJsonLoggingMetricExporter).

The console and logging-otlp have no configuration that is common across all signals.

You need to add dependencies to your project for the exporters your application uses, even ones supported by Helidon config.

The table below describes the exporter types that Helidon configuration supports and what dependency your project needs to support them.

If you need to use an exporter that is not in the table:

  • Add a dependency on the OpenTelemetry artifact that contains that exporter type.
  • Add application code that prepares the exporter instance.
  • Prepare the Helidon OpenTelemetry builders programmatically and add your exporter instance to the builder.

In the table below, the Maven artifacts are all in the io.opentelemetry group.

Exporter typeOpenTelemetry Java TypeArtifact ID to add - seealso the OpenTelemetry documentation
otlpOtlpGrpc{signal}Exporteropentelemetry-exporter-otlp
OtlpHttp{signal}Exporter
zipkinZipkinSpanExporteropentelemetry-exporter-zipkin
consoleLogging{signal}Exporteropentelemetry-exporter-logging
logging_otlpOtlpJsonLogging{signal}ExporterSystemOutLogRecordExporter

Assigning Exporters

In configuration, you link processors and readers with the exporters you want each to use as follows:

  • For clarity, name each exporter if you have more than one.
  • Optionally specify for each processor or reader the names of the exporters it should use.
    If you omit the exporter names for a processor or reader, Helidon associates it with all configured exporters. If you configure no exporters explicitly, Helidon associates the OpenTelemetry default exporter with the processor or reader.

The following examples show increasingly-complicated scenarios using tracing as the signal:

  • Default
  • Minimal configuration
  • Maximum flexibility

For many applications the default and minimal scenarios work well.

Default

This scenario includes no configuration at all for either processors or exporters.

OpenTelemetry uses its default processor (batch) with its default exporter (otlp using grpc). |

telemetry:
  service: "inventory"
  tracing:
    sampler: "always_off"

Minimal configuration

The user configures at most one processor and at most one exporter.

The single processor uses the single exporter.

No exporter name is declared or referenced.

telemetry:
  service: "inventory"
  tracing:
    sampler: "always_off"
    exporters:
      - type: zipkin
        compression: gzip
    processors:
      - type: batch
        max-queue-size: 50

Maximum flexibility

The user configures possibly multiple processors and possibly multiple named exporters. Each processor’s configuration lists the names of the exporters it should use; no names means all exporters.

The first processor (type batch) uses both exporters because it does not specify any exporter names. The second processor uses only the alternate-otlp exporter.|

telemetry:
  service: "inventory"
  tracing:
    sampler: "always_off"
    exporters:
      - type: zipkin
        compression: gzip
        name: "compressed-zipkin"
      - endpoint: "http://collect.com:4317"
        name: "alternate-otlp""
    processors:
      - type: batch
        max-queue-size: 50
      - type: simple
        exporters: ["alternate-otlp"]

Tracing Configuration

The settings under signals.tracing prepare an OpenTelemetry TracerProvider. When your application uses the Helidon tracing API to obtain a Tracer, Helidon uses the TracerProvider prepared from this config to create the tracer.

The next table describes the OpenTelemetry tracing settings.

Configuration options

KeyTypeDescription
span-limitsSpanLimitsConfigTracing span limits
attributesTypedAttributesName/value pairs passed to OpenTelemetry
processorsList<ProcessorConfig>Settings for span processors
exportersMap<String, SpanExporter>Span exporters
samplerSamplerConfigTracing sampler

OpenTelemetry applies the defaults described in the next table.

SettingOpenTelemetry default (and OpenTelemetry doc link)
exportersotlp with grpc protocol - see "Properties: exporters, otel.traces.exporter property"
processorsbatch with defaults - see "Properties for batch span processor(s)"
samplerparentbased_always_on - see "Properties for sampler"
span-limitsSee tracing "Properties for span limits"

Span Sampler

OpenTelemetry offers different ways of sampling data—deciding which tracing spans tp capture and send to the backend. The OpenTelemetry documentation describes sampling in more detail.

Helidon configuration supports the sampler implementations that reside in the opentelemetry-sdk as listed in the table below. Other samplers are in other components. If you need to use one of those:

  • Add the relevant OpenTelemetry dependency to your project.
  • Instantiate the span sample you need.
  • Prepare the sampler and the OpenTelemetry-related builders programmatically and use your sampler to assign the sampler the OpenTelemetryTracer.Builder should use.

Configuration options

KeyTypeDefaultDescription
paramDoubleSampler parameter
typeSamplerTypeDEFAULTSampler type

Span Limits

OpenTelemetry allows you to constrain certain aspects of the data it gathers in tracing spans. By assigning the settings in the table below, you can apply the span limits you want.

Configuration options

KeyTypeDescription
max-attribute-value-lengthIntegerMaximum attribute value length
max-eventsIntegerMaximum number of events
max-attributes-per-eventIntegerMaximum number of attributes per event
max-attributesIntegerMaximum number of attributes
max-attributes-per-linkIntegerMaximum number of attributes per link
max-linksIntegerMaximum number of links

The OpenTelemetry documentation describes the defaults; see the "Properties for span limits" section there.

OpenTelemetry defaults for span limits:

SettingOpenTelemetry Default
max-attribute-value-lengthno limit
max-attributes128
max-attributes-per-event128
max-events128
max-links128

Metrics Configuration

The settings under signals.metrics prepare an OpenTelemetry MeterProvider. If your code uses the OpenTelemetry API to obtain an OpenTelemetry meter, meter provider, or meter builder, OpenTelemetry uses the MeterProvider prepared from this configuration.

The sections below describe Helidon config settings that correspond very directly to OpenTelemetry builders for the relevant OpenTelemetry type. Refer to the relevant OpenTelemetry documentation or Javadoc to understand the effect each setting has.

Configuration options

KeyTypeDescription
readersList<MetricReaderConfig>Settings for metric readers
attributesTypedAttributesName/value pairs passed to OpenTelemetry
viewsList<ViewRegistrationConfig>Metric view information, configurable using io.helidon.telemetry.otelconfig.ViewRegistrationConfig
exportersMap<String, MetricExporter>Metric exporter configurations, configurable using io.helidon.telemetry.otelconfig.MetricExporterConfig

OpenTelemetry applies the defaults described in the next table.

SettingOpenTelemetry default (and OpenTelemetry doc link)
exportersotlp with grpc protocol - see that web page’s "Properties: exporters, otel.metrics.exporter property"] section.
readersPeriodicMetricReader with an interval of one minute

The following example illustrates some of the ways you can configure OpenTelemetry metrics behavior. It is neither complete nor typical.

telemetry:
  service: "test-telemetry"
  signals:
    metrics:1
      exporters:
        - name: exp-12
          type: otlp
          endpoint: "http://host:1234"
          temporality-preference: cumulative3
          default-histogram-aggregation:4
            type: base2-exponential-bucket-histogram
            max-buckets: 152
            max-scale: 19
        - name: exp-25
          type: otlp
          protocol: grpc
          temporality-preference: delta6
          default-histogram-aggregation:7
            type: explicit-bucket-histogram
            bucket-boundaries: [3,5,7]
      readers:
        - type: periodic8
          exporter: exp-1
          interval: PT6S
      views:
        - name: sum-view9
          aggregation:
            type: sum
          description: "Sum view"
          instrument-selector:
            name: counter-selector
            type: counter
            meter-name: my-counter
  1. Introduces the metrics configuration.
  2. Introduces the first metric exporter (with name exp-1).
  3. Indicates to accumulate measurement values since the previous transmission.
  4. Prescribes to aggregate histograms for transmission using the OpenTelemetry BASE2_EXPONENTIAL_BUCKET_HISTOGRAM technique with the specified maximum number of buckets and maximum scale.
  5. Introduces the second metric exporter (with name exp-2).
  6. Indicates to transmit deltas since the last transmission.
  7. Prescribes to aggregate histograms using a histogram with the given explicit bucket boundary values.
  8. Declares a single metric reader of the OpenTelemetry PERIODIC types gathering data each 6 seconds.
  9. Declares a single view to influence the transmission of the my-counter counter data.

Metric Exporters

The configuration for metrics exporters has several additional settings beyond those described earlier for exporters in general.

Configuration options

KeyTypeDefaultDescription
headersMap<String, String>Headers added to each export message
memory-modeMemoryModeMemory mode
temporality-preferenceMetricTemporalityPreferenceTypePreferred output aggregation technique (how transmitted values reflect the values recorded locally), configurable as a io.helidon.telemetry.otelconfig.MetricTemporalityPreferenceType value: CUMULATIVE, DELTA, LOWMEMORY
internal-telemetry-versionInternalTelemetryVersionSelf-monitoring telemetry OpenTelemetry should collect
certificateResourceTrusted certificates
typeMetricExporterTypeOTLPMetric exporter type
timeoutDurationExporter timeout
connect-timeoutDurationConnection timeout
endpointURIEndpoint of the collector to which the exporter should transmit
protocolStringDEFAULTExporter protocol type
client.keyResourceTLS client key
default-histogram-aggregationDefaultAggregationSelectorPreferred default histogram aggregation technique, configurable as io.helidon.telemetry.otelconfig.MetricDefaultHistogramAggregationConfig
client.certificateResourceTLS certificate
compressionCompressionTypeCompression the exporter uses
retry-policyRetryPolicyConfigRetry policy

Metric Aggregation

OpenTelemetry allows control over how each exporter aggregates histogram data prior to transmission to a backend.

Configuration options

KeyTypeDescription
typeMetricDefaultHistogramAggregationTypeType of aggregation default

You can configure the explicit bucket boundaries for EXPLICIT_BUCKET_HISTOGRAM aggregation.

KeyTypeDescription
bucket-boundariesList<Double>Explicit bucket boundaries

You can configure the exponential histogram aggregation behavior.

KeyTypeDescription
max-bucketsIntegerMaximum number of buckets
max-scaleIntegerMaximum scale

Metric Readers

An OpenTelemetry metric reader collects metric data in the server and then uses the associated metric exporter to send that data to the endpoint configured.

Configuration options

KeyTypeDefaultDescription
exporterStringName of the configured metric exporter to use for this metric reader
typeMetricReaderTypePERIODICMetric reader type

The periodic reader supports the following settings.

KeyTypeDefaultDescription
exporterStringName of the configured metric exporter to use for this metric reader
intervalDurationMetric reader read interval
typeMetricReaderTypePERIODICMetric reader type

Metric Views

OpenTelemetry metric views allow you to influence how meters are aggregated for reporting to backend systems.

Configuration options

KeyTypeDescription
cardinality-limitIntegerCardinality limit
instrument-selectorInstrumentSelectorConfigInstrument selector, configurable using io.helidon.telemetry.otelconfig.InstrumentSelectorConfig
attribute-filterPredicateAttribute name filter, configurable as a string compiled as a regular expression using java.util.regex.Pattern
nameStringMetrics view name
descriptionStringMetric view description
aggregationAggregationAggregation for the metric view, configurable as an io.helidon.telemetry.otelconfig.AggregationType: DROP, DEFAULT, SUM, LAST_VALUE, EXPLICIT_BUCKET_HISTOGRAM, BASE2_EXPONENTIAL_BUCKET_HISTOGRAM

The instrument selector controls which meters this view reflects.

KeyTypeDescription
unitStringInstrument unit
meter-nameStringMeter name
nameStringInstrument name
meter-schema-urlStringMeter schema URL
meter-versionStringMeter version
typeInstrumentTypeInstrument type

Logging Configuration

The settings under signal.logging prepare an OpenTelemetry LoggerProvider.

The sections below describe Helidon config settings that correspond directly to OpenTelemetry builders for the relevant OpenTelemetry type. Refer to the relevant OpenTelemetry documentation or Javadoc to understand the effect each setting has.

Configuration options

KeyTypeDescription
trace-basedBooleanWhether to include only log records from traces which are sampled
attributesTypedAttributesName/value pairs passed to OpenTelemetry
minimum-severitySeverityMinimum severity level of log records to process
processorsList<ProcessorConfig>Settings for logging processors
enabledBooleanWhether the OpenTelemetry logger should be enabled
log-limitsLogLimitsConfigLog limits to apply to log transmission
exportersMap<String, LogRecordExporter>Log record exporters

OpenTelemetry uses the following defaults:

SettingOpenTelemetry default
exportersnone
minimum-severityundefined severity number
processorsno-op processor
trace-basedfalse

Log Limits

For defaults, Helidon defers to the OpenTelemetry defaults, listed below.

Configuration options

KeyTypeDescription
max-attribute-value-lengthIntegerMaximum length of an attribute value
max-number-of-attributesIntegerMaximum number of attributes allowed

OpenTelemetry applies the following defaults:

SettingOpenTelemetry default
max-attribute-value-lengthInteger.MAX_VALUE
max-number-of-attributes128
exportersotlp with grpc protocol - see that web page’s "Properties: exporters, otel.logger.exporter property" section.
log-limitsmax-
processorsotlp - see that web page’s "Properties: logs" section.

The following example illustrates some of the ways you can configure OpenTelemetry logger behavior. It is neither complete nor typical.

application.yaml
telemetry:
  service: test-tel-logging
  global: false
  signals:
    logging:1
      minimum-severity: TRACE2
      log-limits:3
        max-attribute-value-length: 20
        max-number-of-attributes: 14
      processors:4
        - type: batch
          schedule-delay: PT10S
          max-queue-size: 15
          max-export-batch-size: 5
          timeout: PT30S
        - type: simple
      exporters:5
        - name: exp-1
          endpoint: "http://host:1234"
  1. Introduces the logger configuration.
  2. Sets the minimum log level severity to of log messages to send to the backend system.
  3. Configures limits related to attributes that accompany log messages.
  4. Prescribes the logger processors.
  5. Prescribes the logger exporters.

Reference

Copyright © 2018, 2026 Oracle and/or its affiliates.