dartastic_opentelemetry
OpenTelemetry SDK for Dart and Flutter. Distributed tracing, metrics, OTLP exporters (gRPC/HTTP), and context propagation for observability backends.
0.10.0
73K downloads/mo
#1264 most downloaded on pub.dev
MindfulSoftwareLLC/dartastic_opentelemetry
What this package is like to depend on
Last release today
23 Aug 2026
Ships unpredictably
gaps range from 8 days to 5 months
Nearly every release is documented
notes for 15 of 15 stable releases
Nothing withdrawn
no release was ever pulled
1 years old
33 releases · first in 2025
28 releases in the last 12 months
see the full history below
Release timeline
33 releases · May 2025 to Aug 2026Releases
latest 33-
1.1.0-beta.1423 Aug 2026 pre-releaseRelease notes
Open source →Changed
-
Requires
dartastic_opentelemetry_api^1.0.0-rc.2. Picks up the
semantic conventions at registry v1.44.0 — including the full
browser.web_vital.*set — and three spec-compliance fixes.One of those changes behaviour visible from this package:
Context.withSpanContextnow returns a derived Context when the incoming
span context belongs to a different trace, instead of throwing
ArgumentError. Per the Context specification a set-value operation always
returns a derived Context, and per the Propagators APIextractmust never
throw — receiving a valid span context for another trace during extraction
is ordinary, not an error. Four tests that asserted the throw now assert the
derived Context.SDKSpan.end()no longer forwards the deprecatedspanStatusargument to
its delegate;setStatus()had already applied it to the same delegate, so
the second pass was redundant. -
BREAKING (spec compliance): sampler decisions are now honored end to end
(#120, #121, #122, #123, #129). ADropdecision produces a non-recording
span that reaches no processor;RecordOnlyrecords without setting the
W3CSampledflag; built-in processors deliver only recording spans to
onStart/onEndand only sampled spans to exporters, per the spec's
IsRecording/Sampled reaction table; the forbidden Sampled+non-recording
combination is unrepresentable;createSpanroutes through the sampler and
processors instead of bypassing them. Code that relied on unsampled or
dropped spans being exported must adjust its sampler configuration. -
BREAKING (spec compliance): the default sampler is now
ParentBased(root: AlwaysOn)instead of bareAlwaysOn(#126). Root
spans still sample by default, but child spans of unsampled remote or local
parents now respect the parent's decision. Pass
sampler: const AlwaysOnSampler()to restore the old behavior. -
Child spans inherit the parent
TraceState(#124), and
SamplingResultgains atraceStatefield (#125) so samplers can
modify or replace it:nullkeeps the inherited parent TraceState, an
explicitly emptyTraceStateclears it. Existing custom samplers keep
working unchanged. -
BREAKING:
OTelEnvconfiguration functions (getOtlpConfig,getBspConfig,getServiceConfig,getLogRecordLimits, etc.) now return strongly-typed Dart Records instead ofMap<String, dynamic>.
Migration hint: Update map accesses to record property accesses (e.g.,config['endpoint'] as String?→config.endpoint).
Added
-
TracerProvider.hasSpanProcessors— allocation-free check for registered
span processors. -
OTLP exporters send an identifying
User-Agentheader. Per the OTLP
spec, OTLP requests SHOULD identify the exporter, language, and version.
Every OTLP request now carriesOTel-OTLP-Exporter-Dart/<version>(HTTP
headers on the HTTP exporters;ChannelOptions.userAgenton the gRPC
exporters). A user-supplieduser-agentheader is prepended to the default
rather than replacing it (#228). -
OTel.defaultGrpcEndpoint(http://localhost:4317), the OTLP/gRPC
default endpoint. The endpoint default is now picked per signal after the
protocol is resolved instead of defaulting everything to the HTTP port
4318 (#220).
Fixed
-
browser.*resource attributes anduser_agent.originalare now
populated on web (#190). Invalid@JSbindings made the web resource
detector throw on first use; the error was swallowed and the attributes
were silently missing. A detector failure now omits attributes instead of
emitting blanks. -
browser.mobileis now a boolean, which is how the registry types it.
It was emitted as the string'true'/'false', so a backend filtering
browser.mobile = truematched nothing. -
browser.languagesis now a string array, and its key comes from the
API. It was a comma-joined string under a key this package declared
privately. The naming rules say an attribute that can represent multiple
entities "SHOULD be pluralized and the value type SHOULD be an array",
which is also how the registry shapes the neighbouringbrowser.brands.
The key is nowBrowserCandidate.browserLanguages, staged in the API as an
upstream candidate, so the name and the argument for it live in one place.
It is set only when the browser reports languages: an empty array is a real
value on the wire and would claim the browser accepts none. -
browser.vendoris no longer emitted.navigator.vendoris a frozen
legacy API that returns a hardcoded vendor string rather than the real
vendor, and the registry'sbrowser.brandsis the structured answer to
the same question. -
browser.mobileis now correct on iPad. Since iPadOS 13 an iPad
requests desktop sites by default and reports aMacintoshuser agent,
so a user-agent test alone reported every iPad as a desktop. The
detector now also consultsnavigator.maxTouchPoints, which
distinguishes a touch device from a Mac. A touchscreen laptop is still
not mobile — both signals have to agree. -
OtlpHttpMetricExporter.forceFlush()andshutdown()now await
in-flight exports (#262). Both returned immediately, andshutdown()
closed the HTTP client under the live request — failing an export that
was about to succeed. Now matches the span and log HTTP exporters. -
Tracer.enablednow returnsfalsewhenTracerProviderhas no span
processor(s) registered, per the Trace SDK spec, sparing span-creation cost
when nothing is listening. Thanks to @abidiahmedcom (#138, #175). -
OTLP/gRPC exporters now default to port 4317, not 4318. The OTLP spec
defaults the endpoint tohttp://localhost:4317for OTLP/gRPC and
http://localhost:4318for the two HTTP protocols. Previously a single
4318 default was applied before the protocol was known, so gRPC-only
deployments silently exported to the wrong port (#220). -
An empty environment variable value is treated as unset. Per the spec,
an empty value of an environment variable MUST be interpreted the same way
as when the variable is unset.EnvironmentService.getValuenow normalizes
empty strings tonull, so every consumer (endpoint, protocol, service
name, log level, …) reads an empty value as unset (#213).Thanks to @abidiahmedcom; reported by @yuzurihaaa (#213, #220, #228).
-
service.nameinOTEL_RESOURCE_ATTRIBUTESno longer overrides an
explicitserviceName:argument orOTEL_SERVICE_NAME(#103).
Precedence is now, highest first: explicit argument,OTEL_SERVICE_NAME,
OTEL_RESOURCE_ATTRIBUTES, default.service.versionfollows the same
order. -
OTEL_LOG_LEVELnow takes effect at the start ofOTel.initialize, so
debug logging covers the environment parsing itself. -
Baggage values containing
=(e.g. base64 padding) are no longer
dropped on extract, and an unparsablebaggageheader leaves existing
baggage untouched instead of clearing it. Thanks to @abidiahmedcom
(#199, #200, #261).
Release notes
Open source →Changed
-
Requires
dartastic_opentelemetry_api^1.0.0-rc.2. Picks up the semantic conventions at registry v1.44.0 — including the fullbrowser.web_vital.*set — and three spec-compliance fixes.One of those changes behaviour visible from this package:
Context.withSpanContextnow returns a derived Context when the incoming span context belongs to a different trace, instead of throwingArgumentError. Per the Context specification a set-value operation always returns a derived Context, and per the Propagators APIextractmust never throw — receiving a valid span context for another trace during extraction is ordinary, not an error. Four tests that asserted the throw now assert the derived Context.SDKSpan.end()no longer forwards the deprecatedspanStatusargument to its delegate;setStatus()had already applied it to the same delegate, so the second pass was redundant. -
BREAKING (spec compliance): sampler decisions are now honored end to end (#120, #121, #122, #123, #129). A
Dropdecision produces a non-recording span that reaches no processor;RecordOnlyrecords without setting the W3CSampledflag; built-in processors deliver only recording spans toonStart/onEndand only sampled spans to exporters, per the spec's IsRecording/Sampled reaction table; the forbidden Sampled+non-recording combination is unrepresentable;createSpanroutes through the sampler and processors instead of bypassing them. Code that relied on unsampled or dropped spans being exported must adjust its sampler configuration. -
BREAKING (spec compliance): the default sampler is now
ParentBased(root: AlwaysOn)instead of bareAlwaysOn(#126). Root spans still sample by default, but child spans of unsampled remote or local parents now respect the parent's decision. Passsampler: const AlwaysOnSampler()to restore the old behavior. -
Child spans inherit the parent
TraceState(#124), andSamplingResultgains atraceStatefield (#125) so samplers can modify or replace it:nullkeeps the inherited parent TraceState, an explicitly emptyTraceStateclears it. Existing custom samplers keep working unchanged. -
BREAKING:
OTelEnvconfiguration functions (getOtlpConfig,getBspConfig,getServiceConfig,getLogRecordLimits, etc.) now return strongly-typed Dart Records instead ofMap<String, dynamic>. Migration hint: Update map accesses to record property accesses (e.g.,config['endpoint'] as String?→config.endpoint).
Added
-
TracerProvider.hasSpanProcessors— allocation-free check for registered span processors. -
OTLP exporters send an identifying
User-Agentheader. Per the OTLP spec, OTLP requests SHOULD identify the exporter, language, and version. Every OTLP request now carriesOTel-OTLP-Exporter-Dart/<version>(HTTP headers on the HTTP exporters;ChannelOptions.userAgenton the gRPC exporters). A user-supplieduser-agentheader is prepended to the default rather than replacing it (#228). -
OTel.defaultGrpcEndpoint(http://localhost:4317), the OTLP/gRPC default endpoint. The endpoint default is now picked per signal after the protocol is resolved instead of defaulting everything to the HTTP port 4318 (#220).
Fixed
-
browser.*resource attributes anduser_agent.originalare now populated on web (#190). Invalid@JSbindings made the web resource detector throw on first use; the error was swallowed and the attributes were silently missing. A detector failure now omits attributes instead of emitting blanks. -
browser.mobileis now a boolean, which is how the registry types it. It was emitted as the string'true'/'false', so a backend filteringbrowser.mobile = truematched nothing. -
browser.languagesis now a string array, and its key comes from the API. It was a comma-joined string under a key this package declared privately. The naming rules say an attribute that can represent multiple entities "SHOULD be pluralized and the value type SHOULD be an array", which is also how the registry shapes the neighbouringbrowser.brands. The key is nowBrowserCandidate.browserLanguages, staged in the API as an upstream candidate, so the name and the argument for it live in one place. It is set only when the browser reports languages: an empty array is a real value on the wire and would claim the browser accepts none. -
browser.vendoris no longer emitted.navigator.vendoris a frozen legacy API that returns a hardcoded vendor string rather than the real vendor, and the registry'sbrowser.brandsis the structured answer to the same question. -
browser.mobileis now correct on iPad. Since iPadOS 13 an iPad requests desktop sites by default and reports aMacintoshuser agent, so a user-agent test alone reported every iPad as a desktop. The detector now also consultsnavigator.maxTouchPoints, which distinguishes a touch device from a Mac. A touchscreen laptop is still not mobile — both signals have to agree. -
OtlpHttpMetricExporter.forceFlush()andshutdown()now await in-flight exports (#262). Both returned immediately, andshutdown()closed the HTTP client under the live request — failing an export that was about to succeed. Now matches the span and log HTTP exporters. -
Tracer.enablednow returnsfalsewhenTracerProviderhas no span processor(s) registered, per the Trace SDK spec, sparing span-creation cost when nothing is listening. Thanks to @abidiahmedcom (#138, #175). -
OTLP/gRPC exporters now default to port 4317, not 4318. The OTLP spec defaults the endpoint to
http://localhost:4317for OTLP/gRPC andhttp://localhost:4318for the two HTTP protocols. Previously a single 4318 default was applied before the protocol was known, so gRPC-only deployments silently exported to the wrong port (#220). -
An empty environment variable value is treated as unset. Per the spec, an empty value of an environment variable MUST be interpreted the same way as when the variable is unset.
EnvironmentService.getValuenow normalizes empty strings tonull, so every consumer (endpoint, protocol, service name, log level, …) reads an empty value as unset (#213).Thanks to @abidiahmedcom; reported by @yuzurihaaa (#213, #220, #228).
-
service.nameinOTEL_RESOURCE_ATTRIBUTESno longer overrides an explicitserviceName:argument orOTEL_SERVICE_NAME(#103). Precedence is now, highest first: explicit argument,OTEL_SERVICE_NAME,OTEL_RESOURCE_ATTRIBUTES, default.service.versionfollows the same order. -
OTEL_LOG_LEVELnow takes effect at the start ofOTel.initialize, so debug logging covers the environment parsing itself. -
Baggage values containing
=(e.g. base64 padding) are no longer dropped on extract, and an unparsablebaggageheader leaves existing baggage untouched instead of clearing it. Thanks to @abidiahmedcom (#199, #200, #261).
-
-
1.1.0-beta.1313 Aug 2026 pre-releaseRelease notes
Open source →Security
-
OTLP header values are no longer written to the debug log. Two leaks are fixed:
- Debug logging logged the raw values of all
OTEL_EXPORTER_OTLP_HEADERSand the
signal-specificOTEL_EXPORTER_OTLP_{TRACES,METRICS,LOGS}_HEADERS. The message was
emitted above the per-header loop that redactsAuthorization, so the credential
reached the log regardless of that redaction. Thanks to @arpitjain099 (#100). OtlpHttpSpanExporterandOtlpHttpLogRecordExporterprinted every header value
exceptAuthorization, at construction and on each export request — including
headers configured in code, which never pass through an environment variable.
Who is affected: applications running with
OTEL_LOG_LEVEL=DEBUG(orOTelLogat
debug) and a credential in an OTLP header, from the environment or from exporter
config. Treat any debug logs collected from an affected build as containing that
credential and rotate it.Tracked as GHSA-4rh6-c2v5-374w (CWE-532). Affects
>= 1.0.0-alphaon this
line and>= 0.9.0on the stable channel; see the 0.9.8 entry. - Debug logging logged the raw values of all
Added
OTEL_DART_HEADER_LOG_ALLOWLIST, andOTel.initialize(otlpHeaderLogAllowlist:),
name the OTLP headers whose values may appear in the debug log (#96).
Names match exactly, case insensitively; the code parameter replaces
the environment variable rather than adding to it;authorizationand
proxy-authorizationare never logged even when listed. Thanks to @arpitjain099 (#101).
Changed
- Debug logs now print
name: [REDACTED]for any header value not on the allowlist,
replacingAuthorization: [REDACTED - length: N]— the length is dropped on purpose,
since it narrows the search space for the token. Header names and the header count are
still logged. A header value you relied on seeing at debug level now has to be listed
inOTEL_DART_HEADER_LOG_ALLOWLIST.
Release notes
Open source →Security
-
OTLP header values are no longer written to the debug log. Two leaks are fixed:
- Debug logging logged the raw values of all
OTEL_EXPORTER_OTLP_HEADERSand the signal-specificOTEL_EXPORTER_OTLP_{TRACES,METRICS,LOGS}_HEADERS. The message was emitted above the per-header loop that redactsAuthorization, so the credential reached the log regardless of that redaction. Thanks to @arpitjain099 (#100). OtlpHttpSpanExporterandOtlpHttpLogRecordExporterprinted every header value exceptAuthorization, at construction and on each export request — including headers configured in code, which never pass through an environment variable.
Who is affected: applications running with
OTEL_LOG_LEVEL=DEBUG(orOTelLogat debug) and a credential in an OTLP header, from the environment or from exporter config. Treat any debug logs collected from an affected build as containing that credential and rotate it.Tracked as GHSA-4rh6-c2v5-374w (CWE-532). Affects
>= 1.0.0-alphaon this line and>= 0.9.0on the stable channel; see the 0.9.8 entry. - Debug logging logged the raw values of all
Added
OTEL_DART_HEADER_LOG_ALLOWLIST, andOTel.initialize(otlpHeaderLogAllowlist:), name the OTLP headers whose values may appear in the debug log (#96). Names match exactly, case insensitively; the code parameter replaces the environment variable rather than adding to it;authorizationandproxy-authorizationare never logged even when listed. Thanks to @arpitjain099 (#101).
Changed
- Debug logs now print
name: [REDACTED]for any header value not on the allowlist, replacingAuthorization: [REDACTED - length: N]— the length is dropped on purpose, since it narrows the search space for the token. Header names and the header count are still logged. A header value you relied on seeing at debug level now has to be listed inOTEL_DART_HEADER_LOG_ALLOWLIST.
-
-
1.1.0-beta.1220 Jul 2026 pre-releaseRelease notes
Open source →Changed
- Internal attribute keys now come from the generated registry enums
(Service.*,ExceptionAttributes.*,Otel.*) instead of string
literals, across resource creation, exception recording, the
package:loggingbridge, the OTLP span/log transformers, the sampler,
and the env resource-attribute parsing. A mistyped key is now a compile
error — the same hardening applied to the resource detector after #90.
No wire change:Enum.keyresolves to the identical registry string.
Fixed
host.archno longer reports the hostname (#90). The IO resource
detector copy-pastedPlatform.localHostnameintohost.arch; it now
resolves the real CPU architecture (amd64/arm64/arm32/x86/…)
fromPlatform.version, mapped to registry values, and omits the
attribute when it can't be parsed. Fixes downstream consumers that
select per-architecture artifacts (e.g. debug symbols) off the resource.- The IO detector now keys every attribute from the generated registry
enums (Host.*,Os.*,ProcessAttributes.*) instead of string
literals, so a mistyped key is a compile error — the class of bug that
caused #90. The malformedhost.os.nameis corrected toos.name.
Removed
- The IO resource detector no longer emits
host.processors,
host.locale, orprocess.num_threads— none are OpenTelemetry
registry attributes.
Release notes
Open source →Changed
- Internal attribute keys now come from the generated registry enums
(
Service.*,ExceptionAttributes.*,Otel.*) instead of string literals, across resource creation, exception recording, thepackage:loggingbridge, the OTLP span/log transformers, the sampler, and the env resource-attribute parsing. A mistyped key is now a compile error — the same hardening applied to the resource detector after #90. No wire change:Enum.keyresolves to the identical registry string.
Fixed
host.archno longer reports the hostname (#90). The IO resource detector copy-pastedPlatform.localHostnameintohost.arch; it now resolves the real CPU architecture (amd64/arm64/arm32/x86/…) fromPlatform.version, mapped to registry values, and omits the attribute when it can't be parsed. Fixes downstream consumers that select per-architecture artifacts (e.g. debug symbols) off the resource.- The IO detector now keys every attribute from the generated registry
enums (
Host.*,Os.*,ProcessAttributes.*) instead of string literals, so a mistyped key is a compile error — the class of bug that caused #90. The malformedhost.os.nameis corrected toos.name.
Removed
- The IO resource detector no longer emits
host.processors,host.locale, orprocess.num_threads— none are OpenTelemetry registry attributes.
- Internal attribute keys now come from the generated registry enums
-
1.1.0-beta.1120 Jul 2026 pre-release -
1.1.0-beta.1020 Jul 2026 pre-releaseRelease notes
Open source →Fixed
W3CBaggagePropagator.extractno longer discards the incoming
context when thebaggageheader is absent (#87). It returned a
fresh context instead of the passed one, so in the spec-default
composite (tracecontext, then baggage) any request carrying
traceparentbut nobaggageheader lost its just-extracted span
context — breaking traces at every service boundary unless callers
hand-ordered extraction. Per the Propagators API spec, extract now
returns the passed context unchanged when there is nothing to extract.- OTLP endpoint schemes now determine TLS per the OTLP spec (#88).
http://endpoints connect insecure andhttps://secure;
OTEL_EXPORTER_OTLP_INSECURE(and per-signal variants) applies only
to scheme-less endpoints, and an explicit programmaticsecurestill
wins. PreviouslyOTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4317
attempted TLS and failed with a HandshakeException unless the
insecure flag was also set. Resolution is shared across all three
signals viaOTelEnv.resolveOtlpSecure; metrics additionally now
honorOTEL_EXPORTER_OTLP_METRICS_INSECURE, which was parsed but
ignored.
Fixed
- OTLP/JSON enum fields are now encoded as integers per the OTLP spec,
not proto3-JSON's default enum names: spankind, statuscode, log
severityNumber, metricaggregationTemporality. Same origin story as
the 1.1.0-beta.7 hex-id fix —toProto3Json()'s defaults deviate from
the OTLP spec, lenient receivers masked it, and a strict
cross-implementation check (the Dartastic engine wire-parity harness)
caught it. Conversion is field-keyed and prefix-guarded, so attribute
string values that merely resemble enum names are never touched.
Added
- Public
MetricTransformer.transformMetricsone-shot — the metrics
analogue ofOtlpLogRecordTransformer.transformLogRecords: converts a
wholeMetricDatabatch to a ready-to-serialize OTLP
ExportMetricsServiceRequest(transformMetrics(data).writeToBuffer()),
so alternative exporters and sinks can reuse the transform instead of
re-implementing the per-metric mapping. Both bundled OTLP metric
exporters (HTTP and gRPC) now build their requests through it, removing
two hand-rolled copies of the same assembly; wire output is unchanged
(same instrumentation-scope constant, sameOTel.resource(null)
fallback, resolved by the caller so the transformer stays a pure leaf).
Release notes
Open source →Fixed
W3CBaggagePropagator.extractno longer discards the incoming context when thebaggageheader is absent (#87). It returned a fresh context instead of the passed one, so in the spec-default composite (tracecontext, then baggage) any request carryingtraceparentbut nobaggageheader lost its just-extracted span context — breaking traces at every service boundary unless callers hand-ordered extraction. Per the Propagators API spec, extract now returns the passed context unchanged when there is nothing to extract.- OTLP endpoint schemes now determine TLS per the OTLP spec (#88).
http://endpoints connect insecure andhttps://secure;OTEL_EXPORTER_OTLP_INSECURE(and per-signal variants) applies only to scheme-less endpoints, and an explicit programmaticsecurestill wins. PreviouslyOTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4317attempted TLS and failed with a HandshakeException unless the insecure flag was also set. Resolution is shared across all three signals viaOTelEnv.resolveOtlpSecure; metrics additionally now honorOTEL_EXPORTER_OTLP_METRICS_INSECURE, which was parsed but ignored.
Fixed
- OTLP/JSON enum fields are now encoded as integers per the OTLP spec,
not proto3-JSON's default enum names: span
kind, statuscode, logseverityNumber, metricaggregationTemporality. Same origin story as the 1.1.0-beta.7 hex-id fix —toProto3Json()'s defaults deviate from the OTLP spec, lenient receivers masked it, and a strict cross-implementation check (the Dartastic engine wire-parity harness) caught it. Conversion is field-keyed and prefix-guarded, so attribute string values that merely resemble enum names are never touched.
Added
- Public
MetricTransformer.transformMetricsone-shot — the metrics analogue ofOtlpLogRecordTransformer.transformLogRecords: converts a wholeMetricDatabatch to a ready-to-serialize OTLPExportMetricsServiceRequest(transformMetrics(data).writeToBuffer()), so alternative exporters and sinks can reuse the transform instead of re-implementing the per-metric mapping. Both bundled OTLP metric exporters (HTTP and gRPC) now build their requests through it, removing two hand-rolled copies of the same assembly; wire output is unchanged (same instrumentation-scope constant, sameOTel.resource(null)fallback, resolved by the caller so the transformer stays a pure leaf).
Changed
- OTEL_BLRP_ env var validation now warns on invalid values* — previously,
invalid
OTEL_BLRP_SCHEDULE_DELAYandOTEL_BLRP_EXPORT_TIMEOUTvalues were silently ignored; they now emitOTelLog.warndiagnostics consistent with BSP behavior.OTEL_BLRP_SCHEDULE_DELAY=0is now accepted as valid (meaning "export as fast as possible"), andOTEL_BLRP_EXPORT_TIMEOUT=0means "no limit", mirroring BSP semantics. OTelEnv._getPositiveIntEnvnow warns on unusable values — non-numeric, below-minimum, and above-maximum values all emitOTelLog.warn, giving consistent diagnostics to every caller without per-site bookkeeping.OTelEnv.getBlrpConfig()simplified to raw env reading — domain-level defaults, validation, and batch-to-queue clamping moved toBatchLogRecordProcessorConfig.fromEnvironment().
-
1.1.0-beta.918 Jul 2026 pre-releaseRelease notes
Open source →Changed
- Adopt
dartastic_opentelemetry_api1.0.0-rc.1 (constraint
^1.0.0-rc.1). No SDK code changes were needed: the SDK never used
the removed vendor/RUM enums, and it implements the now-abstract
APIObservableResultinterface. - CI: self-hosted coverage badge built from lcov.info and published to
thebadgesbranch; Codecov upload removed (uploads had failed since
branch protection was enabled). The README coverage badge is now live
data instead of a hardcoded percentage.
Release notes
Open source →Changed
- Adopt
dartastic_opentelemetry_api1.0.0-rc.1 (constraint^1.0.0-rc.1). No SDK code changes were needed: the SDK never used the removed vendor/RUM enums, and it implements the now-abstractAPIObservableResultinterface. - CI: self-hosted coverage badge built from lcov.info and published to
the
badgesbranch; Codecov upload removed (uploads had failed since branch protection was enabled). The README coverage badge is now live data instead of a hardcoded percentage.
- Adopt
-
1.1.0-beta.818 Jul 2026 pre-releaseRelease notes
Open source →Added
OTEL_PROPAGATORSsupport and global propagator wiring.
OTel.initialize()now installs the API's globalTextMapPropagator
per the spec ("Global Propagators"): the default is the W3C
tracecontext,baggagecomposite;none(or no supported values)
leaves the API's spec-mandated no-op in place; unsupported names emit
anOTelLog.warnand are ignored. Supported values:tracecontext,
baggage,none. Instrumentation libraries can now obtain "the"
propagator viaOTelAPI.textMapPropagatorinstead of being handed one
explicitly.OTEL_BSP_*environment variables for configuringBatchSpanProcessor
(OTEL_BSP_SCHEDULE_DELAY,OTEL_BSP_EXPORT_TIMEOUT,OTEL_BSP_MAX_QUEUE_SIZE,
OTEL_BSP_MAX_EXPORT_BATCH_SIZE). Values are read by
BatchSpanProcessorConfig.fromEnvironment()whichOTel.initialize()uses
by default. Invalid or out-of-range values now emitOTelLog.warndiagnostics.
OTEL_BSP_EXPORT_TIMEOUT=0is honored as "no limit" per spec.- Comma-separated
OTEL_*_EXPORTERlists. The spec's "implementation
MAY accept a comma-separated list to enable setting multiple exporters"
is now supported for all three signals:OTEL_TRACES_EXPORTER=otlp,console
installs aCompositeExporter, metrics use aCompositeMetricExporter,
and logs install one processor per exporter.nonein a list wins;
unsupported values (zipkin, the deprecatedlogging) emit an
OTelLog.warnand are ignored; a list with no usable values falls back
to the spec defaultotlp. Previously a list value silently installed
no exporter at all. - Unknown
OTEL_METRICS_EXPORTERvalues now warn and are ignored
instead of silently becomingotlp;prometheusgets a dedicated
warning pointing at programmaticPrometheusExporteruse and the
planned scrape server (#82) — auto-wiring it today would be a silent
no-op since the env-created exporter is unreachable by the app.
Removed
- Breaking:
OTel.initializeno longer acceptsdartasticApiKeyor
tenantId, and theOTel.dartasticApiKeystatic is gone. Both were
non-standard, vendor-specific parameters that predate the platform
layering: API keys belong in OTLP exporter headers
(OTEL_EXPORTER_OTLP_HEADERS) and tenant identity is platform-layer
context, not an SDK concern. Thetenant_idresource-attribute
stamping and its debug-log special-casing are removed with them. - Breaking: the non-standard
OTEL_*-namespace extensions are renamed
or removed. The per-signal diagnostic vars squatted the spec's core
namespace and are renamed to the spec's language-specific convention
(OTEL_{LANGUAGE}_{FEATURE}):OTEL_LOG_SPANS→OTEL_DART_LOG_SPANS,
OTEL_LOG_METRICS→OTEL_DART_LOG_METRICS,OTEL_LOG_EXPORT→
OTEL_DART_LOG_EXPORT(same semantics: enable theOTelLogper-signal
diagnostic sinks; programmatic setters unchanged). The
OTEL_CONSOLE_EXPORTERdart-define is removed — console output of the
telemetry itself uses the standardOTEL_*_EXPORTER=console(or the
comma-list form, e.g.otlp,console).
Changed
- Depends on
dartastic_opentelemetry_api1.0.0-beta.10 and re-exports
its surface: the Weaver-generated semantic-convention enums (90 registry
namespaces incl. entities/metrics/events),NonRecordingSpan, and the
globalTextMapPropagator. SDK consumers referencing renamed semconv
enums through this package inherit the API's breaking renames — the
complete old→new tables are in the API package's 1.0.0-beta.10
CHANGELOG. SDK span creation is unaffected (the API's no-SDK span
behavior only applies without an SDK factory installed). - Examples and tests migrated to the new names (
Db,Server,Code,
Http.httpRequestMethod/httpResponseStatusCode/httpResponseBodySize)
and off registry-deprecated keys: the database examples now emit
db.system.name,db.namespace,db.operation.name, and
db.query.textinstead of the deprecateddb.system/db.name/
db.operation/db.statement, and drop the deprecateddb.user. CompositePropagatoris constructed viaOTelAPI.compositePropagator
(its constructor is factory-only as of the API's beta.10).- Default span batch schedule delay changed from 1 s to 5 s (spec default).
The previous hard-codedBatchSpanProcessorConfig(scheduleDelay: Duration(seconds: 1))
inOTel.initialize()has been replaced byBatchSpanProcessorConfig.fromEnvironment(),
whose fallback is the spec-mandated 5000 ms. To restore the old behavior, set
OTEL_BSP_SCHEDULE_DELAY=1000.
Release notes
Open source →Added
OTEL_PROPAGATORSsupport and global propagator wiring.OTel.initialize()now installs the API's globalTextMapPropagatorper the spec ("Global Propagators"): the default is the W3Ctracecontext,baggagecomposite;none(or no supported values) leaves the API's spec-mandated no-op in place; unsupported names emit anOTelLog.warnand are ignored. Supported values:tracecontext,baggage,none. Instrumentation libraries can now obtain "the" propagator viaOTelAPI.textMapPropagatorinstead of being handed one explicitly.OTEL_BSP_*environment variables for configuringBatchSpanProcessor(OTEL_BSP_SCHEDULE_DELAY,OTEL_BSP_EXPORT_TIMEOUT,OTEL_BSP_MAX_QUEUE_SIZE,OTEL_BSP_MAX_EXPORT_BATCH_SIZE). Values are read byBatchSpanProcessorConfig.fromEnvironment()whichOTel.initialize()uses by default. Invalid or out-of-range values now emitOTelLog.warndiagnostics.OTEL_BSP_EXPORT_TIMEOUT=0is honored as "no limit" per spec.- Comma-separated
OTEL_*_EXPORTERlists. The spec's "implementation MAY accept a comma-separated list to enable setting multiple exporters" is now supported for all three signals:OTEL_TRACES_EXPORTER=otlp,consoleinstalls aCompositeExporter, metrics use aCompositeMetricExporter, and logs install one processor per exporter.nonein a list wins; unsupported values (zipkin, the deprecatedlogging) emit anOTelLog.warnand are ignored; a list with no usable values falls back to the spec defaultotlp. Previously a list value silently installed no exporter at all. - Unknown
OTEL_METRICS_EXPORTERvalues now warn and are ignored instead of silently becomingotlp;prometheusgets a dedicated warning pointing at programmaticPrometheusExporteruse and the planned scrape server (#82) — auto-wiring it today would be a silent no-op since the env-created exporter is unreachable by the app.
Removed
- Breaking:
OTel.initializeno longer acceptsdartasticApiKeyortenantId, and theOTel.dartasticApiKeystatic is gone. Both were non-standard, vendor-specific parameters that predate the platform layering: API keys belong in OTLP exporter headers (OTEL_EXPORTER_OTLP_HEADERS) and tenant identity is platform-layer context, not an SDK concern. Thetenant_idresource-attribute stamping and its debug-log special-casing are removed with them. - Breaking: the non-standard
OTEL_*-namespace extensions are renamed or removed. The per-signal diagnostic vars squatted the spec's core namespace and are renamed to the spec's language-specific convention (OTEL_{LANGUAGE}_{FEATURE}):OTEL_LOG_SPANS→OTEL_DART_LOG_SPANS,OTEL_LOG_METRICS→OTEL_DART_LOG_METRICS,OTEL_LOG_EXPORT→OTEL_DART_LOG_EXPORT(same semantics: enable theOTelLogper-signal diagnostic sinks; programmatic setters unchanged). TheOTEL_CONSOLE_EXPORTERdart-define is removed — console output of the telemetry itself uses the standardOTEL_*_EXPORTER=console(or the comma-list form, e.g.otlp,console).
Changed
- Depends on
dartastic_opentelemetry_api1.0.0-beta.10 and re-exports its surface: the Weaver-generated semantic-convention enums (90 registry namespaces incl. entities/metrics/events),NonRecordingSpan, and the globalTextMapPropagator. SDK consumers referencing renamed semconv enums through this package inherit the API's breaking renames — the complete old→new tables are in the API package's 1.0.0-beta.10 CHANGELOG. SDK span creation is unaffected (the API's no-SDK span behavior only applies without an SDK factory installed). - Examples and tests migrated to the new names (
Db,Server,Code,Http.httpRequestMethod/httpResponseStatusCode/httpResponseBodySize) and off registry-deprecated keys: the database examples now emitdb.system.name,db.namespace,db.operation.name, anddb.query.textinstead of the deprecateddb.system/db.name/db.operation/db.statement, and drop the deprecateddb.user. CompositePropagatoris constructed viaOTelAPI.compositePropagator(its constructor is factory-only as of the API's beta.10).- Default span batch schedule delay changed from 1 s to 5 s (spec default).
The previous hard-coded
BatchSpanProcessorConfig(scheduleDelay: Duration(seconds: 1))inOTel.initialize()has been replaced byBatchSpanProcessorConfig.fromEnvironment(), whose fallback is the spec-mandated 5000 ms. To restore the old behavior, setOTEL_BSP_SCHEDULE_DELAY=1000.
-
1.1.0-beta.711 Jul 2026 pre-releaseRelease notes
Open source →Fixed
OtlpGrpcSpanExporter.export()gains a Dart-level timeout backstop. Previously the configuredtimeoutwas applied only via gRPC'sCallOptionsdeadline. A Dart-level.timeout()now also bounds the RPC and tears down the channel on expiry, as defense-in-depth for real-world hangs where a collector accepts a connection then stops responding. Note (under review): this does NOT fix the concurrency test hang that prompted it — that was event-loop starvation from the gRPC client's reconnect churn, which no Timer-based bound can fix (see the PR discussion). Reviewers are deciding whether to keep this backstop; if dropped, this entry goes with it.- Debug logging no longer adds a
ConsoleExporterto the trace pipeline.OTel.initialize()used to append aConsoleExporterto the span exporters whenever debug logging was enabled (e.g.OTEL_LOG_LEVEL=debug/trace), silently changing the export pipeline shape. Per the OTel spec the default exporter isotlponly — the same cleanup #49 applied to metrics. Console output remains available explicitly:OTEL_TRACES_EXPORTER=console(replaces the exporter) or theOTEL_CONSOLE_EXPORTER--dart-define(adds one alongside). For span logging useOTEL_LOG_SPANS=true.
Added
- Configurable exception handling for
Tracer.withSpan/withSpanAsync. A newSpanExceptionOptions(withrecordException,setStatusOnException, and anexceptionSanitizercallback returning aSanitizedSpanException) lets callers customize how a thrown exception is recorded and whether the span status is set. The defaults preserve the existing behavior (record the exception + setSpanStatusCode.Error), and the original exception is always rethrown. Configure globally viaOTel.initialize(spanExceptionOptions: ...)(also available perTracerProviderandOTel.addTracerProvider) and override per call via the newexceptionOptions:parameter onwithSpan/withSpanAsync/startActiveSpan/startActiveSpanAsyncandOTel.withSpan/OTel.withSpanAsync. Per-call options are merged field-by-field over the global config (viaSpanExceptionOptions.mergeWith), so overriding a single flag preserves a globally configured sanitizer. When a sanitizer is provided, only its returned type/message/stacktrace are recorded — the raw exception's details never leak — and if the sanitizer itself throws, the span is marked failed with a generic description. This enables SDKs and applications to redact PII before it is recorded. (#51)
Fixed
- API-first usage no longer wedges SDK initialization (#50). The API
package auto-installs its no-op
OTelAPIFactorywhen API-only code runs before the SDK initializes (per the OTel spec). PreviouslyOTel.initialize()then failed with "can only be initialized once", andOTel.tracerProvider()crashed with an opaqueAPITracerProvider is not a subtype of TracerProvidercast error.OTel.initialize()now replaces exactly the auto-installed no-op API factory — identified viaOTelFactory.isAPIFactory(API ≥ beta.8), so real factories are never silently replaced — and the SDK accessors (tracerProvider()/meterProvider()/loggerProvider()/addTracerProvider()) throw a clearOTel.initialize() must be called first.StateErrorbefore initialization instead of the cast error.OTelSDKFactorynow overridesisAPIFactorytofalseper the API ≥ beta.8 contract. Note: API objects handed out beforeinitialize()remain no-ops — capture tracers after initialize. Thanks @robert-northmind for the investigation in #53 and the regression test suite adapted from it.
Changed
- Bumped
dartastic_opentelemetry_apito^1.0.0-beta.9. Beta.8 addsOTelFactory.isAPIFactory(used by the fix above) and replaces the no-op factory inOTelAPI.initialize(); beta.9 fixes pre-initialization lazy no-op installs (tracer(),logger(),instrumentationScope(),TraceState.fromString, thefromJsons) and makesContextre-read the global factory so an SDK factory installed later actually takes effect.
-
1.1.0-beta.618 May 2026 pre-releaseRelease notes
Open source →- Bumped
dartastic_opentelemetry_apito^1.0.0-beta.7. Beta.7 fixes observable metrics and standard env var defaults.
Fixed
- Default metrics pipeline no longer prints to stdout.
OTel.initialize()used to wrap the default OTLP metric exporter in aCompositeMetricExporterwithConsoleMetricExporter, so every server using the SDK with zero env vars dumped metric payloads to the console. The default is now OTLP-only, matching traces and logs (and the OTel spec, which specifiesotlpas the default for all three signals — neverconsole). To opt back into stdout output setOTEL_METRICS_EXPORTER=console(or pass an explicitmetricExporter/metricReadertoOTel.initialize).
Added
OTEL_TRACES_EXPORTER/OTEL_METRICS_EXPORTER/OTEL_LOGS_EXPORTERnow honored end-to-end. Each acceptsotlp(default),console, ornone;noneskips processor/reader installation for that signal entirely. Previously onlyOTEL_TRACES_EXPORTERandOTEL_LOGS_EXPORTERwere partially read andOTEL_METRICS_EXPORTERwas ignored.OTEL_SDK_DISABLED=trueglobal off-switch. When set,OTel.initialize()installs no span processors, metric readers, or log record processors — the SDK becomes a no-op for all three signals. Implemented via the newOTelEnv.isSdkDisabled()helper.
- Bumped
-
1.1.0-beta.513 May 2026 pre-releaseRelease notes
Open source →Added
package:dartastic_opentelemetry/testing.dart— opt-in library with the in-memory test harness used by the dart-otel-reference-demo and every OTel-Dart wrapper. ExportsInMemorySpanExporter(withfindSpanByName/findSpansByName/findSpansStartingWith/clear),InMemoryLogExporter,InMemoryMetricExporter,OnDemandMetricReader(timer-free; tests callcollect()explicitly viaTestHarness.collectMetrics),TestHarnessaggregator, andmaybeInitializeOtelForTest()(singleton initializer forsetUpAll). Deliberately not re-exported from the main barrel so production bundles don't carry the test classes — import the/testing.dartpath explicitly. Unifies the test scaffolding across the SDK, the reference demo, and theotel_*wrapper packages; previously each wrapper had its own near-identical copy.
Removed
- Breaking:
Tracer.startSpanWithContextis removed. Deprecated since 1.1.0-beta (released 2026-05-07), four betas ago. Migration is a 1:1 rename —tracer.startSpanWithContext(name: x, context: ctx, kind: k, attributes: a)→tracer.startSpan(x, context: ctx, kind: k, attributes: a). To make the returned span active for a scope, wrap the work withtracer.withSpan(sync) ortracer.withSpanAsync(async); the deprecated method had stopped activating the span as of 1.1.0-beta anyway, so call sites that relied on activation already needed updating. Test suites that exercisedstartSpanWithContextwere migrated in this release.
-
1.1.0-beta.411 May 2026 pre-releaseRelease notes
Open source →Changed
- Bumped
dartastic_opentelemetry_apito^1.0.0-beta.6. Beta.6 is a comprehensive OTel semantic-convention update — see the API CHANGELOG. Headline-level breaking changes consumers will feel:- The
Resourcesuffix was dropped from ~60 attribute-key enums (HttpResource.requestMethod→Http.requestMethod,UrlResource.urlFull→Url.urlFull, etc.). Suffix is kept on six enums that conflict with common Dart / Flutter / library types:ErrorResource,ExceptionResource,FileResource,ProcessResource,ServerResource(package:grpc),EventResource(package:web). UserSemantics→ newUserenum;SessionViewSemanticsis split — OTel-spec keys (session.id,session.previous_id) →Session, non-spec RUM-style keys →RumSessionView.- Two new files in the API:
semantic_metrics.dart(15 enums, ~280 metric instrument names with name + instrument kind + unit) andsemantic_events.dart(16 spec event names). Plus asemantic_values.dartwith typed value-set enums (DbSystem.postgresql,CloudProvider.gcp,HttpRequestMethod.get, etc.). - New
OTelAPI.attributesOf<E extends OTelSemantic>(Map<E, Object>)helper for Dart 3.10 static dot-shorthand.
- The
- Breaking (web only):
WebResourceDetectornow emits the user-agent string underuser_agent.original(the current OTel semconv key, viaUserAgent.userAgentOriginal) instead ofbrowser.user_agent. The browser semconv namespace removedbrowser.user_agentin favor of the top-leveluser_agent.*registry — see https://opentelemetry.io/docs/specs/semconv/registry/attributes/user-agent/. Backends and dashboards that filter on the old key will need to update.
- Bumped
-
1.1.0-beta.311 May 2026 pre-releaseRelease notes
Open source →Added
- OTLP/HTTP-JSON wire format on all three signals.
OtlpHttpSpanExporter,OtlpHttpMetricExporter, andOtlpHttpLogRecordExporternow accept anOtlpHttpProtocolconfig option — defaults tohttpProtobuf(unchanged behaviour), set tohttpJsonto send proto3-JSON-encoded payloads withContent-Type: application/json. The encoding follows the OTLP spec's proto3-to-JSON mapping (request.toProto3Json()on the generated protobuf classes), so no hand-rolled JSON marshaling lives in Dartastic. Wire-up viaOTEL_EXPORTER_OTLP_PROTOCOL=http/json(or signal-specific_TRACES_PROTOCOL/_METRICS_PROTOCOL/_LOGS_PROTOCOL) flows throughOTel.initialize. Per spec,http/jsonisMAY-support, notMUST— adding it lives up to Dartastic's "No skimping: if it's optional in the spec, it's included" promise. Unblocks integration with backends that prefer JSON (Genkit dev UI, browser-based viewers, lightweight collectors).
- OTLP/HTTP-JSON wire format on all three signals.
-
1.1.0-beta.210 May 2026 pre-releaseRelease notes
Open source →Added
- Pluggable
TimeProviderfor span timestamps. Web targets (Dart-on-JS, Wasm) automatically getWebTimeProvider(sub-millisecond viawindow.performance.now()+timeOrigin); native targets keepSystemTimeProvider(DateTime.now, unchanged behaviour). No code change required to pick up the web precision — auto-selected via the API package's platform-awaredefaultTimeProvider. Override viaOTel.initialize(timeProvider: customProvider)for cases like a fake clock in tests. The abstraction lives indartastic_opentelemetry_api(see API beta.5 changelog). The SDK'sTracerProvider.timeProvideris now a delegate getter/setter that reads through to the underlyingAPITracerProvider, so SDK and API share a single source of truth. OTel.attributesFromSemanticMap(Map<OTelSemantic, Object>)— convenience passthrough toOTelAPI.attributesFromSemanticMap. Lets call sites that build attribute maps from typed semconv enums skip the.keyaccessor on every entry:OTel.attributesFromSemanticMap({HttpResource.requestMethod: 'GET'})instead ofOTel.attributesFromMap({HttpResource.requestMethod.key: 'GET'}). Mixing different semconv enum types in one map is fine — the param type is theOTelSemanticinterface that every semconv enum implements.
Changed
- README and every example under
example/now useattributesFromSemanticMapfor typed-enum-keyed maps. The longerattributesFromMapform remains for raw-string-keyed maps ({'foo.bar': value}) and shows up in the README only as a counter-example for app-specific keys without a typed enum. - Bumped
dartastic_opentelemetry_apito^1.0.0-beta.4. Beta.4 addsOTelAPI.loggerProviders()parallel to the existingtracerProviders()/meterProviders().
Fixed
- Named
LoggerProviders now shut down withOTel.shutdown(). Closes the documented gap from beta.1's fix for issue #33. Beta.1 only shut down the defaultLoggerProvider; any provider created viaOTel.addLoggerProvider(name)still kept itsBatchLogRecordProcessor.Timer.periodicalive, parking the Dart isolate aftermain()returned for any consumer with multiple LoggerProviders. With API beta.4's newloggerProviders()enumerator,OTel.shutdown()now iterates all of them the same way it already does for tracer / meter providers.
- Pluggable
-
1.1.0-beta.110 May 2026 pre-releaseRelease notes
Open source →Changed
- Bumped
dartastic_opentelemetry_apito^1.0.0-beta.3. Beta.3 fixes aServiceResourcesemconv key that was mangled by an over-broad find/replace: the entry calledServiceResource.serviceResourcepace(with keyservice.Resourcepace) is restored toServiceResource.serviceNamespace/service.namespace. If you used the misspelled name in your own code, replace it withServiceResource.serviceNamespace.
Fixed
-
BatchSpanProcessor.shutdown()no longer drops queued spans. Two pre-existing bugs in the shutdown path: (1)shutdown()set_isShutdown = truebefore callingforceFlush(), butforceFlush()early-returns when_isShutdown == true— so spans queued at the moment shutdown was invoked were silently dropped. (2)_exportBatch()only exported up tomaxExportBatchSizespans and returned, so even when the drain was reached it stopped after one batch. Brought in line withBatchLogRecordProcessor, which has always drained correctly:shutdown()now drains the queue before setting_isShutdown, and bothshutdown()andforceFlush()loop until the queue is empty (or the exporter throws — bailing on persistent failure rather than spinning forever). -
Process exits cleanly after
OTel.shutdown()(#33): short-lived Dart CLI binaries no longer hang afterawait OTel.shutdown()returns.OTel.shutdown()was iterating over tracer providers and meter providers but not over the defaultLoggerProvider. The defaultBatchLogRecordProcessor'sTimer.periodictherefore stayed alive aftermain()returned, parking the Dart isolate inDart_RunLoopindefinitely (the symptom report describedawait OTel.shutdown()"never returning", but the actual symptom is that process exit hangs —printafterawaitdoes run).OTel.shutdown()now also shuts down the defaultLoggerProvider. Named LoggerProviders (created viaOTel.addLoggerProvider) still need to be shut down by the caller — a follow-up will add aloggerProviders()enumerator to the API soOTel.shutdown()can clean them up automatically. -
Web compatibility:
package:dartastic_opentelemetry/dartastic_opentelemetry.dartis now safe to import on web targets (Flutter web,dart compile js,dart compile wasm). Previously the main library transitively pulled indart:iovia the OTLP/HTTP exporters, certificate utilities, and the platform resource detectors —dart compile jsaccepted these imports thanks to Dart 3 stubs, but the moment any of those classes ran (HttpClient,SecurityContext,Platform.executable, etc.) you gotUnsupportedErrorat runtime. Split into platform-conditional facades:lib/src/resource/native_detectors.dart— exportsProcessResourceDetectorandHostResourceDetectorfrom_io.darton native, from_stub.darton web (stubs throw with a clear migration message if instantiated;PlatformResourceDetector.create()skips them on web by design).lib/src/trace/export/otlp/certificate_utils.dart—_io.dartkeepsvalidateCertificates+createSecurityContext;_stub.dartkeeps onlyvalidateCertificates. The IO-onlycreateSecurityContextis reachable via the IO HTTP exporter path. gRPC exporters importcertificate_utils_io.dartdirectly (gRPC is IO-only by nature).lib/src/trace/export/otlp/http/http_client_factory.dart— new helper that returnsIOClient(HttpClient(...))on native andBrowserClienton web. The three OTLP HTTP exporters (OtlpHttpSpanExporter/OtlpHttpMetricExporter/OtlpHttpLogRecordExporter) lost their directdart:ioimports and now delegate_createHttpClient()to this factory.
Net effect on web: tracer/metrics/logs API works, OTLP/HTTP exporters work via the browser's fetch (browser owns TLS — custom CA / mTLS settings are ignored with a warning),
PlatformResourceDetector.create()returns the env-var + web detector composite.OtlpGrpcSpanExporterand friends remain native-only — gRPC over HTTP/2 trailers isn't a thing in browsers regardless of dart:io.New regression test:
test/web/web_compile_smoke_test.dartruns in Chrome, imports the main library, initializes the SDK, constructs all three HTTP exporters, and runs the platform resource detector. -
dart2wasm:
tool/web_tests.sh(and CI) now runs the web suite under both dart2js (default) and dart2wasm. Caught and fixed a JS-interop bug ingzip_web.dart— theReadableStreamreader yielded aJSUint8Arraythat was being cast directly toUint8List, which works on dart2js but fails withTypeError: 'JSValue' is not a subtype of type 'Uint8List'on dart2wasm. Now goes throughJSUint8Array.toDartso it works on both compilers.
- Bumped
-
1.1.0-beta09 May 2026 pre-releaseRelease notes
Open source →Changed
- Bumped
dartastic_opentelemetry_apito^1.0.0-beta.2(Zone-based context propagation, contributed to the API by Kevin Moore @kevmoo; the cross-isolateisRemotefix in beta.1; newDatabaseResource.dbCollectionName,DatabaseResource.dbResponseReturnedRows, andUserSemantics.userRolessemconv enums in beta.2; and the breaking removal of the singularUserSemantics.userRolein beta.2). - Breaking:
Tracer.withSpanandTracer.withSpanAsyncnow propagate context via Zones (Context.runSync/Context.run) instead of mutating the staticContext.current. Async callbacks within a spanned scope now correctly observe the active span acrossawaitboundaries; concurrentwithSpanAsynccalls no longer race on the global static. - Breaking:
Tracer.startSpanno longer auto-activates the returned span (matching the new API contract and the OpenTelemetry specification). UseOTel.withSpan/OTel.withSpanAsync(or the equivalent onTracer, or thestartActiveSpan/startActiveSpanAsyncconvenience methods) to make a span active for a scope. - Breaking: removed
Tracer.recordSpanandTracer.recordSpanAsync. They were redundant withstartActiveSpan/Async(which expose the span tofn) and the name was unclear ("record what?"). Migration: a one-linertracer.recordSpan(name: x, fn: f)becomesOTel.tracer().startActiveSpan(name: x, fn: (_) => f()). For the explicit lifecycle, usetracer.startSpan(...)+OTel.withSpan(span, fn)+try/catch/finallywithspan.end()infinally. - Added
OTel.withSpan(span, fn)andOTel.withSpanAsync(span, fn)static convenience methods that delegate to the default tracer — saves callers from threading aTracerreference for the common activation case. Both acceptAPISpan(matching the API contract for cross-implementation interop). - Breaking: renamed the SDK
Loggerclass toOTelLoggerto avoid clashing withpackage:logging'sLogger. Migration: replaceLogger(the SDK type) withOTelLoggerin your code.OTel.logger(...)andOTel.loggerProvider().getLogger(...)continue to return the same instances, only the type name changed.LoggerProvider,APILogger, and otherLogger*-prefixed symbols are unchanged. - Breaking:
Tracer.startSpanWithContextno longer mutatesContext.current. It is now a thin wrapper aroundstartSpan(name, context: ctx)and is@Deprecated. Activate the returned span explicitly withTracer.withSpan/withSpanAsync. Tracer.startSpan: when bothcontextandparentSpanare provided with different traces, the explicitparentSpannow wins fortraceIdandtraceFlagsresolution. Previously the SDK would build an internally inconsistent SpanContext (context's traceId + parentSpan's spanId) which the new API validation correctly rejects.Tracer.startSpan: replaced the staleeffectiveContext != Context.rootidentity-style check with a content-based check (effectiveContext.span != null+ always readeffectiveContext.spanContext). The old check skipped parent inheritance wheneverContext.current == Context.root, which is the case inside an isolate spawned viaContext.runIsolate()(the API attaches the propagated context as both the isolate's current and root). Combined with the API beta.1isRemotefix, trace continuity now works end-to-end acrossrunIsolate.
Added
OTel.contextKey<T>(name)now accepts an optionalisTransferableflag (defaultfalse) which is forwarded to the API. Custom context keys must opt in to cross-isolate transfer; built-inBaggageandSpanContextalways transfer.- Re-exported
ServerResourceandUrlResourcesemantic enums from the API. - New regression test (
tracer_methods_test.dart) verifying that concurrentwithSpanAsyncoperations isolate their active span — would catch any future regression of the Zone migration.
Fixed
test/web/util/zip/gzip_web_test.dart: replaced a corrupt hardcoded base64 gzip blob (CRC mismatch — the browser'sDecompressionStream, Python'sgzip, and Node all reject it) with a freshly-generated one (mtime=0for a deterministic header). Pre-existing bug; the test had never passed under a strict gzip decoder.- Tooling:
Makefiletest-safeandtest-webtargets pointed attool/run_tests.shandtool/web_tests.sh, neither of which existed. Repointedtest-safeat the existingtool/test.sh(used by CI). Addedtool/web_tests.shrunningdart test -p chrome ./test/web. - CI: added a
test-webjob to.github/workflows/dart.ymlthat runstool/web_tests.shin Chrome on every push and PR — web tests previously only ran locally on demand. - Documentation: every example file (and every code snippet in the SDK and API READMEs) now uses typed enum keys for span/log/baggage attributes — never raw strings. Examples without a matching OTel-semconv enum define a small local
ExampleAttribute/ExampleBaggage/DemoAttributeenum at the top of the file to demonstrate the recommended pattern (the placeholder name isExampleAttribute/ExampleBaggagerather thanAppAttributeso readers rename it for their domain instead of copying it verbatim; the redundantapp.prefix was also dropped from invented demo keys). Replaces deprecatednet.peer.*,client.ip,http.url,http.response_content_lengthwith their modern semconv equivalents (ServerResource.serverAddress/Port,ClientResource.clientAddress,UrlResource.urlFull,HttpResource.responseBodySize). - Examples updated for spec-aligned behavior:
example.dart,grafana_cloud_env_example.dart,grafana/grafana_cloud_env_example.dart: replaced'url.full'/'url.path'/'net.peer.name'/'net.peer.port'string literals with the newUrlResourceandServerResourceenums.isolate_context_example.dart: rewritten to usetracer.withSpanAsyncso the parent SpanContext propagates intorunIsolate, and to avoid capturing non-sendable SDK objects in the isolate closure. Also dropped a privatesrc/import.propagator_example.dart: built the inject Context fromspan.spanContextdirectly instead of relying on the deprecated auto-activation; Step 5 now reports the child span's own ids (and parent linkage) rather than the active context's.
- Bumped
-
1.0.2-alpha19 Apr 2026 pre-releaseRelease notes
Open source →Fixed
- Fixed
OTel.defaultEndpointto use the OTLP/HTTP port4318instead of the gRPC port4317, matching the defaulthttp/protobufprotocol per the OpenTelemetry specification (#29). Removed the conditional port-swap workarounds in trace and logs configuration. - Fixed
SimpleLogRecordProcessor.shutdown()not flushing pending exports (#28). - Fixed flaky
OtlpGrpcLogRecordExporter endpoint empty host defaults to 127.0.0.1test that depended on no process listening on port 4317.
Changed
MetricsConfigurationnow defaults to the HTTP/protobuf protocol (consistent with the trace and logs pipelines and with the OpenTelemetry specification). SetOTEL_EXPORTER_OTLP_PROTOCOL=grpc(orOTEL_EXPORTER_OTLP_METRICS_PROTOCOL=grpc) to opt back into gRPC.
Added
- Public
exportergetter onPeriodicExportingMetricReaderandexportersgetter onCompositeMetricExporterfor introspection and testability.
- Fixed
-
1.0.1-alpha05 Apr 2026 pre-release -
1.0.0-alpha02 Apr 2026 pre-releaseRelease notes
Open source →Added
- Log Signal SDK implementation
- Upgraded to dartastic_opentelemetry_api: ^1.0.0-alpha with Log Signal API
-
0.10.023 Aug 2026Release notes
Open source →Stable-channel republication of
1.1.0-beta.14. Depends on
dartastic_opentelemetry_api: ^0.10.0.The minor bump from
0.9.8carries three breaking spec-compliance
changes:- Sampler decisions are honored end to end (#120–#123, #129): dropped
spans reach no processor,RecordOnlyno longer sets the W3CSampled
flag, and exporters receive only sampled spans. Adjust your sampler
configuration if you relied on unsampled spans being exported. - The default sampler is
ParentBased(root: AlwaysOn)(#126): child
spans now respect an unsampled parent. Pass
sampler: const AlwaysOnSampler()to restore the old behavior. OTelEnvconfiguration functions return typed Dart Records instead
ofMap<String, dynamic>(config['endpoint'] as String?→
config.endpoint).
Also notable: OTLP/gRPC exporters default to port 4317 per the OTLP spec
(#220), OTLP requests carry an identifyingUser-Agent(#228), empty
environment variables read as unset (#213),service.nameprecedence is
fixed (#103),browser.*resource attributes are populated on web (#190)
withbrowser.mobileas a boolean, and baggage values containing=
survive extraction (#199). Full detail in the1.1.0-beta.14entry. - Sampler decisions are honored end to end (#120–#123, #129): dropped
-
0.9.813 Aug 2026Release notes
Open source →Stable-channel republication of
1.1.0-beta.13. Depends on
dartastic_opentelemetry_api: ^0.9.1.Security
-
Fixes the OTLP debug-log credential leak,
GHSA-4rh6-c2v5-374w
(CWE-532). Every0.9.xrelease from0.9.0through0.9.7is affected: with
debug logging enabled, OTLP header values — includingAuthorization,api-key,
and whatever name your backend uses — were written to the log. This is the first
release on the stable channel that redacts them. See the1.1.0-beta.13entry
above for the mechanism and for theOTEL_DART_HEADER_LOG_ALLOWLISTopt-in.If you ran any 0.9.x release with debug logging enabled and a credential in an
OTLP header, rotate that credential. Upgrading alone does not undo the exposure.
Also in this release
The
1.1.0-beta.12changes, which never reached this channel: thehost.archfix
(#90), registry-enum attribute keys throughout, and the removal of the non-registry
host.processors,host.locale, andprocess.num_threadsresource attributes.
Read the1.1.0-beta.12entry as well before upgrading from 0.9.7.Release notes
Open source →Stable-channel republication of
1.1.0-beta.13. Depends ondartastic_opentelemetry_api: ^0.9.1.Security
-
Fixes the OTLP debug-log credential leak, GHSA-4rh6-c2v5-374w (CWE-532). Every
0.9.xrelease from0.9.0through0.9.7is affected: with debug logging enabled, OTLP header values — includingAuthorization,api-key, and whatever name your backend uses — were written to the log. This is the first release on the stable channel that redacts them. See the1.1.0-beta.13entry above for the mechanism and for theOTEL_DART_HEADER_LOG_ALLOWLISTopt-in.If you ran any 0.9.x release with debug logging enabled and a credential in an OTLP header, rotate that credential. Upgrading alone does not undo the exposure.
Also in this release
The
1.1.0-beta.12changes, which never reached this channel: thehost.archfix (#90), registry-enum attribute keys throughout, and the removal of the non-registryhost.processors,host.locale, andprocess.num_threadsresource attributes. Read the1.1.0-beta.12entry as well before upgrading from 0.9.7. -
-
0.9.720 Jul 2026Release notes
Open source →Stable-channel republication of 1.1.0-beta.11 — doc update over beta.10; code identical to 0.9.6, doc only change. Depends on
api 0.9.1.Release notes
Open source →Stable-channel republication of
1.1.0-beta.11— docs only over 0.9.6. Depends ondartastic_opentelemetry_api: ^0.9.1.Adds the
1.1.0-beta.10fixes over 0.9.6: baggage extraction preserving context and endpoint scheme determining TLS (#89), OTLP/JSON enum fields encoded as integers per spec (#86), and publicMetricTransformer.transformMetrics(#85). -
0.9.618 Jul 2026Release notes
Open source →Stable-channel republication of
1.1.0-beta.9. Depends ondartastic_opentelemetry_api: ^0.9.1, itself the republication of api1.0.0-rc.1— note the api constraint moved off the1.0.0-beta.xrange that 0.9.5 used.Covers everything from
1.1.0-beta.1through1.1.0-beta.9; see those entries for the detail. Highlights for anyone coming from 0.9.5:OTEL_PROPAGATORSsupport (#42, #76), BatchSpanProcessor environment variables (#59), comma-separatedOTEL_*_EXPORTERlists (#79), OTLP/HTTP-JSON wire format (#45), OTLP/JSON trace and span ids encoded as hex per spec (#60),LoggerProvidershutdown fixes (#33, #41), web/wasm safety (#36), and the removal of the non-standarddartasticApiKeyandtenantId(#78). -
0.9.509 May 2026Release notes
Open source →Stable-channel republication of
1.1.0-beta— the first of these. Depends ondartastic_opentelemetry_api: ^1.0.0-beta.2. Covers1.0.0-alphathrough1.1.0-betafor users still on 0.9.3, most notably the Log signal SDK.0.9.4was stamped in git a minute before 0.9.5 with the same code but never published to pub.dev; there is no 0.9.4 release. -
0.9.324 Oct 2025Release notes
Open source →Added
- New W3CTracePropagator
- Defined all 74 env var constants
Fixed
- Fixed env vars on Flutter web
- Fixed service.name, service.version, now from OTEL_RESOURCE_ATTRIBUTES
Removed
- OTEL_SERVICE_VERSION, not in the spec
-
0.9.211 Oct 2025 -
0.9.108 Oct 2025 -
0.9.004 Oct 2025Release notes
Open source →- Added support for
OTEL_EXPORTER_OTLP_HEADERSfor http and grpc exporters for trace and metrics - Added support for all other exporter env vars
- Documented OTEL_* env var usage, added grafana examples
- Certificates env vars may not work yet tests skipped.
- Added support for
-
0.8.729 Sep 2025Release notes
Open source →- Upgraded to api 0.8.7. Upgraded all dependencies including grpc to 4.1
- Respected all OTel env vars when no explicit values are specified, uses OTEL_CONSOLE_EXPORTER
- Fixed default export, uses http/protobuf by default, not grpc
- Fixed issue with creation of the grpc exporter
- ConsoleExporter now only created on env vars or explicity
- Minor, doc, dart format, improved .gitignore, removed generated mistakenly committed
-
0.8.617 Jun 2025 -
0.8.407 Jun 2025Release notes
Open source →- fix: Issue #3 - Fixed Metric generics for Histogram.
- chore: All 445 tests pass, 12 ignored, 0 fail, no crashes, thoroughly applied OTel.shutdown in test tearDowns.
-
0.8.314 May 2025 -
0.8.106 May 2025 -
0.8.006 May 2025Release notes
Open source →Added
- Initial public release of the OpenTelemetry SDK for Dart
- Complete implementation of the OpenTelemetry API
- Full tracing implementation with span processors
- Multiple exporters: OTLP (gRPC and HTTP), Console, Zipkin
- Resource providers for service information
- Sampler implementations: AlwaysOn, AlwaysOff, TraceIdRatio, ParentBased
- Context propagation: W3C Trace Context, W3C Baggage, Composite
- Batch processing with configurable parameters
- Comprehensive test suite
- Complete examples for various use cases
Compatibility
- Implements OpenTelemetry SDK specification v1.0.0-rc3
- Requires opentelemetry_api: ^0.8.0
- Compatible with OpenTelemetry Protocol (OTLP) v0.18.0