monitorAction<R> method

Future<R> monitorAction<R>({
  1. required String actionName,
  2. required String provider,
  3. required Future<R> action(
    1. SentryTrace trace
    ),
  4. Map<String, dynamic>? attributes,
  5. Map<String, dynamic> resultParser(
    1. R result
    )?,
  6. bool logAnalytics = true,
  7. String? analyticsEventName,
})
inherited

Method for executing actions with: Performance Tracing (Start/Stop), Automatic Metadata Injection, Direct Analytics Logging

Implementation

Future<R> monitorAction<R>({
  required String actionName,

  /// The source of this action
  required String provider,

  /// The action to perform. Takes the trace as an arg in case you need manual checkpoints.
  required Future<R> Function(Z trace) action,

  /// Static attributes to attach to both the Trace and the Analytics Event
  Map<String, dynamic>? attributes,

  /// Optional: Extract dynamic attributes from the result
  Map<String, dynamic> Function(R result)? resultParser,
  bool logAnalytics = true,
  String? analyticsEventName,
}) async {
  final trace = await createTrace(name: actionName);

  final Map<String, dynamic> combinedAttributes = {
    'provider': provider,
    'action': actionName,
    ...?attributes,
  };

  final appInfoProvider = CoreAppInfoProvider.instance;

  final appInfo = {
    'app_name': appInfoProvider.appName,
    'app_version': appInfoProvider.appVersion,
    'app_build': appInfoProvider.appBuild,
    'package_name': appInfoProvider.packageName,
    'device_id': appInfoProvider.deviceId,
  };

  combinedAttributes.addAll(appInfo);

  // Add all metadata to the trace
  appInfo.forEach((k, v) => trace.putAttribute(k, v.toString()));

  attributes?.forEach((k, v) => trace.putAttribute(k, v.toString()));
  trace.putAttribute('provider', provider);

  await trace.start();

  try {
    final result = await action(trace);

    trace.putAttribute('status', 'success');
    combinedAttributes['status'] = 'success';

    // Parse result for more context
    if (resultParser != null) {
      try {
        final parsed = resultParser(result);
        parsed.forEach((k, v) {
          combinedAttributes[k] = v;
          trace.putAttribute(k, v.toString());
        });
      } catch (e) {
        logger.error(
          this,
          'Result parsing failed for $actionName',
          error: e,
          stackTrace: StackTrace.current,
        );
      }
    }

    if (logAnalytics) {
      unawaited(_logAnalyticsSafe(
        name: analyticsEventName ?? '${provider}_$actionName',
        parameters: combinedAttributes,
      ));
    }

    return result;
  } catch (e, stackTrace) {
    trace.putAttribute('status', 'failure');
    trace.putAttribute('error_message', e.toString());

    combinedAttributes['status'] = 'failure';
    combinedAttributes['error'] = e.toString();

    if (logAnalytics) {
      unawaited(_logAnalyticsSafe(
        name: analyticsEventName ?? '${provider}_$actionName',
        parameters: combinedAttributes,
      ));
    }

    logger.error(
      this,
      'Error during monitored action: $actionName',
      error: e,
      stackTrace: stackTrace,
    );

    rethrow;
  } finally {
    await trace.stop();
  }
}