2021-06-19 23:41:19 +08:00
|
|
|
// ignore: import_of_legacy_library_into_null_safe
|
2023-02-07 22:09:43 +08:00
|
|
|
import 'dart:ffi';
|
2024-07-16 13:23:07 +08:00
|
|
|
|
2023-12-20 10:08:35 +08:00
|
|
|
import 'package:ffi/ffi.dart' as ffi;
|
2023-02-07 22:09:43 +08:00
|
|
|
import 'package:flutter/foundation.dart';
|
2025-03-27 14:17:47 +08:00
|
|
|
import 'package:talker/talker.dart';
|
2023-12-20 10:08:35 +08:00
|
|
|
|
2023-02-07 22:09:43 +08:00
|
|
|
import 'ffi.dart';
|
2021-06-19 23:41:19 +08:00
|
|
|
|
|
|
|
class Log {
|
|
|
|
static final shared = Log();
|
|
|
|
|
2025-03-27 14:17:47 +08:00
|
|
|
late Talker _logger;
|
|
|
|
|
|
|
|
bool enableFlutterLog = true;
|
2024-09-21 16:04:18 +08:00
|
|
|
|
2024-10-10 14:40:38 +08:00
|
|
|
// used to disable log in tests
|
|
|
|
@visibleForTesting
|
|
|
|
bool disableLog = false;
|
|
|
|
|
2021-06-19 23:41:19 +08:00
|
|
|
Log() {
|
2025-03-27 14:17:47 +08:00
|
|
|
_logger = Talker(
|
|
|
|
filter: LogLevelTalkerFilter(),
|
2021-06-19 23:41:19 +08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-09-16 15:46:18 +08:00
|
|
|
// Generic internal logging function to reduce code duplication
|
2025-03-27 14:17:47 +08:00
|
|
|
static void _log(
|
|
|
|
LogLevel level,
|
|
|
|
int rustLevel,
|
|
|
|
dynamic msg, [
|
|
|
|
dynamic error,
|
|
|
|
StackTrace? stackTrace,
|
|
|
|
]) {
|
|
|
|
// only forward logs to flutter in debug mode, otherwise log to rust to
|
|
|
|
// persist logs in the file system
|
|
|
|
if (shared.enableFlutterLog && kDebugMode) {
|
|
|
|
shared._logger.log(msg, logLevel: level, stackTrace: stackTrace);
|
|
|
|
} else {
|
|
|
|
String formattedMessage = _formatMessageWithStackTrace(msg, stackTrace);
|
|
|
|
rust_log(rustLevel, toNativeUtf8(formattedMessage));
|
2024-09-16 15:46:18 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-13 20:46:25 -05:00
|
|
|
static void info(dynamic msg, [dynamic error, StackTrace? stackTrace]) {
|
2024-10-10 14:40:38 +08:00
|
|
|
if (shared.disableLog) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2025-03-27 14:17:47 +08:00
|
|
|
_log(LogLevel.info, 0, msg, error, stackTrace);
|
2021-06-19 23:41:19 +08:00
|
|
|
}
|
|
|
|
|
2023-02-13 20:46:25 -05:00
|
|
|
static void debug(dynamic msg, [dynamic error, StackTrace? stackTrace]) {
|
2024-10-10 14:40:38 +08:00
|
|
|
if (shared.disableLog) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2025-03-27 14:17:47 +08:00
|
|
|
_log(LogLevel.debug, 1, msg, error, stackTrace);
|
2021-06-19 23:41:19 +08:00
|
|
|
}
|
|
|
|
|
2023-02-13 20:46:25 -05:00
|
|
|
static void warn(dynamic msg, [dynamic error, StackTrace? stackTrace]) {
|
2024-10-10 14:40:38 +08:00
|
|
|
if (shared.disableLog) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2025-03-27 14:17:47 +08:00
|
|
|
_log(LogLevel.warning, 3, msg, error, stackTrace);
|
2022-02-20 08:35:52 +08:00
|
|
|
}
|
|
|
|
|
2023-02-13 20:46:25 -05:00
|
|
|
static void trace(dynamic msg, [dynamic error, StackTrace? stackTrace]) {
|
2024-10-10 14:40:38 +08:00
|
|
|
if (shared.disableLog) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2025-03-27 14:17:47 +08:00
|
|
|
_log(LogLevel.verbose, 2, msg, error, stackTrace);
|
2021-09-12 23:04:34 +08:00
|
|
|
}
|
|
|
|
|
2023-02-13 20:46:25 -05:00
|
|
|
static void error(dynamic msg, [dynamic error, StackTrace? stackTrace]) {
|
2024-10-10 14:40:38 +08:00
|
|
|
if (shared.disableLog) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2025-03-27 14:17:47 +08:00
|
|
|
_log(LogLevel.error, 4, msg, error, stackTrace);
|
2021-06-19 23:41:19 +08:00
|
|
|
}
|
|
|
|
}
|
2023-02-07 22:09:43 +08:00
|
|
|
|
|
|
|
bool isReleaseVersion() {
|
|
|
|
return kReleaseMode;
|
|
|
|
}
|
|
|
|
|
2024-09-16 15:46:18 +08:00
|
|
|
// Utility to convert a message to native Utf8 (used in rust_log)
|
2023-02-07 22:09:43 +08:00
|
|
|
Pointer<ffi.Utf8> toNativeUtf8(dynamic msg) {
|
|
|
|
return "$msg".toNativeUtf8();
|
|
|
|
}
|
2024-09-16 15:46:18 +08:00
|
|
|
|
|
|
|
String _formatMessageWithStackTrace(dynamic msg, StackTrace? stackTrace) {
|
2024-09-21 09:57:17 +08:00
|
|
|
if (stackTrace != null) {
|
|
|
|
return "$msg\nStackTrace:\n$stackTrace"; // Append the stack trace to the message
|
|
|
|
}
|
|
|
|
return msg.toString();
|
|
|
|
}
|
2025-03-27 14:17:47 +08:00
|
|
|
|
|
|
|
class LogLevelTalkerFilter implements TalkerFilter {
|
|
|
|
@override
|
|
|
|
bool filter(TalkerData data) {
|
|
|
|
// filter out the debug logs in release mode
|
|
|
|
return kDebugMode ? true : data.logLevel != LogLevel.debug;
|
|
|
|
}
|
|
|
|
}
|