NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev · #1210 most downloaded on pub.dev
Dartastic.io's OpenTelemetry API for Dart following the OpenTelemetry specification. Supports all platforms including web.
Last release 1 months ago
27 Aug 2026
Release timing varies
gaps range from 1 weeks to 5 months
Nearly every release is documented
notes for 13 of 13 stable releases
1 version withdrawn
withdrawn after publishing
1 years old
29 releases · first in 2025
BREAKING : enabled becomes isEnabled() on APITracer , APILogger , APIInstrument and all instruments, and the enabled constructor parameter is removed.
enabled becomes isEnabled() on APITracer, APILogger,APIInstrument and all instruments, and the enabled constructor parameterx.enabled with x.isEnabled().APILogger.isEnabled() now accepts Context, SeverityNumber andEventName. The provider-level enabled getters are unchanged.getTracer, getLogger and getMeter no longer invent aversion and schemaUrl are nownull, rather than this package's own version and a schema URL your library1.0.0 scope version.One column per month.
Unset stays Unset ; analysis tools can no longer be misled by fabricated Ok statuses. The deprecated spanStatus parameter still flows through the setS…
OTelAPI.setErrorHandler — a user-configurable global error handlerOTelLog and never throws. A user-installedOTelFactorydefaultErrorHandlerContext.runIsolateSendPort to aggregate reports across isolatesSpan.end() no longer promotes status from Unset to Ok (api#60).Unset stays Unset; analysis tools can no longer be misled byspanStatus parameter stillsetStatus rules when passed.CompositePropagator.extract walks propagators in the order they wereContext.withSpanContext returns a derived Context instead of throwingArgumentError when the context already holds a span from a differentSemantic conventions regenerated from registry v1.44.0 (previously
v1.43.0-21-g436fa257). Additive only, per the VERSIONING.md policy: 47
new identifiers, no renames and no removals.
The substantial addition is the complete browser.web_vital.* set —
name, value, delta, id, rating and navigation_type — together
with their value enums: cls, lcp, fcp, inp, ttfb and the
obsoleted fid; good / needs-improvement / poor; and the six
navigation types (navigate, reload, back-forward,
back-forward-cache, prerender, restore). Web-vitals instrumentation
now has registry names to emit against instead of inventing its own.
Also new: browser.platform, hw.errors and hw.status,
k8s.node.filesystem.inode.count / .free, and the scaleway_cloud
and scaleway_cloud_compute members.
lib/src/api/semantics/candidates/ — a home for attribute keys that are
not yet in the registry, staged for upstream contribution, exported from
the package barrel and marked @experimental.
This revisits the rc.1 position that "the API package now contains only
registry conventions". That rule was right about the problem — a private
dialect masquerading as OpenTelemetry — but it left no path for the
conventions we want to propose, which the semantic-conventions CONTRIBUTING
guide asks be "prototyped in the corresponding instrumentation(s)" first.
Candidates are kept in a separate directory, under a separate stability
promise, so a consumer can always tell a published convention from a
proposal.
Candidates are unstable in identity but deprecation-cycled: a renamed,
reshaped or rejected candidate is @Deprecated, pointing at its
replacement, for a release before it is removed — the same cycle the
vendor/RUM enums completed. When one is accepted upstream it reappears in
generated semconv/ output and the candidate is deprecated in its favor.
Staged: app.start.type (cold/warm/hot), app.launch.id,
app.screen.previous_id, app.screen.previous_name,
app.gesture.direction, app.gesture.delta.x, app.gesture.delta.y,
device.battery.level, device.battery.state, device.battery.save_mode,
device.emulator, and browser.languages.
doc/SEMCONV_CANDIDATES.md — the disposition of all 116 identifiers
removed in rc.1. Most should return as registry conventions rather than
candidates: the registry has since gained app.crash, app.jank,
app.screen.click, app.widget.click, device.app.lifecycle,
session.start/session.end and browser.web_vital.*, which cover the
bulk of the removed RUM surface. The document maps each removal to its
registry replacement, to a candidate, or to a recorded reason for dropping
it.
Breaking: the deprecated vendor/RUM enums are removed (deprecated with notice in 1.0.0-beta.10): AppLifecycleStates , AppLifecycleSemantics , AppStart…
AppLifecycleStates,AppLifecycleSemantics, AppStartType, AppInfoSemantics,DeviceSemantics, BatterySemantics, NavigationSemantics,InteractionType, InteractionSemantics, PerformanceSemantics,ErrorSemantics, NetworkSemantics, RumSessionView,NavigationAction, and LifecycleState (semantics/rum.dart isflutterrific_opentelemetry defines its ownAPIObservableResult is now an abstract interface. Thedartastic_opentelemetry already does.Attributes.of no longer throws a TypeError when a map value is anList<Object> / List<dynamic>). Lists are nowAttributes.fromJson: homogeneousList<double>, and unsupported element types are warned and ignoredNothing published for this version
semantics/gen_ai_semantics.dart semconv/gen_ai.dart (wholly deprecated, see below)
*Create classes are now @internal and hidden from the public library.
They were internal by doc-comment convention only; the barrel exported them,
so AttributesCreate.create() etc. were callable by any consumer — an open
factory-bypass door, contradicting the beta.8/9 removal of factory cheat
paths. The analyzer now rejects outside-package use
(invalid_use_of_internal_member). Factories and same-package code are
unaffected. Consumers constructing objects must go through OTelAPI or the
installed OTelFactory. Covers all 29 *Create classes, including the
new CompositePropagatorCreate.
Breaking: the semantic-convention enums are now generated from the
OpenTelemetry registry with OTel Weaver, one file per registry
namespace (#50, #51). The hand-written semantics.dart,
semantic_values.dart, semantic_metrics.dart, semantic_events.dart,
gen_ai_semantics.dart, and ui_semantics.dart are gone; generated
files live under lib/src/api/semantics/semconv/ (90 attribute
namespaces, 931 attributes, 167 value enums, 29 metric namespaces with
533 metrics, 14 event namespaces with 32 events, and 24 entity
namespaces with 64 entities). Generated from
semantic-conventions
v1.43.0-21-g436fa257 (commit 436fa257, schema 1.44.0-unreleased).
Regenerate with tool/semconv/generate.sh; verify freshness with
tool/semconv/generate.sh --check. There is no compatibility layer —
the tables below are the migration guide.
Breaking: file restructure. Every old semantics file is replaced:
| Old file | Replacement |
|---|---|
semantics/semantics.dart |
semantics/semantics_base.dart (interfaces) + semantics/semconv/<ns>.dart per namespace + semantics/http_header_attribute.dart |
semantics/semantic_values.dart |
value enums live beside their attribute in semconv/<ns>.dart |
semantics/semantic_metrics.dart |
semconv/metrics/<ns>_metrics.dart per namespace |
semantics/semantic_events.dart |
semconv/events/<ns>_events.dart per namespace |
semantics/gen_ai_semantics.dart |
semconv/gen_ai.dart (wholly deprecated, see below) |
semantics/ui_semantics.dart |
semantics/rum.dart (wholly deprecated, see below) |
semantics/navigation_action.dart |
semantics/rum.dart |
semantics/lifecycle_state.dart |
semantics/rum.dart |
Breaking: attribute-key enums are named after their registry
namespace, with an Attributes suffix only where the bare name
collides with dart:core/dart:io/Flutter-widgets types. Renames
(everything not listed keeps its name and is regenerated in place):
| Old enum | New enum |
|---|---|
Database |
Db |
Kubernetes |
K8s |
Hardware |
Hw (all keys change too — see Fixed) |
OperatingSystem |
Os |
RPC |
Rpc |
GraphQL |
Graphql |
CloudEvents |
Cloudevents |
ComputeUnit |
ContainerAttributes |
ErrorResource |
ErrorAttributes |
EventResource |
EventAttributes |
ExceptionResource |
ExceptionAttributes |
FileResource |
FileAttributes |
ProcessResource |
ProcessAttributes |
ServerResource |
Server |
TelemetrySDK, TelemetryDistro |
Telemetry (merged) |
ComputeInstance |
merged into Host (same member names) |
SourceCode |
merged into Code (same member names) |
GenAI, GenAi |
GenAi (merged, deprecated — see below) |
Environment |
Deployment.deploymentEnvironment (@Deprecated) |
General |
split: Service.serviceName/serviceVersion, Telemetry.telemetrySdk* |
Version |
removed (see Removed) |
Breaking: member identifiers are the camelCase of the full attribute
id (tokens split on ./_; single registry tokens keep their
casing, e.g. replicaset, cloudevents, launchtype). Key strings
are unchanged unless listed under Fixed. Renamed members:
Http:
| Old | New |
|---|---|
requestMethod |
httpRequestMethod |
requestMethodOriginal |
httpRequestMethodOriginal |
requestResendCount |
httpRequestResendCount |
responseStatusCode |
httpResponseStatusCode |
requestSize |
httpRequestSize |
requestBodySize |
httpRequestBodySize |
responseSize |
httpResponseSize |
responseBodySize |
httpResponseBodySize |
GenAi (every member also @Deprecated, see below):
| Old | New |
|---|---|
system |
genAiSystem |
operationName |
genAiOperationName |
requestModel |
genAiRequestModel |
requestMaxTokens |
genAiRequestMaxTokens |
requestTemperature |
genAiRequestTemperature |
requestTopP |
genAiRequestTopP |
requestTopK |
genAiRequestTopK |
requestFrequencyPenalty |
genAiRequestFrequencyPenalty |
requestPresencePenalty |
genAiRequestPresencePenalty |
requestStopSequences |
genAiRequestStopSequences |
responseId |
genAiResponseId |
responseModel |
genAiResponseModel |
responseFinishReasons |
genAiResponseFinishReasons |
usageInputTokens |
genAiUsageInputTokens |
usageOutputTokens |
genAiUsageOutputTokens |
Kubernetes → K8s (single-token registry words):
| Old | New |
|---|---|
k8sReplicaSetUid / k8sReplicaSetName |
k8sReplicasetUid / k8sReplicasetName |
k8sStatefulSetUid / k8sStatefulSetName |
k8sStatefulsetUid / k8sStatefulsetName |
k8sDaemonSetUid / k8sDaemonSetName |
k8sDaemonsetUid / k8sDaemonsetName |
k8sCronJobUid / k8sCronJobName |
k8sCronjobUid / k8sCronjobName |
Hardware → Hw: hardwareId → hwId, hardwareName → hwName,
hardwareParent → hwParent, hardwareSerialNumber →
hwSerialNumber, hardwareType → hwType, hardwareVendor →
hwVendor, hardwareModel → hwModel (key strings change too — see
Fixed).
CloudEvents → Cloudevents: cloudEventsEventId →
cloudeventsEventId, cloudEventsEventSource →
cloudeventsEventSource, cloudEventsEventSpecVersion →
cloudeventsEventSpecVersion, cloudEventsEventSubject →
cloudeventsEventSubject, cloudEventsEventType →
cloudeventsEventType.
TelemetrySDK/TelemetryDistro → Telemetry: sdkName →
telemetrySdkName, sdkLanguage → telemetrySdkLanguage,
sdkVersion → telemetrySdkVersion, distroName →
telemetryDistroName, distroVersion → telemetryDistroVersion.
Aws: awsEcsLaunchType → awsEcsLaunchtype.
All other attribute-key enums already followed the rule — their
members are unchanged.
Breaking: metric enum members follow the same rule — camelCase of
the full metric name instead of the old namespace-stripped short form.
Every member of the 15 pre-existing metric enums gains its namespace
prefix; the old name was exactly the new name minus that prefix (e.g.
CicdMetric.pipelineRunActive → CicdMetric.cicdPipelineRunActive,
HttpMetric.serverRequestDuration →
HttpMetric.httpServerRequestDuration, K8sMetric.podCpuUsage →
K8sMetric.k8sPodCpuUsage).
Breaking: SemanticEvent split into per-namespace event enums
implementing the unchanged OTelEvent interface:
Old SemanticEvent member |
New |
|---|---|
exception |
ExceptionEvent.exception |
featureFlagEvaluation |
FeatureFlagEvent.featureFlagEvaluation |
browserWebVital |
BrowserEvent.browserWebVital |
azureResourceLog |
AzureEvent.azureResourceLog |
genAiEvaluationResult |
GenAiEvent.genAiEvaluationResult |
faasInvocationException |
FaasEvent.faasInvocationException |
httpClientRequestException |
HttpEvent.httpClientRequestException |
httpServerRequestException |
HttpEvent.httpServerRequestException |
rpcClientCallException |
RpcEvent.rpcClientCallException |
rpcServerCallException |
RpcEvent.rpcServerCallException |
genAiClientInferenceOperationDetails |
GenAiEvent.genAiClientInferenceOperationDetails |
messagingCreateException |
MessagingEvent.messagingCreateException |
messagingSendException |
MessagingEvent.messagingSendException |
messagingProcessException |
MessagingEvent.messagingProcessException |
messagingReceiveException |
MessagingEvent.messagingReceiveException |
messagingSettleException |
MessagingEvent.messagingSettleException |
Breaking: value-enum renames (name = PascalCase of the full
attribute id): AwsEcsLaunchType → AwsEcsLaunchtype, HardwareType
→ HwType, MessagingOperation → MessagingOperationType. DbSystem
still exists for the deprecated db.system (now @Deprecated); the
current attribute db.system.name gets the new DbSystemName.
Value-enum member ids follow the registry member ids with Dart
reserved words $-escaped, which renames two members:
SystemPagingDirection.pageIn → in$, SystemPagingDirection.pageOut
→ out (emitted values unchanged). The deprecated bare state
attribute's value enum is named StateValue to avoid colliding with
Flutter's State.
Breaking: legacy az.* keys moved out of Azure — the registry
files deprecated ids by their real prefix, so Azure.azNamespace and
Azure.azServiceRequestId are now Az.azNamespace and
Az.azServiceRequestId (both @Deprecated) in semconv/az.dart.
Deprecated-only legacy roots each get their own file the same way:
az.dart, net.dart, message.dart, pool.dart, and other.dart
(the dotless legacy state key).
HttpHeaderAttribute now extends OTelSemantic, so request/response
header template attributes can be used directly as keys in
attributesFromSemanticMap / attributesOf.
Full attribute-registry coverage (#51): 24 namespaces that were never
modeled, including the app.* namespace and app entity from the
issue — App, Aspnetcore, Cpu, Cpython, Disk, Dotnet,
Go, Jsonrpc, Jvm, Linux, Mainframe, Mcp, Nfs,
Nodejs, OncRpc, Openai, Openshift, Oracle (oracle.db.*,
release candidate), OracleCloud, Pprof, SecurityRule, Signalr,
V8js, Zos — plus complete member sets for every previously
partial namespace.
Entity enums (#51): <Ns>Entity enums for all 64 registry
entities (24 namespaces), each member carrying the entity type string
plus identifying / descriptive lists wired to the attribute-key
enums — e.g. AppEntity.app identifies by App.appBuildId. New
OTelEntity interface in semantics_base.dart.
14 new metric namespaces (aspnetcore, azure, cpu, cpython,
dotnet, go, hw, jvm, kestrel, nfs, nodejs, openshift,
signalr, v8js) alongside the regenerated 15.
OTelSemanticIntValue for int-valued registry value enums
(cpython.gc.generation, rpc.grpc.status_code).
SemconvRegistry — a generated index of every semconv enum
(allAttributeEnums, allValueEnums, allIntValueEnums,
allMetricEnums, allEventEnums, allEntityEnums) plus the pinned
registry version/commit. Powers package-wide invariant tests
(duplicate-key detection, key-format checks).
Every non-stable enum member now carries a Stability: doc line
(development, release_candidate, alpha, experimental), and
every registry-deprecated attribute carries @Deprecated with the
registry's replacement guidance.
tool/semconv/generate.sh + checked-in Weaver templates
(tool/semconv/templates/registry/dart[_test]/), pinned to the same
otel/weaver:v0.24.2 container digest the semantic-conventions repo
pins. Also generates audit tests asserting every key, value, metric,
event, and entity against the registry, plus source audits for
@Deprecated/Stability: annotations.
NonRecordingSpan and OTelAPI.nonRecordingSpan(SpanContext) — the
spec's "Wrapping a SpanContext in a Span" operation: the wrapped
context is returned unchanged, isRecording is false, and all other
operations are no-ops (#40).
Global TextMapPropagator — OTelAPI.textMapPropagator getter/setter,
implementing the spec's Global Propagators requirement: "The OpenTelemetry
API MUST provide a way to obtain a propagator for each supported Propagator
type" (TextMapPropagator being the single supported type today). The
global is non-generic (TextMapPropagator<dynamic, dynamic>) and, like
every other API object, routed through OTelFactory, so a replacement
factory can substitute its own implementation. Isolate-local;
OTelAPI.reset() restores the no-op default (#42).
OTelAPI.compositePropagator / OTelFactory.compositePropagator —
factory-routed construction for CompositePropagator, previously the
only instantiable API object built by direct construction; its public
constructor is now private (Breaking, construct via the factory)
(#42).
NoopTextMapPropagator — the default value of the global, satisfying
"The OpenTelemetry API MUST use no-op propagators unless explicitly
configured otherwise": inject writes nothing and extract returns the
passed Context unchanged (#42).
semantics/rum.dart, names/keys/membersAppLifecycleStates, AppLifecycleSemantics,AppStartType, AppInfoSemantics, DeviceSemantics,BatterySemantics, NavigationSemantics, InteractionType,InteractionSemantics, PerformanceSemantics, ErrorSemantics,NetworkSemantics, RumSessionView, NavigationAction,LifecycleState.GenAi — the gen_ai.* conventions moved upstream to@Deprecated, e.g. Db.dbSystem/dbConnectionString/dbUser/dbName/dbStatement/dbOperation, Deployment.deploymentEnvironment,Otel.otelLibraryName/otelLibraryVersion, Enduser.*,EventAttributes.eventName, Code.codeNamespace,FeatureFlag.featureFlagVariant, the legacy net.*/az.*/http.*DbSystem value enum — plus every otherdeprecated: entry in the registry.Members that do not exist in the attribute registry (not even as
deprecated):
| Removed | Use instead |
|---|---|
Http.connectionState |
Http.httpConnectionState (was a duplicate key) |
Database.dbClientConnectionUsedState |
Db.dbClientConnectionState |
Messaging.messagingDestination |
Messaging.messagingDestinationName |
Messaging.messagingDestinationKind |
removed from the spec, no replacement |
Messaging.messagingTempDestination |
Messaging.messagingDestinationTemporary |
Messaging.messagingProtocol |
Network.networkProtocolName |
Messaging.messagingProtocolVersion |
Network.networkProtocolVersion |
Elasticsearch.elasticsearchClusterName |
Db.dbNamespace |
Elasticsearch.elasticsearchNodeVersion |
removed, no replacement |
User.userSession |
Session.sessionId |
ComputeUnit.containerImageTag |
ContainerAttributes.containerImageTags |
General.telemetryAutoVersion |
Telemetry.telemetryDistroVersion |
System.systemDiskIoDirection |
Disk.diskIoDirection |
AppInfoSemantics vendor keys as semconv |
official identity is App.appBuildId / Artifact.* |
Value-enum members that do not exist in the registry:
TelemetrySdkLanguage.dart (note: dart is missing from the
registry's telemetry.sdk.language well-known values — an upstream
semconv gap; SDKs should keep emitting the literal dart),
CloudPlatform.herokuDyno, NetworkConnectionType.mobile,
ProfileFrameType.java/nodejs/python, and
SystemMemoryState.slabReclaimable/slabUnreclaimable (slab states
moved upstream to system.memory.linux.slab.state).
Version enum — schema.url is not a registry attribute; schema URLs
belong on providers/InstrumentationScope.
General, SemanticEvent, and the duplicate GenAI enum (see the
rename/split tables above).
genAiSpanName() — not a convention; compose
'<operation> <model>' directly.
Wire format — emitted attribute keys change (#50, #51). These fix
the strings actually emitted, so backends keying on the spec names
will now match:
| Member (old) | Old emitted key | Correct key |
|---|---|---|
Kubernetes.k8sResourcepaceName |
k8s.Resourcepace.name |
K8s.k8sNamespaceName → k8s.namespace.name (#50) |
SourceCode.codeResourcepace |
code.Resourcepace |
Code.codeNamespace → code.namespace (#50; itself deprecated → code.function.name) |
Hardware.* (7 members) |
hardware.* |
Hw.* → hw.* |
FeatureFlag.featureFlagProviderName |
feature_flag.provider_name |
same identifier, now feature_flag.provider.name |
CloudPlatform.azureVm/azureAks/azureFunctions/azureAppService/azureOpenshift/azureContainerApps/azureContainerInstances |
azure_vm etc. |
same identifiers, now the registry's dotted values azure.vm, azure.aks, azure.functions, azure.app_service, azure.openshift, azure.container_apps, azure.container_instances |
GenAiTokenType.completion |
completion |
same identifier (@Deprecated), now emits output; new member GenAiTokenType.output |
Breaking: With only the API installed (no SDK), startSpan/createSpan
now follow trace/api.md's "Behavior of the API in the absence of an
installed SDK": the returned span is non-recording (isRecording is
false and every mutating operation is a no-op) and carries the
SpanContext from the parent Context — explicit or implicit —
unchanged; when the context has no span, it carries an empty
SpanContext (all-zero trace/span IDs, unsampled flags). Previously
the API minted random valid IDs and returned recording spans (#40).
SDK span creation is unaffected: the no-op behavior applies only when
the installed factory isAPIFactory.
Baggage now follows the spec for values, names, and no-SDK use.
Per the Baggage API spec, values are any valid UTF-8 string — the empty
string is accepted (previously ArgumentError) and survives Set/Get
and both fromJson paths (previously dropped). Invalid (empty) names are
ignored with a warning instead of throwing. copyWith / copyWithout /
copyWithBaggage work without an installed SDK (previously StateError),
per "The Baggage API MUST be fully functional in the absence of an
installed SDK."
TraceState.put / remove never throw. Per the trace API spec,
mutating operations validate input and "MUST NOT return TraceState
containing invalid data" while following the error-handling guidelines —
invalid keys/values are now ignored with a warning (previously
ArgumentError), and both operations work without an installed SDK
(previously StateError).
Provider accessors use safe defaults instead of throwing. Per the
trace API spec, an invalid name must return "a working Tracer
implementation... as a fallback rather than returning null or throwing an
exception": OTelAPI.tracerProvider('') / meterProvider('') /
loggerProvider('') now warn and return the global default (previously
ArgumentError), and getTracer / getMeter / getLogger after
provider shutdown warn and return a no-op instance (previously
StateError).
AppLifecycleSemantics , AppStartType , AppInfoSemantics , DeviceSemantics , BatterySemantics , NavigationSemantics , InteractionType , InteractionSemantics , PerformanceSemantics , ErrorSemantics , NetworkSemantics , RumSessionView , NavigationAction , and LifecycleState ( semantics/rum.dart is gone). They are not OpenTelemetry semantic conventions and so do not belong in this package; flutterrific_opentelemetry defines its own Flutter conventions for what the registry does not yet cover. The API package now contains only registry conventions.
OTelAPI.instrumentationScope() recursed into itself when called before initialization, causing an immediate StackOverflowError ; it now lazily install
OTelAPI.instrumentationScope() recursed into itself when called beforeStackOverflowError; it now lazilyOTelAPI.tracer() and OTelAPI.logger() threw a null-check error beforeTraceState.fromString / fromMap / empty, SpanContext.fromJson, andBaggage.fromJson threw StateError('Call initialize() first.') insteadfromString parses the W3Ctracestate header (a propagator path) and the fromJsons run in freshOTelAPI.tracerProviders() / meterProviders() / loggerProviders()OTelAPI.attributesFromMap, Attributes.of, and Map.toAttributes() noattrsFromMap "cheat" (obsoleteattributesFromMap is now respected on all three paths (#33).TraceState multi-tenant tracestate keys (tenant-id@system-id) nowtenant-id may start with atenant-id/system-id are length-capped (241/14 chars).OTelFactory.isAPIFactory — identifies the API's auto-installed no-op factory. Defaults to false on OTelFactory ; OTelAPIFactory overrides it to true .
OTelFactory.isAPIFactory — identifies the API's auto-installed no-opfalse on OTelFactory; OTelAPIFactory overrides ittrue. SDK factories (which extend OTelAPIFactory) must override it tofalse. Lets SDK initialization replace the spec-mandated no-op APIruntimeType checks (see dartastic_opentelemetry #50 / PR #53).Context.root / Context.current (and other Context APIs) threwStateError('Call initialize() first.') when accessed beforeOTelAPI.initialize(), violating the OTel spec requirement that the APIOTelAPI's existing behavior. ThanksContext re-reads the global factory on every access instead of keepinginitialize()) replaces a no-op cached before initialization.OTelAPI.initialize() now replaces an installed no-op API factoryisAPIFactory == true) instead of throwing, so API use beforeContext.current) no longer blocks explicitStateError.Nothing published for this version
…, otel.span.sampling_result , plus the deprecated-but-still-emitted otel.library.name / otel.library.version
OTelAPI.attributesOf<E extends OTelSemantic>(Map<E, Object>) — a
shorthand-friendly counterpart to attributesFromSemanticMap.
Parameterized on a single concrete semconv enum [E], so Dart 3.10
static dot-shorthand can drop the prefix at the call site:
// Today and forever:
OTelAPI.attributesOf<Http>({
Http.requestMethod: 'GET',
Http.responseStatusCode: 200,
});
// With Dart 3.10+ static dot-shorthand enabled:
OTelAPI.attributesOf<Http>({
.requestMethod: 'GET',
.responseStatusCode: 200,
});attributesFromSemanticMap stays the right call site when you need to
mix multiple semconv enums or your own OTelSemantic-implementing
enums in one map.
New top-level User enum in semantics.dart covering the OTel-spec
user.* keys: userId, userEmail, userFullName, userName,
userRoles, userSession. Replaces the previous UserSemantics
enum in ui_semantics.dart.
New top-level Session enum in semantics.dart covering the OTel-spec
session.* keys: sessionId, sessionPreviousId. Spec-only subset
of the previous SessionViewSemantics.
Spec-derived metric-name enums in new semantic_metrics.dart.
Covers every metric in the OTel attribute registry except the
language-runtime namespaces (jvm.*, go.*, nodejs.*,
cpython.*, v8js.*, kestrel.*, aspnetcore.*, signalr.*,
openshift.*, nfs.* — Dart apps don't emit those). Generated by
parsing the OTel model/*/metrics.yaml files, so name / instrument
kind / unit string travel together:
final metric = HttpMetric.serverRequestDuration;
metric.name; // 'http.server.request.duration'
metric.instrument; // SemanticInstrument.histogram
metric.unit; // 's'Enums (15): CicdMetric, ContainerMetric, DbMetric,
DnsMetric, FaasMetric, GenAiMetric, HttpMetric, K8sMetric,
McpMetric, MessagingMetric, OtelMetric, ProcessMetric,
RpcMetric, SystemMetric, VcsMetric. New OTelMetric interface
unifies them; new SemanticInstrument enum names the four OTel
instrument kinds.
Spec event-name enum in new semantic_events.dart — all 16
spec-defined event names (exception, feature_flag.evaluation,
browser.web_vital, gen_ai.client.inference.operation.details,
the per-protocol *.exception events for HTTP/RPC/messaging/FaaS,
plus azure.resource.log). SemanticEvent exposes a name
getter; OTelEvent interface for switching.
Breaking: Dropped the Resource suffix from semconv-enum names where
it didn't conflict with a built-in Dart / Flutter / common-package type.
HttpResource.requestMethod is now Http.requestMethod,
UrlResource.urlFull is now Url.urlFull, etc. — a straight find-and-
replace migration for ~60 enums. Migration: replace XResource →
X for every enum below.
Kept the Resource suffix on five enums to avoid name clashes with
common types:
| Enum | Conflicts with |
|---|---|
ErrorResource |
dart:core Error |
ExceptionResource |
dart:core Exception |
FileResource |
dart:io File |
ProcessResource |
dart:io Process |
ServerResource |
package:grpc Server |
EventResource |
package:web Event |
All other 60+ enums dropped the suffix: Client, Cloud,
ComputeUnit, ComputeInstance, Database, Deployment, Device,
Environment, FeatureFlag, GenAI, General, GraphQL, Host,
Http, Kubernetes, Messaging, Network, OperatingSystem,
RPC, Url, Service, SourceCode, TelemetryDistro,
TelemetrySDK, UserAgent, Version, plus all 33 new enums in this
release (Android, Artifact, Aws, Azure, Browser, Cassandra,
Cicd, CloudEvents, Cloudfoundry, Code, Destination, Dns,
Elasticsearch, Enduser, Faas, Gcp, Geo, Hardware,
Heroku, Ios, Log, Oci, Opentracing, Otel, Peer,
Profile, Source, System, Test, Thread, Tls, Vcs,
Webengine).
Breaking — file restructure. lib/src/api/semantics/resource_semantics.dart
→ lib/src/api/semantics/semantics.dart (the new consolidated home
for the OTelSemantic interface and every attribute-key enum);
lib/src/api/semantics/resource_values.dart →
lib/src/api/semantics/semantic_values.dart. The previous standalone
semantics.dart (interface only) is deleted; its content moved to
the top of the renamed file. Consumers using the package barrel
(package:dartastic_opentelemetry_api/dartastic_opentelemetry_api.dart)
are unaffected. Direct src/api/semantics/... imports need the
new paths.
Breaking — UserSemantics removed. Use the new User enum in
semantics.dart instead. Migration: UserSemantics.userId →
User.userId, etc.
Breaking — SessionViewSemantics split. OTel-spec keys
(session.id, session.previous_id) → Session in semantics.dart.
Datadog/Dynatrace-style non-spec RUM keys (session_id underscored,
session.start, session.duration, view.*, action.count,
user_satisfaction_score) → new RumSessionView enum in
ui_semantics.dart. ui_semantics.dart is now strictly the home
for Flutter / RUM non-spec conventions.
Typed value-set enums — a new semantic_values.dart file exposes
enums for the 35+ OTel attributes whose spec entry defines a closed
set of valid string values. Each value enum exposes its on-wire
string via a .value getter and implements OTelSemanticValue for
future polymorphic helpers. Highlights:
CloudProvider, CloudPlatform, FaasInvokedProvider,FaasTriggerHostArch, OsTypeHttpRequestMethod, HttpConnectionStateNetworkType, NetworkTransport, NetworkConnectionType,NetworkIoDirectionDbSystem, DbClientConnectionState, CassandraConsistencyLevel,AzureCosmosdbConnectionMode, AzureCosmosdbConsistencyLevelMessagingSystem, MessagingOperationRpcSystem, RpcMessageType, GraphqlOperationTypeOpentracingRefType, OtelStatusCode, OtelSpanSamplingResult,TelemetrySdkLanguageSystemCpuState, SystemMemoryState, SystemFilesystemState,SystemFilesystemType, SystemPagingDirection,SystemPagingState, SystemPagingType, SystemProcessStatus,DiskIoDirection, LogIostreamIosAppState, AndroidAppStateAwsEcsLaunchTypeCicdPipelineRunState, CicdPipelineTaskType, CicdWorkerStateHardwareType, TlsProtocolNameVcsChangeState, VcsLineChangeType, VcsRefTypeTestCaseResultStatus, TestSuiteRunStatusProfileFrameTypeGenAiOperationName, GenAiSystem, GenAiTokenTypeContainerCpuState, ProcessContextSwitchType,ProcessPagingFaultTypeUsage:
OTelAPI.attributesFromSemanticMap({
Database.dbSystemName: DbSystem.postgresql.value,
Cloud.cloudProvider: CloudProvider.gcp.value,
Network.networkTransport: NetworkTransport.quic.value,
});Comprehensive semconv-enum coverage of the OTel
attribute registry.
Every top-level registry namespace that wasn't already represented
now has a typed enum. Consumers can keep using raw strings for
app-specific keys, but for spec-defined attributes there is now a
typed-enum entry, making typos at the call site a compile error.
New enums (33):
AndroidResource — android.os.api_level, android.app.state,android.stateArtifactResource — software-artifact / supply-chainartifact.attestation.*, artifact.hash, artifact.purl,artifact.version, etc.)AwsResource — ECS / EKS / Lambda / S3 / CloudWatch Logs /aws.ecs.*, aws.eks.cluster.arn,aws.lambda.invoked_arn, aws.s3.*, aws.dynamodb.*,aws.log.*, aws.request_id)AzureResource — azure.client.id, azure.cosmosdb.*, plus theaz.namespace / az.service_request_id keys still emittedBrowserResource — browser.brands, browser.language,browser.mobile, browser.platform (matches what the SDK webCassandraResource — cassandra.consistency.level,cassandra.coordinator.dc, etc.CicdResource — pipeline / task / worker attributescicd.pipeline.*, cicd.worker.*, cicd.system.component)CloudEventsResource — cloudevents.event_id,cloudevents.event_source, cloudevents.event_spec_version,cloudevents.event_subject, cloudevents.event_typeCloudfoundryResource — Cloud Foundry platform attrscloudfoundry.app.*, cloudfoundry.org.*,cloudfoundry.process.*, cloudfoundry.space.*,cloudfoundry.system.*)CodeResource — source-link attrs (code.function.name,code.file.path, code.line.number, code.column.number,code.namespace, code.stacktrace)DestinationResource — destination.address,destination.port (mirror of ServerResource for outbound non-HTTP)DnsResource — dns.question.name, dns.answersElasticsearchResource — elasticsearch.cluster.name,elasticsearch.node.name, elasticsearch.node.versionEnduserResource — enduser.id, enduser.role, enduser.scopeuser.*; enduser.* is what services set aboutEventResource — event.name (used by the logs signal)FaasResource — Function-as-a-Service attrs (faas.coldstart,faas.invoked_*, faas.trigger, etc.)GcpResource — gcp.client.service, gcp.cloud_run.job.*,gcp.gce.instance.*GeoResource — geo.continent.code, geo.country.iso_code,geo.locality.name, geo.location.lat, geo.location.lon,geo.postal_code, geo.region.iso_codeHardwareResource — hardware.id, hardware.name,hardware.parent, hardware.type, hardware.serial_number,hardware.vendor, hardware.modelHerokuResource — heroku.app.id, heroku.release.commit,heroku.release.creation_timestampIosResource — ios.app.state, ios.stateLogResource — log.iostream, log.file.*, log.record.original,log.record.uidNetworkResource — added networkProtocolNamenetwork.protocol.name), networkProtocolVersionnetwork.protocol.version), and networkTransportnetwork.transport) — current OTel semconv keys for the wireOciResource — oci.manifest.digestOpentracingResource — opentracing.ref_typeOtelResource — otel.scope.name, otel.scope.version,otel.status_code, otel.status_description,otel.span.sampling_result, plus the deprecated-but-still-emittedotel.library.name / otel.library.versionPeerResource — peer.serviceProfileResource — profile.frame.type (experimental profilingSourceResource — source.address, source.port (mirror ofClientResource for inbound non-HTTP)SystemResource — system-level metric attrs for CPU / memory /TestResource — test.case.name, test.case.result.status,test.suite.name, test.suite.run.statusThreadResource — thread.id, thread.nameTlsResource — full TLS connection attribute settls.cipher, tls.protocol.*, tls.client.*, tls.server.*)UserAgentResource — user_agent.original, user_agent.name,user_agent.version — the OTel semconv user-agent attributes setdartastic_dio_otel) onVcsResource — version-control attrsvcs.repository.url.full, vcs.ref.head.*, vcs.change.*,vcs.owner.name, vcs.provider.name, etc.)WebengineResource — webengine.description, webengine.name,webengine.versionBackfilled current-spec keys on DatabaseResource — the older
db.system / db.name / db.statement / db.operation entries
are retained for back-compat, with the newer formalized keys added
alongside them: dbSystemName (db.system.name), dbNamespace
(db.namespace), dbOperationName (db.operation.name),
dbOperationBatchSize (db.operation.batch.size), dbQueryText
(db.query.text), dbQuerySummary (db.query.summary),
dbResponseStatusCode (db.response.status_code),
dbStoredProcedureName (db.stored_procedure.name),
dbClientConnectionState (db.client.connection.state),
dbClientConnectionPoolName (db.client.connection.pool.name),
dbClientConnectionUsedState (db.client.connection.used.state).
Backfilled current-spec keys on ComputeUnitResource (which
holds the container.* registry): containerImageTags
(container.image.tags, the pluralized form that replaces the
legacy container.image.tag), containerImageId
(container.image.id), containerImageRepoDigests
(container.image.repo_digests), containerCommand
(container.command), containerCommandArgs
(container.command_args), containerCommandLine
(container.command_line), containerCsiPluginName
(container.csi.plugin.name), containerCsiVolumeId
(container.csi.volume.id), containerLabels
(container.labels).
Pluggable TimeProvider for span timestamps. New abstraction with three pieces:
Pluggable TimeProvider for span timestamps. New abstraction with three pieces:
TimeProvider (interface) and SystemTimeProvider (default, DateTime.now) — lib/src/util/time_provider.dart.WebTimeProvider — window.performance.now() + timeOrigin for sub-millisecond span timestamps on web. Lives in lib/src/util/web_time_provider.dart as a conditional facade (web_time_provider_web.dart on Dart-on-JS / Wasm; web_time_provider_stub.dart throws on native).defaultTimeProvider — platform-aware constant exported from lib/src/util/default_time_provider.dart. Native targets resolve to SystemTimeProvider; web targets to WebTimeProvider. Selected at compile time via dart.library.js_interop, the modern Wasm-compatible check.Plumbed through APITracerProvider.timeProvider → APITracer.timeProvider → APISpan._timeProvider so span starts, ends, and events all source their timestamps from the same clock. APISpan.addEventNow and addEvents(Map) now route through the span's _timeProvider rather than the static OTelFactory.spanEventNow shortcut, which was hardcoded to DateTime.now and silently dropped sub-millisecond precision when the provider was a WebTimeProvider.
Why this matters on web. DateTime.now() on Dart-on-JS is millisecond-precision — the underlying source is JS Date.now(), and microsecondsSinceEpoch returns millisecondsSinceEpoch × 1000 (the lower three digits are always zero, regardless of the Int64 storage type used by OTLP). WebTimeProvider routes through the browser performance API: ~5µs nominal precision, browser-coarsened to ~100µs as a Spectre mitigation, still 10–200× better than Date.now(). Native targets are unaffected and stay at DateTime.now's 1µs floor.
Auto-default on web. Web users do not have to opt in — constructing an APITracerProvider on a web target automatically gets WebTimeProvider via defaultTimeProvider. To override (e.g., a fake clock in tests), assign tracerProvider.timeProvider = customProvider.
OTelAPI.attributesFromSemanticMap({Enum.value: ...}) for typed-enum-keyed attribute maps in place of OTelAPI.attributesFromMap({Enum.value.key: ...}) / Attributes.of({Enum.value.key: ...}) / <String, Object>{...}.toAttributes(). The shorter form drops the .key accessor on every entry while keeping the typed-enum-key principle. Mixing different semconv enum types in one map is fine — the param is Map<OTelSemantic, Object> and every semconv enum implements OTelSemantic. No API surface change; attributesFromSemanticMap has existed since beta-era.OTelAPI.loggerProviders(). Returns the global default APILoggerProvider plus any named providers added via OTelAPI.addLoggerProvider(name). Parallel t
OTelAPI.loggerProviders(). Returns the global default APILoggerProvider plus any named providers added via OTelAPI.addLoggerProvider(name). Parallel to the existing tracerProviders() and meterProviders(). Backed by a new OTelFactory.getLoggerProviders() so SDK implementations get the same enumeration. Lets OTel.shutdown() in the SDK iterate over named LoggerProviders the way it already does for tracer / meter providers, without this, OTel.addLoggerProvider(name) consumers had to remember to shut each one down manually.Breaking: ServiceResource.serviceResourcepace (key service.Resourcepace) was a mangled find/replace artifact (Name → Resource accidentally hit service
ServiceResource.serviceResourcepace (key service.Resourcepace) was a mangled find/replace artifact (Name → Resource accidentally hit serviceNamespace). Restored the correct OTel semconv entry: ServiceResource.serviceNamespace with key service.namespace. Migration: replace ServiceResource.serviceResourcepace with ServiceResource.serviceNamespace.DatabaseResource.dbCollectionName (db.collection.name), current OTel semconv key, replaces the deprecated db.sql.table.
DatabaseResource.dbCollectionName (db.collection.name), current OTel semconv key, replaces the deprecated db.sql.table.DatabaseResource.dbResponseReturnedRows (db.response.returned_rows), current OTel semconv key for the row count returned by a database operation.UserSemantics.userRoles (user.roles), current OTel semconv key, an array of roles assigned to a user.AppAttribute enum to ExampleAttribute (so readers can't blindly copy the name) and dropped the redundant app. prefix from invented demo keys. Where current OTel semconv keys exist, the example now uses the API's typed enums (e.g. DatabaseResource.dbCollectionName, UserSemantics.userRoles) instead of an app-defined fallback.UserSemantics.userRole (singular user.role). The singular form is an anti-pattern. Users typically have multiple roles. Use UserSemantics.userRoles (user.roles) and pass a List<String> instead.Context.runIsolate() now marks the deserialized SpanContext as isRemote = true on the receiving side. Previously the parent isolate's local SpanContex
Context.runIsolate() now marks the deserialized SpanContext as isRemote = true on the receiving side. Previously the parent isolate's local SpanContext (with isRemote = false) was restored verbatim, so tracer.startSpan in the new isolate fell into the "no parent" branch and produced a fresh root span instead of a child of the parent. This now matches the W3C trace-context-from-HTTP semantic, a SpanContext that crossed a process or isolate boundary is treated as remote and parented correctly.(Thank you to Kevin Moore @kevmoo) Context.run() and Context.runSync(). Zone-based implicit context propagation. These are the spec-aligned way to att
Context.run() and Context.runSync(). Zone-based implicit context propagation. These are the spec-aligned way to attach a context for a scope of execution and ensure it propagates correctly across awaits and async callbacks.isTransferable flag on ContextKey (default false) to opt custom keys into cross-isolate transfer via Context.runIsolate().ServerResource and UrlResource semantic resource enums.tracer.startSpan() no longer automatically activates the span in the current context, aligning with the OpenTelemetry specification. Use tracer.withSpan / withSpanAsync (or Context.runSync / Context.run) to make a span active for a scope.Context.currentWithBaggage() is now pure. It returns a Context with Baggage but no longer mutates Context.current. Pair the returned Context with runSync / run if you need it active.ContextKey are no longer transferred across isolate boundaries by default. Pass isTransferable: true when creating the key to opt in. Built-in Baggage and SpanContext continue to transfer unconditionally.APITracer.withSpan() and withSpanAsync() now use Zone-based context propagation (Context.runSync / Context.run) for correct behavior across async boundaries (no-op implementation only).Context.current setter. Setting it does not propagate across Zones, which produces incorrect context inside async callbacks. Use Context.run() or Context.runSync() instead.APITracer.createSpan() now correctly inherits parent spans from the provided context parameter or Context.current. Previously these were ignored.Context.runIsolate() now serializes the specific Context instance it was called on, not the global Context.current.Context.runIsolate() no longer mutates the parent isolate's _currentContext on return. Eliminates a case where Zone-bound context could leak into the parent's static field.nowAsNanos() no longer loses precision on JS. The 64-bit wrap now happens before the multiplication by 1000.Documentation, updated to 1.0.0-alpha release candidate, matching dartastic_opentelemetry
Documentation, updated to 1.0.0-alpha release candidate, matching dartastic_opentelemetry
Stable-channel republication of 1.0.0-rc.3 . The code is the rc's code with a stable version stamp, so users who have not opted into prereleases get t
Stable-channel republication of 1.0.0-rc.3. The code is the rc's code with a
stable version stamp, so users who have not opted into prereleases get the
fixes. See the 1.0.0-rc.3 entry for detail.
Stable-channel republication of 1.0.0-rc.3. The code is the rc's code with a
stable version stamp, so users who have not opted into prereleases get the
fixes. See the 1.0.0-rc.3 entry for detail. The changes listed below are the
delta against 0.10.0, the previous stable release, not against the previous
prerelease.
enabled is now isEnabled() on tracers, loggers and
instruments, and the enabled constructor parameter is removed. Replace
x.enabled with x.isEnabled().
(#105)getTracer, getLogger and getMeter no longer invent a
scope version or schema URL. Both are null when you omit them.
(#108)Stable-channel republication of 1.0.0-rc.2 — the first stable-channel release since 0.9.1 . The code is the rc's code with a stable version stamp, so
Stable-channel republication of 1.0.0-rc.2 — the first stable-channel
release since 0.9.1. The code is the rc's code with a stable version
stamp, so users who have not opted into prereleases get the fixes. See
the 1.0.0-beta.* through 1.0.0-rc.2 entries for the complete history
since 0.9.1.
1.0.0-rc.1's removal of 116 vendor/RUM identifiers that were notdoc/SEMCONV_CANDIDATES.md mapsOTelAPI.setErrorHandler — configure where the library's internalContext.runIsolate carries theSpan.end() no longer fabricates an OkCompositePropagator.extract runs in registration order, andContext.withSpanContext derives instead of throwing.browser.web_vital.* set, plus an @experimental candidates/Stable-channel republication of 1.0.0-rc.2. The first stable-channel
release since 0.9.1. The code is the rc's code with a stable version
stamp, so users who have not opted into prereleases get the fixes. See
the 1.0.0-beta.* through 1.0.0-rc.2 entries for the complete history
since 0.9.1. The changes listed below are the delta against 0.9.1,
the previous stable release, not against the previous prerelease.
The highlights, for anyone coming from 0.9.1:
OTelAPI.setErrorHandler. Configure where the library's internal
error reports go. The default logs and never throws; a strict handler
can crash-fast in development; Context.runIsolate carries the
handler into child isolates.Span.end() no longer fabricates an Ok
status, CompositePropagator.extract runs in registration order, and
Context.withSpanContext derives instead of throwing.browser.web_vital.* set, plus an @experimental candidates/
staging area for keys proposed upstream.1.0.0-rc.1's removal of 116 vendor/RUM identifiers that were not
OpenTelemetry semantic conventions. doc/SEMCONV_CANDIDATES.md maps
every removal to its registry replacement, a staged candidate, or a
recorded reason for dropping it.Stable-channel republication of 1.0.0-rc.1 — identical content, published so ^0.9.0 users and default dart pub add get current code.
Stable-channel republication of 1.0.0-rc.1 — identical content, published so ^0.9.0 users and default dart pub add get current code.
Logs signal, kudos to https://github.com/yuzurihaaa
Logs signal, kudos to https://github.com/yuzurihaaa
Fixed default logging behavior to log INFO
Fixed default logging behavior to log INFO
adjusted meta dependency down to 1.16
bumped all dependencies to latest
### Changed - added span addXXXAttribute - InstrumentationScope toString
### Changed - SpanEvent toString
Attributes toString uses toJson
Added instrumentationScope() to API
getTracerProviders/getMeterProviders
Initial public release of the OpenTelemetry API for Dart
Your coding agent can read these notes before it upgrades. Set up the MCP server →