dartastic_opentelemetry_api 1.0.0-beta.2 copy "dartastic_opentelemetry_api: ^1.0.0-beta.2" to clipboard
dartastic_opentelemetry_api: ^1.0.0-beta.2 copied to clipboard

Dartastic.io's OpenTelemetry API for Dart following the OpenTelemetry specification. Supports all platforms including web.

example/dartastic_opentelemetry_api_example.dart

// Licensed under the Apache License, Version 2.0
// Copyright 2025, Michael Bushe, All rights reserved.

import 'package:dartastic_opentelemetry_api/dartastic_opentelemetry_api.dart';

/// Example-only attribute keys used in this file. Prefer enums over raw
/// strings — the API's built-in semantic-convention enums (UserSemantics,
/// HttpResource, DatabaseResource, etc.) cover the OTel-defined keys; this
/// enum holds the keys that aren't in any convention. In your own app,
/// rename this to something domain-specific (e.g. `CheckoutAttribute`).
enum ExampleAttribute implements OTelSemantic {
  // Generic demo keys showing attribute types.
  exampleString('example.string'),
  exampleBool('example.bool'),
  exampleInt('example.int'),
  exampleDouble('example.double'),
  exampleStringList('example.string_list'),
  exampleBoolList('example.bool_list'),
  exampleIntList('example.int_list'),
  exampleDoubleList('example.double_list'),
  eventFoo('event.foo'),
  // Auth / cache / batch / payment / retry — none of these are in the
  // OTel semantic conventions, so they're app-defined here.
  authMethod('auth.method'),
  cacheKey('cache.key'),
  cacheRegion('cache.region'),
  batchId('batch.id'),
  jobsTotal('jobs.total'),
  paymentUserId('payment.user_id'),
  paymentMethod('payment.method'),
  paymentGateway('payment.gateway'),
  retryCount('retry.count');

  @override
  final String key;

  @override
  String toString() => key;

  const ExampleAttribute(this.key);
}

