OpenTelemetry Semantic Conventions

The Spring portfolio provides built-in instrumentation based on the Micrometer APIs. Arconia lets you configure your applications to export telemetry data adopting the OpenTelemetry Semantic Conventions instead of the default Micrometer conventions.

OpenTelemetry Semantic Conventions are the standard for cloud-native observability and are supported by a wide range of backends, from on-premises to cloud solutions. Arconia provides Dev Services for OpenTelemetry backends you can use during development and testing. Check out the Dev Services documentation for more details.

Getting Started

The conventions are provided by different modules, depending on the instrumentation they apply to:

Area Dependency Conventions Stability

JVM, HTTP, Errors

io.arconia:arconia-opentelemetry-semantic-conventions

Stable

Database

net.ttddyy.observation:datasource-micrometer-spring-boot and net.ttddyy.observation:datasource-micrometer-opentelemetry

Stable

Generative AI

io.arconia:arconia-opentelemetry-ai-semantic-conventions

Development

For the JVM, HTTP, and Errors conventions, add the Arconia OpenTelemetry Semantic Conventions dependency to your project. The module auto-activates when present on the classpath.

  • Gradle

  • Maven

dependencies {
  implementation 'io.arconia:arconia-opentelemetry-semantic-conventions'
}
<dependency>
    <groupId>io.arconia</groupId>
    <artifactId>arconia-opentelemetry-semantic-conventions</artifactId>
</dependency>

Your application also needs OpenTelemetry configured to export telemetry data, using either the Arconia OpenTelemetry Spring Boot Starter or the Spring Boot OpenTelemetry partial support (spring-boot-starter-opentelemetry). The recommended approach is the Arconia OpenTelemetry Spring Boot Starter:

  • Gradle

  • Maven

dependencies {
  implementation 'io.arconia:arconia-opentelemetry-spring-boot-starter'
}
<dependency>
    <groupId>io.arconia</groupId>
    <artifactId>arconia-opentelemetry-spring-boot-starter</artifactId>
</dependency>

If you use one of the available OpenTelemetry Dev Services during development or testing, Arconia will configure OpenTelemetry automatically to export logs, metrics, and traces to the specific service based on the OpenTelemetry Semantic Conventions.

JVM

Provides semantic conventions for JVM metrics, following the stable OpenTelemetry Semantic Conventions for JVM specification. They are based on the support provided by the Micrometer Metrics project, extended by Arconia to cover all the stable JVM metrics.

Area Metrics

Memory

jvm.memory.used, jvm.memory.committed, jvm.memory.limit, jvm.memory.used_after_last_gc

Garbage collection

jvm.gc.duration

Threads

jvm.thread.count

Class loading

jvm.class.loaded, jvm.class.unloaded, jvm.class.count

CPU

jvm.cpu.time, jvm.cpu.count, jvm.cpu.recent_utilization

The jvm.gc.duration metric replaces both the jvm.gc.pause and jvm.gc.concurrent.phase.time metrics from Micrometer, so it covers both garbage collection pauses and concurrent phases. The jvm.gc.name and jvm.gc.cause attributes tell them apart: for example, G1 Young Generation pauses versus G1 Concurrent GC phases (with cause No GC), or ZGC Pauses versus ZGC Cycles.

The Micrometer jvm.threads.live metric is not published, since the jvm.thread.count metric replaces it: summed over the jvm.thread.state attribute, it counts the same live platform threads.

Known Deviations

