LCOV - code coverage report
Current view: top level - lib/src/logs - logger.dart (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 57 57
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              : library;
       5              : 
       6              : import 'package:fixnum/fixnum.dart';
       7              : import 'package:meta/meta.dart';
       8              : 
       9              : import '../../dartastic_opentelemetry.dart';
      10              : 
      11              : part 'logger_create.dart';
      12              : 
      13              : /// SDK implementation of the APILogger interface.
      14              : ///
      15              : /// The OTelLogger is responsible for emitting log records. It holds a reference
      16              : /// to the LoggerProvider to access resource, processors, and other configuration.
      17              : ///
      18              : /// This implementation delegates some functionality to the API OTelLogger
      19              : /// implementation while adding SDK-specific behaviors like processor notification.
      20              : ///
      21              : /// More information:
      22              : /// https://opentelemetry.io/docs/specs/otel/logs/sdk/#logger
      23              : class OTelLogger implements APILogger {
      24              :   /// The underlying API OTelLogger implementation.
      25              :   final APILogger _delegate;
      26              : 
      27              :   /// The LoggerProvider that created this logger.
      28              :   final LoggerProvider _provider;
      29              : 
      30              :   /// Private constructor for creating OTelLogger instances.
      31              :   ///
      32              :   /// @param delegate The API OTelLogger implementation to delegate to
      33              :   /// @param provider The LoggerProvider that created this logger
      34            9 :   OTelLogger._({
      35              :     required APILogger delegate,
      36              :     required LoggerProvider provider,
      37              :   })  : _delegate = delegate,
      38              :         _provider = provider {
      39            9 :     if (OTelLog.isDebug()) {
      40           27 :       OTelLog.debug('OTelLogger: Created with name: ${delegate.name}');
      41              :     }
      42              :   }
      43              : 
      44              :   /// Gets the LoggerProvider that created this logger.
      45            8 :   LoggerProvider get provider => _provider;
      46              : 
      47              :   /// Gets the resource associated with this logger.
      48            3 :   Resource? get resource => _provider.resource;
      49              : 
      50            8 :   @override
      51           16 :   String get name => _delegate.name;
      52              : 
      53            8 :   @override
      54           16 :   String? get version => _delegate.version;
      55              : 
      56            8 :   @override
      57           16 :   String? get schemaUrl => _delegate.schemaUrl;
      58              : 
      59            8 :   @override
      60           16 :   Attributes? get attributes => _delegate.attributes;
      61              : 
      62            8 :   @override
      63              :   bool isEnabled(
      64              :       {Context? context, Severity? severityNumber, String? eventName}) {
      65              :     // Check if provider is enabled
      66           32 :     if (!_provider.enabled || _provider.isShutdown) {
      67              :       return false;
      68              :     }
      69              : 
      70              :     // Check if any processors are registered
      71           24 :     if (_provider.logRecordProcessors.isEmpty) {
      72              :       return false;
      73              :     }
      74              : 
      75              :     // Check if all processors return false for enabled
      76           24 :     final allDisabled = _provider.logRecordProcessors.every(
      77           16 :       (processor) => !processor.enabled(
      78            8 :         instrumentationScope: OTel.instrumentationScope(
      79            8 :           name: name,
      80            8 :           version: version ?? '1.0.0',
      81            8 :           schemaUrl: schemaUrl,
      82            8 :           attributes: attributes,
      83              :         ),
      84              :       ),
      85              :     );
      86              : 
      87              :     return !allDisabled;
      88              :   }
      89              : 
      90            8 :   @override
      91              :   void emit({
      92              :     DateTime? timeStamp,
      93              :     DateTime? observedTimestamp,
      94              :     Context? context,
      95              :     Severity? severityNumber,
      96              :     String? severityText,
      97              :     dynamic body,
      98              :     Attributes? attributes,
      99              :     String? eventName,
     100              :   }) {
     101            8 :     if (!isEnabled()) {
     102            1 :       if (OTelLog.isDebug()) {
     103            1 :         OTelLog.debug('OTelLogger: emit called but logger is disabled');
     104              :       }
     105              :       return;
     106              :     }
     107              : 
     108              :     // Convert DateTime to nanoseconds since Unix epoch (Int64)
     109              :     final timestampNanos = timeStamp != null
     110            4 :         ? Int64(timeStamp.microsecondsSinceEpoch) * Int64(1000)
     111              :         : null;
     112              : 
     113              :     // Set observed timestamp to now if not provided
     114              :     final observedNanos = observedTimestamp != null
     115            4 :         ? Int64(observedTimestamp.microsecondsSinceEpoch) * Int64(1000)
     116           40 :         : Int64(DateTime.now().microsecondsSinceEpoch) * Int64(1000);
     117              : 
     118              :     // Use current context if not provided
     119            8 :     final effectiveContext = context ?? Context.current;
     120              : 
     121              :     // Create the instrumentation scope
     122            8 :     final instrumentationScope = OTel.instrumentationScope(
     123            8 :       name: name,
     124            8 :       version: version ?? '1.0.0',
     125            8 :       schemaUrl: schemaUrl,
     126            8 :       attributes: this.attributes,
     127              :     );
     128              : 
     129              :     // Create the log record
     130            8 :     final logRecord = SDKLogRecord(
     131              :       instrumentationScope: instrumentationScope,
     132           16 :       resource: _provider.resource,
     133              :       timestamp: timestampNanos,
     134              :       observedTimestamp: observedNanos,
     135              :       context: effectiveContext,
     136              :       severityNumber: severityNumber,
     137              :       severityText: severityText,
     138              :       body: body,
     139              :       attributes: attributes,
     140              :       eventName: eventName,
     141              :     );
     142              : 
     143            8 :     if (OTelLog.isDebug()) {
     144           16 :       OTelLog.debug('OTelLogger: Emitting log record: $logRecord');
     145              :     }
     146              : 
     147              :     // Notify all processors
     148           24 :     for (final processor in _provider.logRecordProcessors) {
     149              :       try {
     150            8 :         processor.onEmit(logRecord, effectiveContext);
     151              :       } catch (e) {
     152            1 :         if (OTelLog.isError()) {
     153            1 :           OTelLog.error(
     154            2 :               'OTelLogger: Error in processor ${processor.runtimeType}: $e');
     155              :         }
     156              :       }
     157              :     }
     158              :   }
     159              : 
     160              :   /// Emits a log record with TRACE severity.
     161              :   ///
     162              :   /// @param body The log message body
     163              :   /// @param attributes Optional attributes
     164              :   /// @param eventName Optional event name
     165            1 :   void trace(dynamic body, {Attributes? attributes, String? eventName}) {
     166            1 :     emit(
     167              :       severityNumber: Severity.TRACE,
     168              :       severityText: 'TRACE',
     169              :       body: body,
     170              :       attributes: attributes,
     171              :       eventName: eventName,
     172              :     );
     173              :   }
     174              : 
     175              :   /// Emits a log record with DEBUG severity.
     176              :   ///
     177              :   /// @param body The log message body
     178              :   /// @param attributes Optional attributes
     179              :   /// @param eventName Optional event name
     180            1 :   void debug(dynamic body, {Attributes? attributes, String? eventName}) {
     181            1 :     emit(
     182              :       severityNumber: Severity.DEBUG,
     183              :       severityText: 'DEBUG',
     184              :       body: body,
     185              :       attributes: attributes,
     186              :       eventName: eventName,
     187              :     );
     188              :   }
     189              : 
     190              :   /// Emits a log record with INFO severity.
     191              :   ///
     192              :   /// @param body The log message body
     193              :   /// @param attributes Optional attributes
     194              :   /// @param eventName Optional event name
     195            2 :   void info(dynamic body, {Attributes? attributes, String? eventName}) {
     196            2 :     emit(
     197              :       severityNumber: Severity.INFO,
     198              :       severityText: 'INFO',
     199              :       body: body,
     200              :       attributes: attributes,
     201              :       eventName: eventName,
     202              :     );
     203              :   }
     204              : 
     205              :   /// Emits a log record with WARN severity.
     206              :   ///
     207              :   /// @param body The log message body
     208              :   /// @param attributes Optional attributes
     209              :   /// @param eventName Optional event name
     210            1 :   void warn(dynamic body, {Attributes? attributes, String? eventName}) {
     211            1 :     emit(
     212              :       severityNumber: Severity.WARN,
     213              :       severityText: 'WARN',
     214              :       body: body,
     215              :       attributes: attributes,
     216              :       eventName: eventName,
     217              :     );
     218              :   }
     219              : 
     220              :   /// Emits a log record with ERROR severity.
     221              :   ///
     222              :   /// @param body The log message body
     223              :   /// @param attributes Optional attributes
     224              :   /// @param eventName Optional event name
     225            1 :   void error(dynamic body, {Attributes? attributes, String? eventName}) {
     226            1 :     emit(
     227              :       severityNumber: Severity.ERROR,
     228              :       severityText: 'ERROR',
     229              :       body: body,
     230              :       attributes: attributes,
     231              :       eventName: eventName,
     232              :     );
     233              :   }
     234              : 
     235              :   /// Emits a log record with FATAL severity.
     236              :   ///
     237              :   /// @param body The log message body
     238              :   /// @param attributes Optional attributes
     239              :   /// @param eventName Optional event name
     240            1 :   void fatal(dynamic body, {Attributes? attributes, String? eventName}) {
     241            1 :     emit(
     242              :       severityNumber: Severity.FATAL,
     243              :       severityText: 'FATAL',
     244              :       body: body,
     245              :       attributes: attributes,
     246              :       eventName: eventName,
     247              :     );
     248              :   }
     249              : }
        

Generated by: LCOV version 2.0-1