/// The API does nothing on its own; it's more typical to use the SDK.
/// However, as required by the OpenTelemetry Specification, the API
/// works (as a no-op) without the SDK installed.
void main() {
  OTelAPI.initialize(endpoint: 'http://localhost:4317');
  // Use typed enum keys — never raw strings.
  final stringAttribute =
      OTelAPI.attributeString(ExampleAttribute.exampleString.key, 'foo');
  final boolAttribute =
      OTelAPI.attributeBool(ExampleAttribute.exampleBool.key, true);
  final intAttr = OTelAPI.attributeInt(ExampleAttribute.exampleInt.key, 42);
  final doubleAttribute =
      OTelAPI.attributeDouble(ExampleAttribute.exampleDouble.key, 42.1);
  final stringListAttribute = OTelAPI.attributeStringList(
      ExampleAttribute.exampleStringList.key, ['foo', 'bar', 'baz']);
  final boolListAttribute = OTelAPI.attributeBoolList(
      ExampleAttribute.exampleBoolList.key, [true, false, true]);
  final intListAttr = OTelAPI.attributeIntList(
      ExampleAttribute.exampleIntList.key, [42, 43, 44]);
  final doubleListAttribute = OTelAPI.attributeDoubleList(
      ExampleAttribute.exampleDoubleList.key, [42.0, 42.1, 42.2]);

  OTelAPI.attributes([
    stringAttribute,
    boolAttribute,
    intAttr,
    doubleAttribute,
    stringListAttribute,
    boolListAttribute,
    intListAttr,
    doubleListAttribute
  ]);

  final baggage = OTelAPI.baggageForMap({'userId': 'yoda'});
  // Create a context with the baggage and run the example within it.
  // This ensures correct propagation across asynchronous boundaries.
  OTelAPI.context(baggage: baggage).runSync(() {
    //Trace Signal
    final defaultGlobalAPINOOPTracerProvider = OTelAPI.tracerProvider();
    final tracer = defaultGlobalAPINOOPTracerProvider
        .getTracer('dart-otel-api-example-service');

    // Use withSpan to make the span active within its scope. Wrap the work
    // in try/catch/finally so the span is always ended and any thrown
    // exception is recorded with SpanStatusCode.Error per the OTel spec.
    final span = tracer.startSpan('doSomeExampleSpan');
    try {
      tracer.withSpan(span, () {
        // Same thing as above, more simply but with some loss of type
        // checking. If your Map has anything but the types above an
        // exception will be thrown.
        final equalToTheAbove = OTelAPI.attributesFromMap({
          ExampleAttribute.exampleString.key: 'foo',
          ExampleAttribute.exampleBool.key: true,
          ExampleAttribute.exampleInt.key: 42,
          ExampleAttribute.exampleDouble.key: 42.1,
          ExampleAttribute.exampleStringList.key: ['foo', 'bar', 'baz'],
          ExampleAttribute.exampleBoolList.key: [true, false, true],
          ExampleAttribute.exampleIntList.key: [42, 43, 44],
          ExampleAttribute.exampleDoubleList.key: [42.0, 42.1, 42.2],
        });
        span.attributes = equalToTheAbove;
        span.addEventNow(
          'data-retrieved',
          OTelAPI.attributes(
              [OTelAPI.attributeString(ExampleAttribute.eventFoo.key, 'bar')]),
        );
      });
      // Capitalized Ok to match the OTel spec.
      span.setStatus(SpanStatusCode.Ok);
    } catch (e, stackTrace) {
      span.recordException(e, stackTrace: stackTrace);
      span.setStatus(SpanStatusCode.Error, e.toString());
      rethrow;
    } finally {
      span.end();
    }

    //Log Signal
    final defaultGlobalAPINOOPLoggerProvider = OTelAPI.loggerProvider();
    final logger = defaultGlobalAPINOOPLoggerProvider
        .getLogger('dart-otel-api-example-service');

    logger.emit(eventName: 'heartbeat', body: 'Service is healthy.');

    logger.emit(
      eventName: 'user_login',
      severityNumber: Severity.INFO,
      body: 'User successfully logged in.',
      attributes: Attributes.of({
        UserSemantics.userId.key: 42,
        ExampleAttribute.authMethod.key: 'password',
      }),
    );

    logger.emit(
      eventName: 'cache_miss',
      severityText: 'WARN',
      body: 'Cache miss for requested key.',
      attributes: Attributes.of({
        ExampleAttribute.cacheKey.key: 'profile_42',
        ExampleAttribute.cacheRegion.key: 'us-east-1',
      }),
    );

    final attrs = {
      DatabaseResource.dbOperation.key: 'update',
      DatabaseResource.dbCollectionName.key: 'orders',
      DatabaseResource.dbResponseReturnedRows.key: 3,
    }.toAttributes();

    logger.emit(
      eventName: 'order_update',
      severityNumber: Severity.INFO,
      body: 'Order update completed.',
      attributes: attrs,
    );

    logger.emit(
      eventName: 'batch_job_summary',
      severityNumber: Severity.INFO,
      // Body is a user-defined structure (per the OTel logs spec) — its
      // inner keys are not span/log attributes, so they don't go through
      // an OTelSemantic enum.
      body: [
        {'job': 'resize_images', 'status': 'ok'},
        {'job': 'generate_thumbnails', 'status': 'ok'},
        {'job': 'sync_metadata', 'status': 'failed'},
      ],
      attributes: Attributes.of({
        ExampleAttribute.batchId.key: 'batch-2025-11-15-01',
        ExampleAttribute.jobsTotal.key: 3,
      }),
    );

    logger.emit(
      eventName: 'payment_failure',
      severityText: 'ERROR',
      body: 'Payment could not be processed.',
      attributes: Attributes.of({
        ExampleAttribute.paymentUserId.key: 101,
        ExampleAttribute.paymentMethod.key: 'credit_card',
        ExampleAttribute.paymentGateway.key: 'stripe',
        ExampleAttribute.retryCount.key: 2,
      }),
    );
  });
}
3
likes
0
points
27.5k
downloads

Publisher

verified publishermindfulsoftware.com

Weekly Downloads

Dartastic.io's OpenTelemetry API for Dart following the OpenTelemetry specification. Supports all platforms including web.

Homepage
Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

collection, fixnum, meta, web

More

Packages that depend on dartastic_opentelemetry_api