The JVM metrics currently deviate from the OpenTelemetry Semantic Conventions for JVM in the following ways, because of the Micrometer instrumentation they are based on:

  • The jvm.cpu.time metric is reported in nanoseconds instead of seconds (micrometer#7703).

  • The jvm.memory.used, jvm.memory.committed, jvm.memory.limit, jvm.memory.used_after_last_gc, jvm.thread.count, jvm.class.count, and jvm.cpu.count metrics are exported as gauges instead of non-monotonic sums (micrometer#7432).

  • The jvm.thread.count metric doesn’t have the jvm.thread.daemon attribute (micrometer#7702).

  • The jvm.memory.limit metric is reported as -1 for the memory pools without a defined maximum, such as Metaspace when no maximum size is configured, instead of not being reported.

  • Metrics use the units defined by Micrometer instead of the UCUM units required by the conventions: bytes, threads, and classes instead of By, {thread}, and {class}. The jvm.cpu.count and jvm.cpu.recent_utilization metrics have no unit, instead of {cpu} and 1 (micrometer#8130).

Configuration Properties

Table 1. JVM Configuration Properties
Property Default Description

arconia.observations.conventions.opentelemetry.jvm.enabled

true

Whether to enable JVM semantic conventions.

HTTP

Provides semantic conventions for HTTP server and client request observations, following the stable OpenTelemetry Semantic Conventions for HTTP specification.

Spans of requests whose response status code signals an error get the Error status even when no exception was thrown: 5xx for HTTP servers, 4xx and 5xx for HTTP clients. It requires the Micrometer Tracing OpenTelemetry bridge, which both the Arconia OpenTelemetry Spring Boot Starter and spring-boot-starter-opentelemetry include.

The conventions cover the servlet web stack and the blocking HTTP clients. The reactive web stack and WebClient keep the Spring Framework conventions, since Arconia doesn’t support the reactive stack. This includes the streaming calls that Spring AI makes with WebClient.

HTTP Server

Activated when the application is a servlet-based web application. The conventions are based on the support provided by the Spring Framework project, extended by Arconia to cover additional stable conventions.

The requests are reported with the http.server.request.duration metric and spans named after the request method and the matched route, such as GET /users/{id}. The query string of the request is recorded as url.query, with the values of sensitive query parameters replaced by REDACTED.

Requests answered with a 5xx status get error.type set to the status code. Requests answered with any other status don’t get it, even when Spring MVC handled an exception to produce the response, such as a validation failure answered with 400, since the request completed with a status code.

HTTP Client

Activated for the RestClient and RestTemplate instances built from the builders auto-configured by Spring Boot. The requests are reported with the http.client.request.duration metric and spans named after the request method, such as GET. The full URL of the request is recorded as url.full, with the credentials and the values of sensitive query parameters replaced by REDACTED. When the request fails without a response, error.type holds the class name of the I/O error, such as java.net.ConnectException, instead of the ResourceAccessException that Spring Framework wraps it in.

The outcome and uri attributes from Spring Framework are kept, since the OpenTelemetry Semantic Conventions don’t define a stable equivalent for them. The uri attribute holds the path of the URI template used for the request, such as /users/{id}, and lets you break down the client metrics by endpoint.

Configuration Properties

Table 2. HTTP Configuration Properties
Property Default Description

arconia.observations.conventions.opentelemetry.http.enabled

true

Whether to enable HTTP semantic conventions for HTTP servers and clients.

arconia.observations.conventions.opentelemetry.http.capture-url-query

true

Whether to capture the URL query string of the HTTP server observations as url.query, with the values of the sensitive query parameters redacted. The HTTP client observations always include it in url.full.

arconia.observations.conventions.opentelemetry.http.sensitive-query-parameters

AWSAccessKeyId, Signature, X-Amz-Signature, X-Amz-Credential, X-Amz-Security-Token, sig, X-Goog-Signature

Query parameters whose values are replaced by REDACTED in the URL query string of the HTTP server and client observations, matched case-sensitively. Setting it replaces the default list, and an empty list disables the redaction.

arconia.observations.conventions.opentelemetry.http.additional-sensitive-query-parameters

-

Additional query parameters whose values are replaced by REDACTED in the URL query string of the HTTP server and client observations, on top of the sensitive query parameters, matched case-sensitively.

arconia.observations.conventions.opentelemetry.http.capture-request-headers

-

HTTP request headers to record on the HTTP server and client spans, matched case-insensitively. Avoid headers carrying sensitive information, such as Authorization.

arconia.observations.conventions.opentelemetry.http.capture-response-headers

-

HTTP response headers to record on the HTTP server and client spans, matched case-insensitively. Avoid headers carrying sensitive information, such as Set-Cookie.

Errors

Records the stable error.type attribute on every observation ending in an error, following the OpenTelemetry Semantic Conventions for recording errors. The attribute is recorded on both the span and the metrics of the observation.

The attribute holds the fully qualified class name of the error in the form the JVM uses, such as com.example.OrderService$OrderNotFoundException for a nested class. It’s the same form Spring Framework and the OpenTelemetry Java instrumentation report.

When the convention of the observation sets a more specific value, that value is kept. For example, HTTP responses signaling an error get their status code: 5xx for servers, 4xx and 5xx for clients.

The attribute isn’t recorded for successful operations, so the none value Spring Framework sets on successful HTTP server requests is removed.

Configuration Properties

Table 3. Errors Configuration Properties
Property Default Description

arconia.observations.conventions.opentelemetry.error.enabled

true

Whether to enable error semantic conventions, recording the error.type attribute on observations ending in an error.

Database

Activated when the Datasource Micrometer dependencies are added to the project. They automatically instrument all DataSource beans in your Spring Boot application, generating metrics and traces for database queries executed via JDBC following the stable OpenTelemetry Semantic Conventions for Database. Arconia manages the versions of the dependencies for you.

  • Gradle

  • Maven

dependencies {
  implementation 'net.ttddyy.observation:datasource-micrometer-spring-boot'
  implementation 'net.ttddyy.observation:datasource-micrometer-opentelemetry'
}
<dependency>
    <groupId>net.ttddyy.observation</groupId>
    <artifactId>datasource-micrometer-spring-boot</artifactId>
</dependency>
<dependency>
    <groupId>net.ttddyy.observation</groupId>
    <artifactId>datasource-micrometer-opentelemetry</artifactId>
</dependency>

Refer to the Datasource Micrometer documentation for configuration options and more details.

With Datasource Micrometer 2.3.0 and its OpenTelemetry support, the following operations fail because of the instrumentation, while they work without it:

  • executing a Statement batch without any statement added to it, which fails with an IndexOutOfBoundsException;

  • executing queries on PostgreSQL, MySQL, or MariaDB connections whose JDBC URL has no // after the driver name, such as the short form jdbc:postgresql:mydb, which fail with a NullPointerException.

Known Deviations

The Datasource Micrometer instrumentation currently deviates from the OpenTelemetry Semantic Conventions for Database in the following ways:

  • Failed queries don’t get the db.response.status_code attribute, and the db.client.operation.duration metric doesn’t get the error.type attribute. Arconia records error.type on the spans (see Errors).

  • The server.port attribute is recorded also for the default port of the database, and as -1 when the connection URL doesn’t specify a port. The db.client.operation.duration metric also gets network.peer.address and network.peer.port from the connection URL.

  • The db.client.operation.duration metric gets the db.query.text attribute, which the conventions make opt-in for metrics because of its potentially high cardinality.

  • The db.query.summary attribute and the span name of INSERT …​ VALUES queries wrongly include a SELECT operation, and db.operation.name uses underscores for operations made of several words, such as CREATE_TABLE, instead of matching the query summary.

  • Each query is also recorded with the jdbc.query metric from Micrometer, in addition to db.client.operation.duration.

  • The db.namespace attribute is not recorded for Microsoft SQL Server.

  • The db.system.name attribute is set to other_sql for all the databases except PostgreSQL, MySQL, MariaDB, and Microsoft SQL Server, instead of the values the conventions define for the other databases, such as h2database, oracle.db, and ibm.db2.

  • The db.operation.name and db.collection.name attributes are extracted from the query text, which the conventions advise against for SQL databases.

Generative AI

Provides semantic conventions for Spring AI generative AI observations following the experimental OpenTelemetry Semantic Conventions for Generative AI.

The OpenTelemetry Semantic Conventions for Generative AI are still experimental, and they might change in the future.

Add the dedicated dependency to your project. The conventions auto-activate for Spring AI applications.

  • Gradle

  • Maven

dependencies {
  implementation 'io.arconia:arconia-opentelemetry-ai-semantic-conventions'
}
<dependency>
    <groupId>io.arconia</groupId>
    <artifactId>arconia-opentelemetry-ai-semantic-conventions</artifactId>
</dependency>

If another Generative AI convention module is also active, Arconia fails at startup with an actionable error message. Disable the unwanted module via its enabled property.

The module supports multiple convention flavors. The default opentelemetry flavor targets standard OpenTelemetry-compatible backends. For platform-specific setup using alternative conventions, refer to the dedicated pages: OpenLIT Semantic Conventions, OpenLLMetry Semantic Conventions, LangSmith Semantic Conventions, and Langfuse Semantic Conventions.

Features

  • Chat model spans, with the model and its parameters.

  • Embedding model spans, with the model and the number of dimensions.

  • Tool execution spans.

  • Advisor spans.

  • Chat client spans, recorded as agent invocations. The conversation ID of the chat memory is recorded on them and on the spans nested in them.

  • Operation duration metrics for chat, embedding, and image model calls.

  • Token usage metrics.

  • Input and output message content, captured as span attributes, span events, or log events.

Model calls, embeddings, tool executions, and chat client calls ending in an error get the error.type attribute when the error conventions are active. They belong to the Arconia OpenTelemetry Semantic Conventions module, which the Generative AI module doesn’t depend on: add both dependencies to get them.

Known Deviations

The Spring AI observations currently deviate from the OpenTelemetry Semantic Conventions for Generative AI in the following ways:

  • Chat model and embedding model spans have the INTERNAL span kind instead of CLIENT, since the Spring AI observations don’t describe them as calls to a remote service.

  • The server.address and server.port attributes are not recorded, since the Spring AI observations don’t expose the endpoint of the model provider.

  • System instructions are recorded in gen_ai.input.messages as messages with the system role, also for model providers that accept them separately from the chat history, such as Anthropic and Google Gemini, for which the conventions recommend the gen_ai.system_instructions attribute.

  • Attribute values are always strings, also for attributes defined as numbers or arrays, such as gen_ai.usage.input_tokens and gen_ai.request.stop_sequences (micrometer#7433).

Content Capturing

Model calls and tool executions can carry sensitive data, so capturing their content is opt-in. Three properties enable it: capture-message-content for the input and output messages of model calls, capture-tool-definitions for the definitions of the tools available to the model, and capture-tool-call-content for the arguments and result of tool executions.

The inference-content-destination property decides where the captured messages and tool definitions of a model call are recorded:

  • span-attributes (default): as attributes of the model call span.

  • log-events: in a gen_ai.client.inference.operation.details event exported through the OpenTelemetry Logs API, as defined by the OpenTelemetry Semantic Conventions. The event has the DEBUG severity the conventions recommend, so pipelines that drop debug logs drop it too. It carries the attributes of the model call span and the content in structured form, and it’s correlated with the span. It’s exported together with the other application logs, whether OpenTelemetry is configured by the Arconia OpenTelemetry Spring Boot Starter or by the Spring Boot OpenTelemetry support.

  • span-events: in a gen_ai.client.inference.operation.details event attached to the model call span. The OpenTelemetry Semantic Conventions now record events through the Logs API, but up to version 1.27 they recorded the content as span events, which some backends still display alongside the trace.

Binary media in messages, such as images sent as bytes or as base64 data URIs, is recorded inline as base64 only when the encoded content is at most 32000 characters long. Larger media is left out, so that the size of spans and events stays bounded. Media referenced by URL is always recorded as a URI part.

The arguments and result of tool executions are always recorded as attributes of the tool execution span. The same goes for the input and output messages of a chat client call, recorded on the agent invocation span: they are recorded only with the span-attributes destination, since with the other destinations the model calls of the chat client already carry them in their events.

Configuration Properties

Table 4. OpenTelemetry AI Configuration Properties
Property Default Description

arconia.observations.conventions.opentelemetry.ai.enabled

true

Whether to enable the OpenTelemetry AI Semantic Conventions module.

arconia.observations.conventions.opentelemetry.ai.flavor

opentelemetry

The convention flavor to apply. Accepted values: opentelemetry, openlit, openllmetry, langsmith, langfuse.

arconia.observations.conventions.opentelemetry.ai.capture-message-content

false (when flavor is opentelemetry)

Whether to capture the input and output messages of model calls. The default depends on the flavor: the opentelemetry flavor doesn’t capture them, the other flavors do.

arconia.observations.conventions.opentelemetry.ai.capture-tool-definitions

false (when flavor is opentelemetry)

Whether to capture the definitions of the tools available to the model in model calls. The default depends on the flavor: the opentelemetry flavor doesn’t capture them, the other flavors do.

arconia.observations.conventions.opentelemetry.ai.capture-tool-call-content

false (when flavor is opentelemetry)

Whether to capture the arguments and result of tool executions. The default depends on the flavor: the opentelemetry flavor doesn’t capture them, the other flavors do.

arconia.observations.conventions.opentelemetry.ai.inference-content-destination

span-attributes

Where to record the captured messages and tool definitions of model calls. Only the opentelemetry flavor supports it, the other flavors record the content where their platform expects it. Accepted values: span-attributes, span-events, log-events.

Histograms

The duration and token usage metrics defined by the OpenTelemetry Semantic Conventions are histograms. As in Spring Boot, their buckets are not published by default, to keep the number of time series low: only the count, sum, and maximum are exported, which is enough for throughput and average values. To compute percentiles, enable the histogram buckets for the metrics you need.

You can use the bucket boundaries advised by the OpenTelemetry Semantic Conventions with the Spring Boot management.metrics.distribution.slo properties.

  • YAML

  • Properties

management:
  metrics:
    distribution:
      slo:
        http.server.request.duration: 5ms,10ms,25ms,50ms,75ms,100ms,250ms,500ms,750ms,1000ms,2500ms,5000ms,7500ms,10000ms
management.metrics.distribution.slo.http.server.request.duration=5ms,10ms,25ms,50ms,75ms,100ms,250ms,500ms,750ms,1000ms,2500ms,5000ms,7500ms,10000ms
Metric Advised Bucket Boundaries

http.server.request.duration, http.client.request.duration

5ms,10ms,25ms,50ms,75ms,100ms,250ms,500ms,750ms,1000ms,2500ms,5000ms,7500ms,10000ms

jvm.gc.duration

10ms,100ms,1000ms,10000ms

gen_ai.client.operation.duration

10ms,20ms,40ms,80ms,160ms,320ms,640ms,1280ms,2560ms,5120ms,10240ms,20480ms,40960ms,81920ms

gen_ai.client.token.usage

1,4,16,64,256,1024,4096,16384,65536,262144,1048576,4194304,16777216,67108864

Alternatively, you can publish exponential histograms, which adapt their buckets to the recorded values and don’t need any boundaries. With the Arconia OpenTelemetry Spring Boot Starter, select the exponential aggregation and enable the histograms with the Spring Boot management.metrics.distribution.percentiles-histogram properties.

  • YAML

  • Properties

arconia:
  otel:
    metrics:
      exporter:
        histogram-aggregation: base2-exponential-bucket-histogram
management:
  metrics:
    distribution:
      percentiles-histogram:
        http.server.request.duration: true
arconia.otel.metrics.exporter.histogram-aggregation=base2-exponential-bucket-histogram
management.metrics.distribution.percentiles-histogram.http.server.request.duration=true

Stability

The OpenTelemetry Semantic Conventions module only adopts conventions declared stable by OpenTelemetry: the JVM metrics, the HTTP server and client spans and metrics, and the error.type attribute. It makes two exceptions:

  • The jvm.gc.cause attribute of the jvm.gc.duration metric is still in development, but it’s kept because it tells garbage collection pauses and concurrent phases apart (see JVM).

  • The QUERY value of the http.request.method attribute is still in development, but it’s one of the HTTP methods the stable conventions define as known by default.

The OpenTelemetry Semantic Conventions for Generative AI are still in development, and they are provided by a separate module.

Known Deviations

Besides the deviations of each instrumentation, described in the sections above, some differences from the conventions come from Micrometer and apply to all the observations:

  • Attribute values are always strings, also for attributes defined as numbers, such as http.response.status_code and server.port (micrometer#7433).

  • Spans ending without an error get the Ok status instead of being left unset, because the Micrometer Tracing OpenTelemetry bridge sets it (tracing#1634). It affects most spans, such as the Generative AI ones. It doesn’t affect the spans of HTTP server requests, nor the spans of HTTP client requests and database queries that have a parent span.

  • Spans of HTTP server requests that answer a handled exception with a status below 500, such as a validation failure answered with 400, get the Error status instead of being left unset, because the Micrometer Tracing OpenTelemetry bridge sets it whenever an exception is reported to the observation and the OpenTelemetry API doesn’t allow unsetting it. The error.type attribute follows the conventions and isn’t recorded.

  • With the Micrometer OTLP registry, durations use the seconds unit instead of s (micrometer#6988).

  • The .active long task timers that Micrometer adds for each observation, such as http.server.request.duration.active, have no equivalent in the conventions and get the attribute values known when the operation starts. For example, HTTP server requests in progress have http.response.status_code set to 200, the initial status of the response.