LCOV - code coverage report
Current view: top level - src/metrics/export - composite_metric_exporter.dart (source / functions) Coverage Total Hit
Test: lcov.info Lines: 73.7 % 19 14
Test Date: 2025-11-15 13:23:01 Functions: - 0 0

            Line data    Source code
       1              : // Licensed under the Apache License, Version 2.0
       2              : // Copyright 2025, Michael Bushe, All rights reserved.
       3              : 
       4              : import 'package:dartastic_opentelemetry_api/dartastic_opentelemetry_api.dart'
       5              :     show OTelLog;
       6              : 
       7              : import '../data/metric_data.dart';
       8              : import '../metric_exporter.dart';
       9              : 
      10              : /// A composite metric exporter that delegates to multiple exporters.
      11              : ///
      12              : /// This exporter implements the fan-out pattern, where metrics are exported
      13              : /// to multiple backends simultaneously. It forwards all export, flush, and
      14              : /// shutdown operations to each of its delegate exporters.
      15              : ///
      16              : /// This is useful for scenarios where you want to send metrics to multiple
      17              : /// destinations, such as a local console and a remote collector.
      18              : ///
      19              : /// More information:
      20              : /// https://opentelemetry.io/docs/specs/otel/metrics/sdk/#metricexporter
      21              : class CompositeMetricExporter implements MetricExporter {
      22              :   /// The list of delegate exporters.
      23              :   final List<MetricExporter> _exporters;
      24              : 
      25              :   /// Whether this exporter has been shut down.
      26              :   bool _shutdown = false;
      27              : 
      28              :   /// Creates a new CompositeMetricExporter with the given list of exporters.
      29              :   ///
      30              :   /// @param exporters The list of exporters to which operations will be delegated
      31           69 :   CompositeMetricExporter(this._exporters);
      32              : 
      33              :   /// Exports metrics to all delegate exporters.
      34              :   ///
      35              :   /// This method forwards the export operation to each delegate exporter.
      36              :   /// If any exporter fails, the composite exporter will still try to export
      37              :   /// to the remaining exporters, but will return false to indicate failure.
      38              :   ///
      39              :   /// @param data The metric data to export
      40              :   /// @return true if all exporters succeeded, false if any exporter failed
      41            2 :   @override
      42              :   Future<bool> export(MetricData data) async {
      43            2 :     if (_shutdown) {
      44            0 :       if (OTelLog.isLogExport()) {
      45            0 :         OTelLog.logExport(
      46              :             'CompositeMetricExporter: Cannot export after shutdown');
      47              :       }
      48              :       return false;
      49              :     }
      50              : 
      51              :     bool success = true;
      52            4 :     for (final exporter in _exporters) {
      53              :       try {
      54            2 :         final result = await exporter.export(data);
      55              :         success = success && result;
      56              :       } catch (e) {
      57            0 :         if (OTelLog.isLogExport()) {
      58            0 :           OTelLog.logExport(
      59            0 :               'CompositeMetricExporter: Export failed for $exporter: $e');
      60              :         }
      61              :         success = false;
      62              :       }
      63              :     }
      64              : 
      65              :     return success;
      66              :   }
      67              : 
      68              :   /// Forces a flush of all delegate exporters.
      69              :   ///
      70              :   /// This method forwards the flush operation to each delegate exporter.
      71              :   /// If any exporter fails to flush, the composite exporter will still try
      72              :   /// to flush the remaining exporters, but will return false to indicate failure.
      73              :   ///
      74              :   /// @return true if all exporters were flushed successfully, false otherwise
      75            2 :   @override
      76              :   Future<bool> forceFlush() async {
      77            2 :     if (_shutdown) {
      78              :       return false;
      79              :     }
      80              : 
      81              :     bool success = true;
      82            4 :     for (final exporter in _exporters) {
      83              :       try {
      84            2 :         final result = await exporter.forceFlush();
      85              :         success = success && result;
      86              :       } catch (e) {
      87              :         success = false;
      88              :       }
      89              :     }
      90              : 
      91              :     return success;
      92              :   }
      93              : 
      94              :   /// Shuts down all delegate exporters.
      95              :   ///
      96              :   /// This method forwards the shutdown operation to each delegate exporter.
      97              :   /// Once shut down, this exporter will no longer accept export requests.
      98              :   ///
      99              :   /// @return true if all exporters were shut down successfully, false otherwise
     100           58 :   @override
     101              :   Future<bool> shutdown() async {
     102           58 :     if (_shutdown) {
     103              :       return true;
     104              :     }
     105              : 
     106           58 :     _shutdown = true;
     107              :     bool success = true;
     108          116 :     for (final exporter in _exporters) {
     109              :       try {
     110           58 :         final result = await exporter.shutdown();
     111              :         success = success && result;
     112              :       } catch (e) {
     113              :         success = false;
     114              :       }
     115              :     }
     116              : 
     117              :     return success;
     118              :   }
     119              : }
        

Generated by: LCOV version 2.0-1