LCOV - code coverage report
Current view: top level - lib/src/environment - environment_service_io.dart (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 17 17
Test Date: 2026-08-27 23:42:02 Functions: - 0 0

            Line data    Source code
       1              : // Copyright The OpenTelemetry Authors
       2              : // SPDX-License-Identifier: Apache-2.0
       3              : 
       4              : import 'dart:io' as io;
       5              : 
       6              : import 'package:meta/meta.dart';
       7              : 
       8              : import 'env_constants.dart';
       9              : import 'env_from_define.dart';
      10              : import 'environment_service.dart';
      11              : 
      12              : /// IO implementation of the environment service.
      13              : ///
      14              : /// This implementation is used on all platforms except web (Dart VM, Flutter
      15              : /// native, and Flutter desktop).
      16              : ///
      17              : /// Environment variable lookup priority:
      18              : /// 1. String.fromEnvironment (--dart-define values)
      19              : /// 2. io.Platform.environment (system environment variables)
      20              : ///
      21              : /// The implementation uses String.fromEnvironment with empty string as the
      22              : /// default value. If the result is empty, it falls back to checking
      23              : /// io.Platform.environment. This allows --dart-define values to take
      24              : /// precedence over system environment variables, as per OpenTelemetry
      25              : /// specification recommendations.
      26              : class EnvironmentService implements EnvironmentServiceInterface {
      27          465 :   static final EnvironmentService _instance = EnvironmentService._();
      28              : 
      29              :   /// The singleton instance of the EnvironmentService.
      30          310 :   static EnvironmentService get instance => _instance;
      31              : 
      32          155 :   EnvironmentService._();
      33              : 
      34              :   /// Test-only replacement for the lookup sources. When non-null, values
      35              :   /// come exclusively from this map (a missing key reads as unset) and
      36              :   /// still flow through the semicolon-to-comma conversion, so tests get
      37              :   /// deterministic, in-process control of the environment without
      38              :   /// spawning subprocesses.
      39              :   @visibleForTesting
      40              :   static Map<String, String>? testOverrides;
      41              : 
      42              :   /// Gets the value of an environment variable.
      43              :   ///
      44              :   /// Returns the value from the first available source:
      45              :   /// 1. String.fromEnvironment if defined via --dart-define
      46              :   /// 2. io.Platform.environment (system environment variables)
      47              :   /// 3. null if not found
      48              :   ///
      49              :   /// Note: String.fromEnvironment only works for compile-time constants that
      50              :   /// are in our [supportedEnvVars] set. This is a limitation of the Dart
      51              :   /// language when using --dart-define.
      52              :   ///
      53              :   /// @param key The name of the environment variable to retrieve
      54              :   /// @return The value of the environment variable, or null if not found
      55          155 :   @override
      56              :   String? getValue(String key) {
      57              :     String? value;
      58              :     final overrides = testOverrides;
      59              :     if (overrides != null) {
      60           19 :       value = overrides[key];
      61              :     } else {
      62              :       // Priority 1: String.fromEnvironment (--dart-define values)
      63              :       // Only check if this is a known environment variable
      64          142 :       if (supportedEnvVars.contains(key)) {
      65          142 :         final fromEnvironment = getFromEnvironment(key);
      66          142 :         if (fromEnvironment != null && fromEnvironment.isNotEmpty) {
      67              :           value = fromEnvironment;
      68              :         }
      69              :       }
      70              : 
      71              :       // Priority 2: Platform environment variables
      72          284 :       value ??= io.Platform.environment[key];
      73              :     }
      74              : 
      75              :     // Handle comma-separated values for --define compatibility
      76              :     // The --define flag cannot handle commas in values, so we use semicolons
      77              :     // as a delimiter for these specific variables and convert them back
      78              :     if (value != null) {
      79              :       switch (key) {
      80          155 :         case otelResourceAttributes:
      81          154 :         case otelPropagators:
      82          154 :         case otelExporterOtlpHeaders:
      83          154 :         case otelExporterOtlpTracesHeaders:
      84          154 :         case otelExporterOtlpMetricsHeaders:
      85          154 :         case otelExporterOtlpLogsHeaders:
      86            5 :           value = value.replaceAll(';', ',');
      87              :           break;
      88              :       }
      89              :     }
      90              : 
      91              :     // Per the OpenTelemetry specification (configuration.md), an empty value
      92              :     // of an environment variable MUST be interpreted the same way as when the
      93              :     // variable is unset. Normalize empty strings to null here so every
      94              :     // consumer reads an empty value as unset (issue #213).
      95          155 :     return (value == null || value.isEmpty) ? null : value;
      96              :   }
      97              : }
        

Generated by: LCOV version 2.0-1