Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.9.4] - 2025-10-30
- Added a BaggageSpanProcessor that adds Baggage as SpanAttributes

## [0.9.3] - 2025-10-25
### Added
- New W3CTracePropagator
Expand Down
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ There are many ways to contribute to this project:
1. Fork the repository
2. Clone your fork:
```bash
git clone https://github.com/YOUR_USERNAME/opentelemetry_api.git
cd opentelemetry_api
git clone https://github.com/YOUR_USERNAME/dartastic_opentelemetry.git
cd dartastic_opentelemetry
```
3. Add the upstream repository:
```bash
git remote add upstream https://github.com/MindfulSoftwareLLC/opentelemetry_api.git
git remote add upstream https://github.com/MindfulSoftwareLLC/dartastic_opentelemetry.git
```
4. Install dependencies:
```bash
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ OpenTelemetry data.
- Tracing with span processors and samplers
- Metrics collection and aggregation
- Context propagation
- Baggage management
- Baggage management and optional `BaggageSpanProcessor` to automatically copy baggage entries as span attributes
- Logging is not available yet

[Dartastic OTel](https://pub.dev/packages/dartastic_opentelemetry) is suitable for Dart backends, CLIs or any
Expand Down
15 changes: 13 additions & 2 deletions example/baggage_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,20 @@
// Copyright 2025, Michael Bushe, All rights reserved.

import 'package:dartastic_opentelemetry/src/otel.dart';
import 'package:dartastic_opentelemetry/src/trace/export/baggage_span_processor.dart';
import 'package:dartastic_opentelemetry_api/dartastic_opentelemetry_api.dart';

Future<void> main() async {
// Create a baggage with a single key-value pair
await OTel.initialize(
serviceName: 'my-service',
serviceVersion: '1.0.0',
);

// Optionally initialize tracer provider with a BaggageSpanProcessor
final tracerProvider = OTel.tracerProvider();
// Make baggage automatically appear in span attributes
tracerProvider.addSpanProcessor(const BaggageSpanProcessor());

final baggage = OTel.baggage(
{'customer.id': OTel.baggageEntry('123', 'source=mobile app')});

Expand All @@ -14,7 +24,8 @@ Future<void> main() async {
// Best practice: Use dot notation for key namespacing to avoid conflicts
final enrichedBaggage = baggage
.copyWith('deployment.environment', 'staging')
.copyWith('user.region', 'us-west', 'source=user profile');
.copyWith('user.region', 'us-west', 'source=user profile')
.copyWith('client.session.id', 'session-123');

// Baggage is always associated with a Context
// This allows it to automatically propagate through your application
Expand Down
1 change: 1 addition & 0 deletions lib/dartastic_opentelemetry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ export 'src/otel.dart';
export 'src/resource/resource.dart';
export 'src/resource/resource_detector.dart';
export 'src/resource/web_detector.dart';
export 'src/trace/export/baggage_span_processor.dart';
export 'src/trace/export/batch_span_processor.dart';
export 'src/trace/export/composite_exporter.dart';
export 'src/trace/export/console_exporter.dart';
Expand Down
78 changes: 78 additions & 0 deletions lib/src/trace/export/baggage_span_processor.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Licensed under the Apache License, Version 2.0
// Copyright 2025, Michael Bushe, All rights reserved.

import 'package:dartastic_opentelemetry/src/trace/span.dart';
import 'package:dartastic_opentelemetry/src/trace/span_processor.dart';
import 'package:dartastic_opentelemetry_api/dartastic_opentelemetry_api.dart';

/// Automatically copies baggage entries to span attributes on span start.
///
/// https://opentelemetry.io/docs/specs/otel/baggage/api/#baggage-propagation
/// "Because a common use case for Baggage is to add data to Span Attributes
/// across a whole trace, several languages have Baggage Span Processors that
/// add data from baggage as attributes on span creation."
///
/// This BaggageSpanProcessor extracts all baggage entries from the parent or
/// current context and adds them as span attributes when spans are created.
///
/// This enables baggage values to be:
/// - Visible in tracing backends (HyperDX, Jaeger, etc.)
/// - Searchable and filterable for trace queries
/// - Automatically propagated to all spans without manual attribute setting
///
/// Example usage:
///
/// ```dart
/// final tracerProvider = OTel.tracerProvider();
/// tracerProvider.addSpanProcessor(BaggageSpanProcessor());
/// ```
class BaggageSpanProcessor implements SpanProcessor {
/// Creates a [BaggageSpanProcessor] instance.
const BaggageSpanProcessor();

@override
Future<void> onStart(Span span, Context? parentContext) async {
// Extract baggage from the current context
final baggage = Context.current.baggage;
if (baggage == null) {
return;
}

final entries = baggage.getAllEntries();
if (entries.isEmpty) {
return;
}

// Convert baggage entries to a map for span attributes
// Note: Baggage metadata is intentionally not included as it's not part of the value
final attributeMap = <String, String>{};
for (final entry in entries.entries) {
attributeMap[entry.key] = entry.value.value;
}

// Add all baggage attributes to the span at once
if (attributeMap.isNotEmpty) {
span.addAttributes(Attributes.of(attributeMap));
}
}

@override
Future<void> onEnd(Span span) async {
// No-op: baggage attributes are already added during onStart
}

@override
Future<void> onNameUpdate(Span span, String newName) async {
// No-op: baggage values don't change when span name is updated
}

@override
Future<void> shutdown() async {
// No-op: this processor has no resources to clean up
}

@override
Future<void> forceFlush() async {
// No-op: this processor doesn't batch or queue spans
}
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: dartastic_opentelemetry
description: Dartastic.io's OpenTelemetry SDK for Dart
version: 0.9.3
version: 0.9.4
repository: https://github.com/MindfulSoftwareLLC/dartastic_opentelemetry.git
homepage: https://dartastic.io

Expand Down
Loading