otel_logging 0.1.0-beta.1 copy "otel_logging: ^0.1.0-beta.1" to clipboard
otel_logging: ^0.1.0-beta.1 copied to clipboard

Bridge `package:logging` records into the OpenTelemetry logs SDK so trace_id / span_id correlation lights up automatically for any Dart app using the Dart team's standard logging package.

dartastic_opentelemetry_logging #

Bridges package:logging records into the Dartastic OpenTelemetry SDK so any Dart application using the de-facto-standard Dart logging package gets trace/span correlation in its log records automatically.

Why #

package:logging is what every Dart server framework and most Flutter apps use for structured application logs. Without a bridge, every consumer who wants trace-id correlation in their backend has to write the same ~15 lines of Logger.root.onRecord.listen(...) plumbing — easy to get the level mapping subtly wrong. This package is that plumbing, written once.

The bridge is opt-in: the OTel SDK does not depend on package:logging. Add this package only when you want the integration.

Usage #

import 'package:dartastic_opentelemetry/dartastic_opentelemetry.dart';
import 'package:dartastic_opentelemetry_logging/dartastic_opentelemetry_logging.dart';
import 'package:logging/logging.dart';

Future<void> main() async {
  await OTel.initialize(serviceName: 'my-app');

  // After OTel.initialize so the default LoggerProvider exists.
  PackageLoggingBridge.install();

  Logger.root.level = Level.ALL;

  Logger('weather.api').info('serving forecast');

  // Records emitted from inside an active span are auto-correlated.
  await OTel.tracer().startActiveSpan('serve', (_) async {
    Logger('handler').warning('upstream slow');
  });

  // Cancel the StreamSubscription before the program exits, otherwise
  // the open subscription keeps the Dart isolate alive after main returns.
  await PackageLoggingBridge.uninstall();
  await OTel.shutdown();
}

Severity mapping #

package:logging Level.value is mapped to OTel Severity using the same boundaries as the SDK's existing dart:developer bridge:

package:logging Level.value OTel Severity
ALL (anything < 300) 0+ TRACE
FINEST 300 TRACE2
FINER 400 TRACE2
FINE 500 DEBUG
CONFIG 700 DEBUG2
INFO 800 INFO
WARNING 900 WARN
SEVERE 1000 ERROR
SHOUT 1200 FATAL

Attributes #

  • exception.type — set when the record has an error (uses runtimeType.toString()).
  • exception.message — set when the record has an error (uses error.toString()).
  • exception.stacktrace — set when the record has a stackTrace.
  • logging.zonehashCode of the originating Zone. Useful when correlating logs across isolates/zones; ignore otherwise.

The OTel logger name (instrumentation scope) defaults to the Logger's name, falling back to package.logging for Logger.root records.

Existing Logger.root.onRecord subscribers keep firing #

Installing the bridge is additive. If your app already prints log records to stdout via a Logger.root.onRecord.listen(...) subscriber, those continue to fire. That matters for Cloud Run / Cloud Functions where the platform also collects stdout.

Lifecycle #

The bridge holds a StreamSubscription on Logger.root.onRecord. Like any open subscription, an open subscription keeps the Dart isolate alive past main(). Always:

await PackageLoggingBridge.uninstall();
await OTel.shutdown();

before letting main() return. Forgetting to uninstall is the same class of bug as issue #33 in the SDK (short-lived CLIs hanging because a Timer/subscription was never cancelled).

License #

Apache 2.0 — see LICENSE.

1
likes
140
points
34
downloads

Documentation

API reference

Publisher

verified publisherdartastic.io

Weekly Downloads

Bridge `package:logging` records into the OpenTelemetry logs SDK so trace_id / span_id correlation lights up automatically for any Dart app using the Dart team's standard logging package.

License

Apache-2.0 (license)

Dependencies

dartastic_opentelemetry, dartastic_opentelemetry_api, logging

More

Packages that depend on otel_logging