import 'package:umbrix/utils/sentry_utils.dart'; import 'package:loggy/loggy.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; // modified version of https://github.com/getsentry/sentry-dart/tree/main/logging class SentryLoggyIntegration extends LoggyPrinter implements Integration { SentryLoggyIntegration({ LogLevel minBreadcrumbLevel = LogLevel.info, LogLevel minEventLevel = LogLevel.error, }) : _minBreadcrumbLevel = minBreadcrumbLevel, _minEventLevel = minEventLevel; final LogLevel _minBreadcrumbLevel; final LogLevel _minEventLevel; late Hub _hub; @override void call(Hub hub, SentryOptions options) { _hub = hub; options.sdk.addIntegration('LoggyIntegration'); } @override Future close() async {} bool _shouldLog(LogLevel logLevel, LogLevel minLevel) { if (logLevel == LogLevel.off) { return false; } return logLevel.priority >= minLevel.priority; } @override Future onLog(LogRecord record) async { if (!canLogEvent(record.error)) return; if (_shouldLog(record.level, _minEventLevel)) { await _hub.captureEvent( record.toEvent(), stackTrace: record.stackTrace, hint: Hint.withMap({TypeCheckHint.record: record}), ); } if (_shouldLog(record.level, _minBreadcrumbLevel)) { await _hub.addBreadcrumb( record.toBreadcrumb(), hint: Hint.withMap({TypeCheckHint.record: record}), ); } } } extension LogRecordX on LogRecord { Breadcrumb toBreadcrumb() { return Breadcrumb( category: 'log', type: 'debug', timestamp: time.toUtc(), level: level.toSentryLevel(), message: message, data: { if (object != null) 'LogRecord.object': object!, if (error != null) 'LogRecord.error': error!, if (stackTrace != null) 'LogRecord.stackTrace': stackTrace!, 'LogRecord.loggerName': loggerName, 'LogRecord.sequenceNumber': sequenceNumber, }, ); } SentryEvent toEvent() { return SentryEvent( timestamp: time.toUtc(), logger: loggerName, level: level.toSentryLevel(), message: SentryMessage(message), throwable: error, // ignore: deprecated_member_use extra: { if (object != null) 'LogRecord.object': object!, 'LogRecord.sequenceNumber': sequenceNumber, }, ); } } extension LogLevelX on LogLevel { SentryLevel? toSentryLevel() => switch (this) { LogLevel.all || LogLevel.debug => SentryLevel.debug, LogLevel.info => SentryLevel.info, LogLevel.warning => SentryLevel.warning, LogLevel.error => SentryLevel.error, _ => null, }; }