Skip to content
Back to archipelago.banuacoder.com

Monitoring Implementations

newrelic_monitoring_impl Free ​

Tier
Freeversion 1.2.7
Command
archipelago generate newrelic_monitoring_impl
Generates
  • infrastructure/newrelic_monitoring_impl
Depends on
monitoring_sdkgenerate these first

New Relic Mobile vendor plugin for monitoring_sdk — implements AppMonitoringVendor with interaction tracing and distributed tracing, and registers itself into the AppMonitoring fanout under the 'newrelic' key.

Variables ​

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

Selected during flutter_modular_monorepo generation via the monitoringVendors multi-select (newrelic option) — see monitoring_sdk, not a variable of this brick itself.

Usage ​

Interactive ​

bash
archipelago generate newrelic_monitoring_impl

Non-interactive (CI) ​

bash
archipelago generate newrelic_monitoring_impl --config my_config.json

Generated Structure ​

text
infrastructure/
└── newrelic_monitoring_impl/
    ├── pubspec.yaml
    └── lib/
        ├── newrelic_monitoring_impl.dart       # Barrel export
        └── src/
            ├── newrelic_monitoring_impl.dart   # NewRelicMonitoringImpl
            ├── config/
            │   └── newrelic_config.dart        # NewRelicConfig data class
            └── di/
                ├── injector.dart               # microPackage init
                ├── injector.module.dart        # Generated DI module
                └── register_module.dart        # NewRelicConfig provider (override required)

API ​

dart
@Named(MonitoringInjectorKey.newrelic)   // 'newrelic'
@LazySingleton(as: AppMonitoringVendor)
class NewRelicMonitoringImpl({required this.config})
    implements AppMonitoringVendor {
  Future<void> initialize();   // builds Config from NewRelicConfig, startAgent
  Future<void> dispose();      // sets isEnabled false — no native shutdown call
  Future<void> setUserContext(String userId, {Map<String, dynamic>? extras});
  Future<void> clearUserContext();
  void log(String message, {String? tag, MonitoringLevel level});
  Future<void> recordError(Object exception, StackTrace? stackTrace, {bool fatal = false, Map<String, dynamic>? context});
  Future<T> recordTransaction<T>(String name, Future<T> Function() action, {String? operation, Map<String, dynamic>? data});
  void breadcrumb(String message, {String? category, Map<String, dynamic>? data, MonitoringLevel level});
}

You never call this class directly — install the brick, and getIt<AppMonitoring>() (from monitoring_sdk) fans out to it. Real behavior, verified against source:

  • initialize() takes no parameters — it always calls NewrelicMobile.instance.startAgent(...) with a Config built from NewRelicConfig. There is no enable: bool toggle; collection is on once initialize() has run.
  • setUserContext(userId, extras) calls NewrelicMobile.instance.setUserId, then sets extras['email']/extras['token'] (if present) as attributes — arbitrary other extras keys are not forwarded yet (a TODO(archipelago) in source notes the SDK has no batch setCustomAttribute).
  • clearUserContext() resets the user id to '' and removes the email/token attributes.
  • log dispatches to logDebug/logInfo/logWarning/logError based on MonitoringLevel (both error and fatal map to logError); formats as [tag] message when a tag is given.
  • recordError sets any context entries as attributes first, then calls NewrelicMobile.instance.recordError(exception, stackTrace ?? StackTrace.current, attributes: {'fatal': fatal}, isFatal: fatal).
  • recordTransaction wraps action() in startInteraction('name:operation') / endInteraction (in a finally), setting data entries as attributes beforehand — this is the interaction-tracing feature.
  • breadcrumb maps to NewrelicMobile.instance.recordBreadcrumb, with category folded into the message as [category] message.

Configuration ​

NewrelicRegisterModule.newRelicConfig throws UnimplementedError by default — you must override it in your app's DI module to supply a real app token:

dart
@module
abstract class AppNewRelicModule extends NewrelicRegisterModule {
  @override
  @lazySingleton
  NewRelicConfig get newRelicConfig => NewRelicConfig(
    appToken: Env.newRelicAppToken,
    enableCrashReporting: true,
    enableInteractionTracing: true,
    enableDistributedTracing: true,
    enableLogging: true,
  );
}
dart
class const NewRelicConfig({
  required this.appToken,
  this.enableCrashReporting = true,
  this.enableInteractionTracing = true,
  this.enableDistributedTracing = true,
  this.enableLogging = true,
  this.collectorAddress,
  this.crashCollectorAddress,
});

The app token comes from New Relic Dashboard → Mobile → (your app) → Settings → Application token — a separate token is issued per platform; supply the right one per build via env vars.

Dependency injection ​

pubspec.yaml's archipelago: manifest declares the module for monorepo_toolkit generate host-registry:

yaml
archipelago:
  di_modules:
    - class: NewrelicMonitoringImplPackageModule

post_gen.dart adds the package to the host app's pubspec.yaml and registers NewrelicMonitoringImplPackageModule 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 (the order monorepo_toolkit generate host-registry computes). Generate monitoring_sdk first when you install standalone, because the vendor imports monitoring_api. flutter_modular_monorepo generates the vendors first in one run, and both orders work. After you add a vendor, run flutter test test/di/injector_test.dart to confirm AppMonitoring resolves.

Dependencies ​

  • monitoring_api — the AppMonitoringVendor contract
  • newrelic_mobile: ^1.2.9
  • dependencies (shared workspace injectable/get_it re-export)

Platform Setup ​

New Relic's Flutter agent requires native project configuration (Gradle plugin on Android, an NEW_RELIC_APP_TOKEN/agent init on iOS) per the newrelic_mobile package's own install instructions — this brick only generates the Dart-side vendor plugin, not the native agent setup.

Known Limitations ​

  • Arbitrary extras keys passed to setUserContext beyond email/token are silently dropped (see API notes above) — a real gap, not just a doc gap.
  • dispose() flips isEnabled to false locally but does not call any native "stop agent" API — the New Relic agent keeps running once started. Withdrawing diagnostics consent is different: the vendor calls shutDown(), and the native agent may only collect again from the next app launch.

Changelog ​

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