dartastic_opentelemetry 1.1.0-beta.5
dartastic_opentelemetry: ^1.1.0-beta.5 copied to clipboard
OpenTelemetry SDK for Dart and Flutter. Distributed tracing, metrics, OTLP exporters (gRPC/HTTP), and context propagation for observability backends.
Changelog #
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
1.1.0-beta.5 - 2026-05-13 #
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.4 - 2026-05-11 #
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.
1.1.0-beta.3 - 2026-05-11 #
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).
1.1.0-beta.2 - 2026-05-10 #
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.
1.1.0-beta.1 - 2026-05-10 #
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.
1.1.0-beta - 2026-05-07 #
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.
1.0.2-alpha - 2026-04-19 #
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.
1.0.1-alpha - 2026-04-05 #
- Added a BaggageSpanProcessor that adds Baggage as SpanAttributes
1.0.0-alpha - 2026-04-02 #
Added #
- Log Signal SDK implementation
- Upgraded to dartastic_opentelemetry_api: ^1.0.0-alpha with Log Signal API
0.9.3 - 2025-10-25 #
0.9.2 - 2025-10-12 #
- Default to INFO OTel logging.
0.9.1 - 2025-10-04 #
- Bumped API to 0.8.8 to fix logging.
0.9.0 - 2025-10-04 #
- 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.
0.8.7 - 2025-09-29 #
- 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.6 - 2025-09-24 #
- Minor, cleaning, format, doc.
0.8.5 - 2025-06-14 #
- prep for wondrous otel demo, upgrade to api 0.8.3, span toString
0.8.4 - 2025-06-06 #
- 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.3 - 2025-06-04 #
- fix: Issue 4, lack of span export
0.8.2 - 2025-05-06 #
- README.md updates
0.8.1 - 2025-05-06 #
- README.md updates
0.8.0 - 2025-05-01 #
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