2023-05-26 21:21:16 +00:00
|
|
|
/*
|
|
|
|
* This file is part of Stack Wallet.
|
|
|
|
*
|
|
|
|
* Copyright (c) 2023 Cypher Stack
|
|
|
|
* All Rights Reserved.
|
|
|
|
* The code is distributed under GPLv3 license, see LICENSE file for details.
|
|
|
|
* Generated by Cypher Stack on 2023-05-26
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2022-08-26 08:11:35 +00:00
|
|
|
import 'dart:core' as core;
|
2022-09-01 08:51:06 +00:00
|
|
|
import 'dart:core';
|
2022-08-26 08:11:35 +00:00
|
|
|
import 'dart:io';
|
|
|
|
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
import 'package:isar/isar.dart';
|
2024-06-13 20:46:22 +00:00
|
|
|
|
2024-05-23 00:37:06 +00:00
|
|
|
import '../models/isar/models/log.dart';
|
|
|
|
import 'constants.dart';
|
|
|
|
import 'enums/log_level_enum.dart';
|
2022-08-26 08:11:35 +00:00
|
|
|
|
|
|
|
export 'enums/log_level_enum.dart';
|
|
|
|
|
|
|
|
class Logging {
|
2022-10-16 23:40:33 +00:00
|
|
|
static const isArmLinux = bool.fromEnvironment("IS_ARM");
|
2022-08-26 08:11:35 +00:00
|
|
|
static final isTestEnv = Platform.environment["FLUTTER_TEST"] == "true";
|
|
|
|
Logging._();
|
|
|
|
static final Logging _instance = Logging._();
|
|
|
|
static Logging get instance => _instance;
|
|
|
|
|
|
|
|
static const core.int defaultPrintLength = 1020;
|
|
|
|
|
|
|
|
late final Isar? isar;
|
2024-06-13 20:46:22 +00:00
|
|
|
late final _AsyncLogWriterQueue _queue;
|
2022-08-26 08:11:35 +00:00
|
|
|
|
|
|
|
Future<void> init(Isar isar) async {
|
2024-06-13 20:46:22 +00:00
|
|
|
_queue = _AsyncLogWriterQueue();
|
2022-08-26 08:11:35 +00:00
|
|
|
this.isar = isar;
|
|
|
|
}
|
|
|
|
|
|
|
|
void log(
|
|
|
|
core.Object? object, {
|
|
|
|
required LogLevel level,
|
|
|
|
core.bool printToConsole = true,
|
|
|
|
core.bool printFullLength = false,
|
|
|
|
}) {
|
2022-10-16 23:40:33 +00:00
|
|
|
try {
|
|
|
|
if (isTestEnv || isArmLinux) {
|
|
|
|
Logger.print(object, normalLength: !printFullLength);
|
|
|
|
return;
|
|
|
|
}
|
2023-01-16 14:34:52 +00:00
|
|
|
String message = object.toString();
|
|
|
|
|
|
|
|
// random value to check max size of message before storing in db
|
|
|
|
if (message.length > 20000) {
|
|
|
|
message = "${message.substring(0, 20000)}...";
|
|
|
|
}
|
|
|
|
|
2022-10-16 23:40:33 +00:00
|
|
|
final now = core.DateTime.now().toUtc();
|
|
|
|
final log = Log()
|
2023-01-16 14:34:52 +00:00
|
|
|
..message = message
|
2022-10-16 23:40:33 +00:00
|
|
|
..logLevel = level
|
|
|
|
..timestampInMillisUTC = now.millisecondsSinceEpoch;
|
|
|
|
if (level == LogLevel.Error || level == LogLevel.Fatal) {
|
|
|
|
printFullLength = true;
|
|
|
|
}
|
2022-08-26 08:11:35 +00:00
|
|
|
|
2024-06-13 20:46:22 +00:00
|
|
|
_queue.add(
|
|
|
|
() async => isar!.writeTxn(
|
|
|
|
() async => await isar!.logs.put(log),
|
|
|
|
),
|
|
|
|
);
|
2022-08-26 08:11:35 +00:00
|
|
|
|
2022-10-16 23:40:33 +00:00
|
|
|
if (printToConsole) {
|
|
|
|
final core.String logStr = "Log: ${log.toString()}";
|
|
|
|
final core.int logLength = logStr.length;
|
2022-08-26 08:11:35 +00:00
|
|
|
|
2022-10-16 23:40:33 +00:00
|
|
|
if (!printFullLength || logLength <= defaultPrintLength) {
|
|
|
|
debugPrint(logStr);
|
|
|
|
} else {
|
|
|
|
core.int start = 0;
|
|
|
|
core.int endIndex = defaultPrintLength;
|
|
|
|
core.int tmpLogLength = logLength;
|
|
|
|
while (endIndex < logLength) {
|
|
|
|
debugPrint(logStr.substring(start, endIndex));
|
|
|
|
endIndex += defaultPrintLength;
|
|
|
|
start += defaultPrintLength;
|
|
|
|
tmpLogLength -= defaultPrintLength;
|
|
|
|
}
|
|
|
|
if (tmpLogLength > 0) {
|
|
|
|
debugPrint(logStr.substring(start, logLength));
|
|
|
|
}
|
2022-08-26 08:11:35 +00:00
|
|
|
}
|
|
|
|
}
|
2022-10-16 23:40:33 +00:00
|
|
|
} catch (e, s) {
|
|
|
|
print("problem trying to log");
|
|
|
|
print("$e $s");
|
|
|
|
Logger.print(object);
|
2022-08-26 08:11:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
abstract class Logger {
|
|
|
|
static final isTestEnv = Platform.environment["FLUTTER_TEST"] == "true";
|
|
|
|
|
|
|
|
static void print(
|
|
|
|
core.Object? object, {
|
|
|
|
core.bool withTimeStamp = true,
|
|
|
|
core.bool normalLength = true,
|
|
|
|
}) async {
|
|
|
|
if (Constants.disableLogger && !isTestEnv) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
final utcTime = withTimeStamp ? "${core.DateTime.now().toUtc()}: " : "";
|
2024-05-27 23:56:22 +00:00
|
|
|
final core.int defaultPrintLength = 1020 - utcTime.length;
|
2022-08-26 08:11:35 +00:00
|
|
|
if (normalLength) {
|
|
|
|
debugPrint("$utcTime$object");
|
|
|
|
} else if (object == null ||
|
|
|
|
object.toString().length <= defaultPrintLength) {
|
|
|
|
debugPrint("$utcTime$object");
|
|
|
|
} else {
|
2024-05-27 23:56:22 +00:00
|
|
|
final core.String log = object.toString();
|
2022-08-26 08:11:35 +00:00
|
|
|
core.int start = 0;
|
|
|
|
core.int endIndex = defaultPrintLength;
|
2024-05-27 23:56:22 +00:00
|
|
|
final core.int logLength = log.length;
|
2022-08-26 08:11:35 +00:00
|
|
|
core.int tmpLogLength = log.length;
|
|
|
|
while (endIndex < logLength) {
|
|
|
|
debugPrint(utcTime + log.substring(start, endIndex));
|
|
|
|
endIndex += defaultPrintLength;
|
|
|
|
start += defaultPrintLength;
|
|
|
|
tmpLogLength -= defaultPrintLength;
|
|
|
|
}
|
|
|
|
if (tmpLogLength > 0) {
|
|
|
|
debugPrint(utcTime + log.substring(start, logLength));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-06-13 20:46:22 +00:00
|
|
|
|
|
|
|
/// basic async queue for writing logs in the [Logging] to isar
|
|
|
|
class _AsyncLogWriterQueue {
|
|
|
|
final List<Future<void> Function()> _queue = [];
|
|
|
|
bool _runningLock = false;
|
|
|
|
|
|
|
|
void add(Future<void> Function() futureFunction) {
|
|
|
|
_queue.add(futureFunction);
|
|
|
|
_run();
|
|
|
|
}
|
|
|
|
|
|
|
|
void _run() async {
|
|
|
|
if (_runningLock) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
_runningLock = true;
|
|
|
|
try {
|
|
|
|
while (_queue.isNotEmpty) {
|
|
|
|
final futureFunction = _queue.removeAt(0);
|
|
|
|
try {
|
|
|
|
await futureFunction.call();
|
|
|
|
} catch (e, s) {
|
|
|
|
debugPrint("$e\n$s");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} finally {
|
|
|
|
_runningLock = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|