Grafana Monitoring Implementation
What you'll learn
- Generating the Grafana monitoring implementation brick
- Configuring Grafana Cloud or a self-hosted stack via
GrafanaRegisterModule - Understanding the built-in log and trace buffering behaviour
Prerequisites
monitoring_sdkalready generated (see Monitoring SDK)- A Grafana Cloud account or a self-hosted Grafana stack with Loki and Tempo
Step 1: Generate the Brick
archipelago generate grafana_monitoring_implYou will be prompted for:
- appName — must match your monorepo app name (e.g.
MyApp) - isForMonorepo —
true
The brick generates in infrastructure/grafana_monitoring_impl/. Unlike the Crashlytics or Sentry bricks, this impl uses plain HTTP — no proprietary SDK is added to your dependency tree.
Step 2: Retrieve Grafana Credentials
Grafana Cloud: Navigate to your Stack → Details → Access Policies. Create a policy with logs:write and traces:write scopes. Copy the Instance ID and the API key.
Self-hosted: You need the Loki push endpoint and the Tempo OTLP HTTP endpoint, plus basic auth credentials if your instance requires them.
Step 3: Override GrafanaRegisterModule
Grafana Cloud:
// apps/<appName>/lib/di/app_grafana_module.dart
@module
abstract class AppGrafanaModule extends GrafanaRegisterModule {
@override
@lazySingleton
GrafanaConfig get grafanaConfig => GrafanaConfig.grafanaCloud(
instanceId: Env.grafanaInstanceId,
apiKey: Env.grafanaApiKey,
serviceName: Env.appName,
serviceVersion: Env.version,
environment: Flavor.status.name,
);
}Self-hosted:
@module
abstract class AppGrafanaModule extends GrafanaRegisterModule {
@override
@lazySingleton
GrafanaConfig get grafanaConfig => GrafanaConfig(
lokiEndpoint: Uri.parse(Env.lokiEndpoint),
tempoEndpoint: Uri.parse(Env.tempoEndpoint),
basicAuthUser: Env.grafanaUser,
basicAuthPassword: Env.grafanaPassword,
serviceName: Env.appName,
serviceVersion: Env.version,
environment: Flavor.status.name,
);
}Step 4: Register the Micro-Package
@InjectableInit(
initializerName: 'configureDependencies',
microPackages: [
GrafanaMonitoringImplPackageModule(),
],
)
Future<void> configureDependencies() => getIt.init();The impl is registered as a @LazySingleton named MonitoringInjectorKey.grafanaImpl.
Step 5: Understand Buffering and Flush
The impl buffers locally before shipping to Grafana:
| Buffer | Interval | Max items |
|---|---|---|
| Logs | 5 s | 100 |
| Traces | 10 s | 50 |
Buffers flush automatically at capacity or on the interval. To flush immediately (e.g. before the app is backgrounded):
final grafana = getIt<AppMonitoring>(instanceName: MonitoringInjectorKey.grafanaImpl)
as GrafanaMonitoringImpl;
await grafana.flushLogs();
await grafana.flushTraces();Logs ship to Loki at /loki/api/v1/push; traces ship to Tempo at /api/traces in OTLP JSON format.
Next Steps
- Set up New Relic for SDK-based APM with interaction tracing
- Configure Crashlytics for native crash symbolication