grafana_monitoring_impl Free
Grafana stack vendor implementation for
monitoring_apiusing OpenTelemetry traces (Tempo) and HTTP log push (Loki).
Version: 1.0.0
Variables
| Variable | Type | Default | Description |
|---|---|---|---|
| appName | string | — | The name of your application |
| isForMonorepo | boolean | true | Whether this is being generated as part of a monorepo |
Architecture
grafana_monitoring_impl is a vendor brick that implements the AppMonitoring contract from monitoring_api by shipping telemetry directly to a Grafana stack — no proprietary SDK required. It uses plain HTTP (package:http) to push logs to Loki and OTLP-compliant JSON traces to Tempo.
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.grafanaImpl and bound to the AppMonitoring 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.
DI Registration
The package uses @InjectableInit.microPackage() for modular registration. The host app imports GrafanaMonitoringImplPackageModule and calls initGrafanaMonitoringImplModule() during DI bootstrap, then overrides 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:
| Buffer | Flush interval | Max size | Destination |
|---|---|---|---|
| Logs | 5 seconds | 100 entries | Loki /loki/api/v1/push |
| Traces | 10 seconds | 50 spans | Tempo /api/traces (OTLP JSON) |
Both buffers are also flushed immediately when they reach capacity, and are drained on dispose().
Generated Structure
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:httpto 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 typedattributes; spans carry service name, version, environment, and user ID - Loki log streaming — Groups buffered log entries by
MonitoringLevelinto Loki streams withservice,environment, andlevellabels - 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 —
setUserIdstores the ID in memory; it is embedded in every subsequent log line (user_id=…) and in every trace span attribute (user.id) - Error spans —
recordErrorlogs to Loki and, when tracing is enabled, records an error span in Tempo witherror.type,error.message,error.fatal, anderror.stacktraceattributes - Manual flush —
flushLogs()andflushTraces()allow explicit drain before app suspend or logout
Dependencies
| Package | Version | Purpose |
|---|---|---|
http | ^1.6.0 | HTTP transport for Loki and Tempo |
monitoring_api | path | AppMonitoring contract |
dependencies | path | injectable / get_it re-export |
Configuration
Override GrafanaRegisterModule in your app DI module to provide endpoints and credentials.
Grafana Cloud
@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
@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
| Field | Type | Default | Description |
|---|---|---|---|
lokiEndpoint | Uri | required | Loki log push endpoint |
tempoEndpoint | Uri | required | Tempo/OTLP trace endpoint |
basicAuthUser | String? | null | Basic Auth username (instance ID for Grafana Cloud) |
basicAuthPassword | String? | null | Basic Auth password (API key for Grafana Cloud) |
serviceName | String | 'flutter-app' | Service name for telemetry attribution |
serviceVersion | String | '1.0.0' | Service version embedded in resource spans |
environment | String | 'production' | Environment label on logs and traces |
enableLogging | bool | true | Enable log buffering and Loki push |
enableTracing | bool | true | Enable 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.