Skip to content

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_sdk already generated (see Monitoring SDK)
  • A Grafana Cloud account or a self-hosted Grafana stack with Loki and Tempo

Step 1: Generate the Brick

bash
archipelago generate grafana_monitoring_impl

You will be prompted for:

  • appName — must match your monorepo app name (e.g. MyApp)
  • isForMonorepotrue

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:

dart
// 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:

dart
@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

dart
@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:

BufferIntervalMax items
Logs5 s100
Traces10 s50

Buffers flush automatically at capacity or on the interval. To flush immediately (e.g. before the app is backgrounded):

dart
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

Built by Banua Coder