Skip to content
Back to archipelago.banuacoder.com

Monitoring Implementations

grafana_monitoring_impl Free ​

Tier
Freeversion 1.2.8
Command
archipelago generate grafana_monitoring_impl
Generates
  • infrastructure/grafana_monitoring_impl
Depends on
network_sdk, monitoring_sdkgenerate these first

Grafana stack vendor implementation for monitoring_api using OpenTelemetry traces (Tempo) and HTTP log push (Loki).

Variables ​

VariableTypeDefaultDescription
appNamestring—The name of your application
isForMonorepobooleantrueWhether this is being generated as part of a monorepo

Install ​

Interactive ​

bash
archipelago generate grafana_monitoring_impl

Non-interactive (CI) ​

bash
archipelago generate grafana_monitoring_impl --config my_config.json

Generate monitoring_sdk first — this brick depends on its monitoring_api and network_sdk_api packages.

Public API ​

GrafanaMonitoringImpl implements monitoring_api's AppMonitoringVendor contract — see monitoring_sdk's own page for how the SDK orchestrates multiple registered vendors. Called directly, the vendor exposes:

dart
final vendor = getIt<AppMonitoringVendor>(instanceName: MonitoringInjectorKey.grafana);
await vendor.initialize();
vendor.log('user opened checkout', level: MonitoringLevel.info);
await vendor.recordError(exception, stackTrace);
await vendor.recordTransaction('checkout', () => api.submitOrder());
await vendor.setUserContext(userId);
vendor.flushLogs();   // force an immediate Loki push
vendor.flushTraces(); // force an immediate Tempo push

Architecture ​

grafana_monitoring_impl is a vendor brick that implements the AppMonitoringVendor contract from monitoring_api by shipping telemetry directly to a Grafana stack — no OpenTelemetry SDK dependency, despite the brick description's "using OpenTelemetry": it hand-builds OTLP-JSON-over-HTTP payloads and Loki push payloads using plain package:http, not an opentelemetry pub package.

It is selected during flutter_modular_monorepo generation when the user picks grafana from the monitoringVendors multi-select.

GrafanaMonitoringImpl is registered as a @LazySingleton named MonitoringInjectorKey.grafana (not grafanaImpl) and bound to the AppMonitoringVendor interface. It receives a GrafanaConfig instance via constructor injection. The config is provided by GrafanaRegisterModule, which the host app must override with real endpoint URLs and credentials. GrafanaRegisterModule also provides the http.Client used for pushes, registered as @Named('grafanaHttpClient') so it cannot collide with the unnamed http.Client from network_sdk_http.

DI Registration ​

The package uses @InjectableInit.microPackage() for modular registration. post_gen.dart adds the package to the host app's pubspec.yaml and registers GrafanaMonitoringImplPackageModule in the app's injector.dart. The monitoring_impl fanout builds its vendor list from the @Named registrations when AppMonitoring is first resolved, so every vendor module must run before that. Install order does not decide this. The hook rebuilds the injector entries from each package's archipelago: di_modules manifest in dependency order. Generate monitoring_sdk first when you install standalone. You then override GrafanaRegisterModule to provide endpoints.

Buffering Model ​

Both logs and traces are buffered in memory and flushed on a timer to avoid per-call HTTP overhead:

BufferFlush intervalMax sizeDestination
Logs5 seconds100 entriesLoki /loki/api/v1/push
Traces10 seconds50 spansTempo /api/traces (OTLP JSON)

Both buffers are also flushed immediately when they reach capacity, and are drained on dispose(). When diagnostics consent is withdrawn the timers stop and both buffers are cleared unsent.

Generated Structure ​

text
infrastructure/
└── grafana_monitoring_impl/
    ├── pubspec.yaml
    └── lib/
        ├── grafana_monitoring_impl.dart        # Barrel export
        └── src/
            ├── grafana_monitoring_impl.dart    # AppMonitoring impl + buffer types
            ├── config/
            │   └── grafana_config.dart         # GrafanaConfig + grafanaCloud factory
            └── di/
                ├── injector.dart               # microPackage init
                ├── injector.module.dart        # Generated DI module
                └── register_module.dart        # GrafanaConfig provider (override required)

