otel_provider 0.1.0-beta.1
otel_provider: ^0.1.0-beta.1 copied to clipboard
OpenTelemetry instrumentation for `package:provider`. A mixin on `ChangeNotifier` that emits short spans on every notifyListeners / dispose. Works with any ChangeNotifier — provider just happens to be [...]
otel_provider #
OpenTelemetry instrumentation for package:provider
and any code using ChangeNotifier. Built on the
Dartastic OpenTelemetry SDK.
Mix in OTelChangeNotifierMixin on your notifier and every
notifyListeners() + dispose() produces a short span — your
state-mutation timeline in Tempo, automatically.
class CartModel extends ChangeNotifier with OTelChangeNotifierMixin {
final _items = <Item>[];
void add(Item i) {
_items.add(i);
notifyListeners(); // span emitted here
}
}
The notifier machinery lives in Flutter foundation, not in
package:provider itself, so this package works for any
ChangeNotifier — pure-Flutter code, GetX models that happen to be
ChangeNotifiers, custom solutions, all of them. The name is provider
because that's the most common consumer.
Why mix in, not wrap? #
A ChangeNotifierProvider wrapper widget can't see notifications —
the only way to hook them is from inside the notifier itself. The
mixin pattern is the cleanest version of that: minimal viral spread
through your code (one extra with clause), no behavior changes,
no API for downstream callers to learn.
Span shape #
| Hook | Span name | Status |
|---|---|---|
notifyListeners (when hasListeners) |
notifier.notify:<runtimeType> |
unset |
dispose |
notifier.disposed:<runtimeType> |
unset |
| Attribute | Source | When set |
|---|---|---|
notifier.name |
runtimeType.toString() |
every span |
notifier.event |
notify / disposed |
every span |
notifier.value |
value.toString() (clipped) |
only on ValueNotifier-style classes with otelRecordValues == true |
notifier.value.type |
value.runtimeType |
same conditions |
notifyListeners with no current listeners short-circuits — no span
is emitted. This matches ChangeNotifier's own behavior (it doesn't
dispatch when nobody is listening), and prevents off-screen models
from polluting your Tempo view with noise.
ValueNotifier support #
When you mix the OTel mixin into a ValueNotifier<T>, you can
opt into recording the value itself by overriding otelRecordValues:
class _Search extends ValueNotifier<String> with OTelChangeNotifierMixin {
_Search(super.initial);
@override
bool get otelRecordValues => true;
@override
int get otelValueMaxLength => 64;
}
Off by default because notifier values often carry user data.
Caveats #
- Resolves the tracer lazily on first emit, so it's safe to mix
this in even before
OTel.initialize()runs. The tracer is cached after first use. - The
notifier.notifyspan is emitted beforesuper.notifyListeners()fires, so it appears before listeners are notified — the natural order for trace causality. package:provider'sChangeNotifierProviderauto-disposes its notifier when the surrounding widget tree unmounts. Thedisposespan will fire then.
License #
Apache 2.0 — see LICENSE.