Key Features ​

  • No proprietary SDK — Uses package:http to talk directly to Loki and Tempo; works with both Grafana Cloud and self-hosted Grafana stacks
  • OTLP-compliant traces — Emits OpenTelemetry Protocol JSON with resourceSpans, scopeSpans, and typed attributes; spans carry service name, version, environment, and user ID
  • Loki log streaming — Groups buffered log entries by MonitoringLevel into Loki streams with service, environment, and level labels
  • Grafana Cloud factory — GrafanaConfig.grafanaCloud(instanceId:, apiKey:) pre-fills standard Grafana Cloud endpoint URLs and encodes Basic Auth from the instance ID and API key
  • Buffered flush — Periodic timers minimize HTTP calls; failed flushes re-queue entries up to the buffer limit to avoid silent data loss
  • User context propagation — setUserId stores the ID in memory; it is embedded in every subsequent log line (user_id=…) and in every trace span attribute (user.id)
  • Error spans — recordError logs to Loki and, when tracing is enabled, records an error span in Tempo with error.type, error.message, error.fatal, and error.stacktrace attributes
  • Manual flush — flushLogs() and flushTraces() allow explicit drain before app suspend or logout

Dependencies ​

PackageVersionPurpose
http^1.6.0HTTP transport for Loki and Tempo
monitoring_apipathAppMonitoringVendor contract
network_sdk_apipathPresent as a dependency but not referenced by this vendor's own code
dependenciespathinjectable / get_it re-export

Platform Setup ​

None required — pushes go over plain HTTPS via package:http.

Limitations ​

  • setUserContext's extras parameter is accepted but not yet applied to subsequent log lines/trace spans — the vendor threads through _userId only (marked with a TODO(archipelago) in source).
  • No OpenTelemetry SDK, retry/backoff policy beyond "re-queue on failure up to buffer size", or gzip compression on the HTTP payloads.

Changelog ​

Run archipelago brick info grafana_monitoring_impl to see the latest published version. Enterprise customers can read the full CHANGELOG.md in the brick source repository.

Configuration ​

Override GrafanaRegisterModule in your app DI module to provide endpoints and credentials.

Grafana Cloud ​

dart
@module
abstract class AppGrafanaModule extends GrafanaRegisterModule {
  @override
  @lazySingleton
  GrafanaConfig get grafanaConfig => GrafanaConfig.grafanaCloud(
    instanceId: Env.grafanaInstanceId,  // Grafana Cloud instance / stack ID
    apiKey: Env.grafanaApiKey,          // Grafana Cloud API key with MetricsPublisher role
    serviceName: Env.appName,
    serviceVersion: Env.version,
    environment: Flavor.status.name,
  );
}

Self-Hosted Grafana ​

dart
@module
abstract class AppGrafanaModule extends GrafanaRegisterModule {
  @override
  @lazySingleton
  GrafanaConfig get grafanaConfig => GrafanaConfig(
    lokiEndpoint: Uri.parse(Env.lokiEndpoint),    // e.g. https://loki.internal/loki/api/v1/push
    tempoEndpoint: Uri.parse(Env.tempoEndpoint),  // e.g. https://tempo.internal/api/traces
    basicAuthUser: Env.grafanaUser,               // optional Basic Auth
    basicAuthPassword: Env.grafanaPassword,
    serviceName: Env.appName,
    serviceVersion: Env.version,
    environment: Flavor.status.name,
    enableLogging: true,
    enableTracing: true,
  );
}

GrafanaConfig Fields ​

FieldTypeDefaultDescription
lokiEndpointUrirequiredLoki log push endpoint
tempoEndpointUrirequiredTempo/OTLP trace endpoint
basicAuthUserString?nullBasic Auth username (instance ID for Grafana Cloud)
basicAuthPasswordString?nullBasic Auth password (API key for Grafana Cloud)
serviceNameString'flutter-app'Service name for telemetry attribution
serviceVersionString'1.0.0'Service version embedded in resource spans
environmentString'production'Environment label on logs and traces
enableLoggingbooltrueEnable log buffering and Loki push
enableTracingbooltrueEnable trace buffering and Tempo push

Grafana Cloud credentials are found in Grafana Cloud Portal → Stack → Details. Create an API key under Access Policies with at least logs:write and traces:write scopes.