mirror of
https://github.com/austinried/subtracks.git
synced 2025-12-27 00:59:28 +01:00
logging framework
This commit is contained in:
parent
7f6ba4776a
commit
2837d4576e
@ -7,6 +7,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import '../../database/dao/sources_dao.dart';
|
||||
import '../../database/database.dart';
|
||||
import '../../l10n/generated/app_localizations.dart';
|
||||
import '../../util/logger.dart';
|
||||
import '../state/database.dart';
|
||||
import '../util/padding.dart';
|
||||
|
||||
@ -216,6 +217,7 @@ class _SettingsSourceScreen extends HookConsumerWidget {
|
||||
} catch (e, _) {
|
||||
// showErrorSnackbar(context, e.toString());
|
||||
// log.severe('Saving source', e, st);
|
||||
logger.w('fuck');
|
||||
error = true;
|
||||
} finally {
|
||||
isSaving.value = false;
|
||||
|
||||
@ -6,44 +6,40 @@ import '../../database/database.dart';
|
||||
final databaseInitializer = FutureProvider<SubtracksDatabase>((ref) async {
|
||||
final db = SubtracksDatabase();
|
||||
|
||||
await db
|
||||
.batch((batch) {
|
||||
batch.insertAll(
|
||||
db.sources,
|
||||
[
|
||||
SourcesCompanion.insert(
|
||||
id: Value(1),
|
||||
name: 'test subsonic',
|
||||
isActive: Value(true),
|
||||
),
|
||||
SourcesCompanion.insert(
|
||||
id: Value(2),
|
||||
name: 'test navidrome',
|
||||
isActive: Value(null),
|
||||
),
|
||||
],
|
||||
mode: InsertMode.insertOrIgnore,
|
||||
);
|
||||
batch.insertAllOnConflictUpdate(db.subsonicSettings, [
|
||||
SubsonicSettingsCompanion.insert(
|
||||
sourceId: Value(1),
|
||||
address: Uri.parse('http://demo.subsonic.org'),
|
||||
username: 'guest1',
|
||||
password: 'guest',
|
||||
useTokenAuth: Value(true),
|
||||
),
|
||||
SubsonicSettingsCompanion.insert(
|
||||
sourceId: Value(2),
|
||||
address: Uri.parse('http://10.0.2.2:4533'),
|
||||
username: 'admin',
|
||||
password: 'password',
|
||||
useTokenAuth: Value(true),
|
||||
),
|
||||
]);
|
||||
})
|
||||
.onError((error, stack) {
|
||||
print(error);
|
||||
});
|
||||
await db.batch((batch) {
|
||||
batch.insertAll(
|
||||
db.sources,
|
||||
[
|
||||
SourcesCompanion.insert(
|
||||
id: Value(1),
|
||||
name: 'test subsonic',
|
||||
isActive: Value(true),
|
||||
),
|
||||
SourcesCompanion.insert(
|
||||
id: Value(2),
|
||||
name: 'test navidrome',
|
||||
isActive: Value(null),
|
||||
),
|
||||
],
|
||||
mode: InsertMode.insertOrIgnore,
|
||||
);
|
||||
batch.insertAllOnConflictUpdate(db.subsonicSettings, [
|
||||
SubsonicSettingsCompanion.insert(
|
||||
sourceId: Value(1),
|
||||
address: Uri.parse('http://demo.subsonic.org'),
|
||||
username: 'guest1',
|
||||
password: 'guest',
|
||||
useTokenAuth: Value(true),
|
||||
),
|
||||
SubsonicSettingsCompanion.insert(
|
||||
sourceId: Value(2),
|
||||
address: Uri.parse('http://10.0.2.2:4533'),
|
||||
username: 'admin',
|
||||
password: 'password',
|
||||
useTokenAuth: Value(true),
|
||||
),
|
||||
]);
|
||||
});
|
||||
|
||||
return db;
|
||||
});
|
||||
|
||||
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
|
||||
import '../../util/logger.dart';
|
||||
import '../state/source.dart';
|
||||
import '../util/color_scheme.dart';
|
||||
import 'theme.dart';
|
||||
@ -36,8 +37,12 @@ class CoverArtTheme extends HookConsumerWidget {
|
||||
: 'https://placehold.net/400x400.png',
|
||||
),
|
||||
);
|
||||
} catch (err) {
|
||||
print(err);
|
||||
} catch (error, stackTrace) {
|
||||
logger.w(
|
||||
'Could not create color scheme from image provider',
|
||||
error: error,
|
||||
stackTrace: stackTrace,
|
||||
);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
@ -7,6 +7,7 @@ import '../sources/models.dart' as models;
|
||||
import 'converters.dart';
|
||||
import 'dao/library_dao.dart';
|
||||
import 'dao/sources_dao.dart';
|
||||
import 'log_interceptor.dart';
|
||||
|
||||
part 'database.g.dart';
|
||||
|
||||
@ -27,14 +28,14 @@ class SubtracksDatabase extends _$SubtracksDatabase {
|
||||
|
||||
static QueryExecutor _openConnection() {
|
||||
return driftDatabase(
|
||||
name: 'my_database',
|
||||
name: 'subtracks_database',
|
||||
native: DriftNativeOptions(
|
||||
databasePath: () async {
|
||||
final directory = await getApplicationSupportDirectory();
|
||||
return path.join(directory.absolute.path, 'subtracks.sqlite');
|
||||
},
|
||||
),
|
||||
);
|
||||
).interceptWith(LogInterceptor());
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
120
lib/database/log_interceptor.dart
Normal file
120
lib/database/log_interceptor.dart
Normal file
@ -0,0 +1,120 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
|
||||
import '../util/logger.dart';
|
||||
|
||||
/// https://drift.simonbinder.eu/examples/tracing/
|
||||
class LogInterceptor extends QueryInterceptor {
|
||||
Future<T> _run<T>(
|
||||
String description,
|
||||
FutureOr<T> Function() operation,
|
||||
) async {
|
||||
final trace = logger.level >= Level.trace;
|
||||
final stopwatch = trace ? (Stopwatch()..start()) : null;
|
||||
|
||||
logger.t('Running $description');
|
||||
|
||||
try {
|
||||
final result = await operation();
|
||||
if (trace) {
|
||||
logger.t(' => succeeded after ${stopwatch!.elapsedMilliseconds}ms');
|
||||
}
|
||||
return result;
|
||||
} on Object catch (e, st) {
|
||||
if (trace) {
|
||||
logger.t(' => failed after ${stopwatch!.elapsedMilliseconds}ms');
|
||||
}
|
||||
logger.e('Query failed', error: e, stackTrace: st);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
TransactionExecutor beginTransaction(QueryExecutor parent) {
|
||||
logger.t('begin');
|
||||
return super.beginTransaction(parent);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> commitTransaction(TransactionExecutor inner) {
|
||||
return _run('commit', () => inner.send());
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> rollbackTransaction(TransactionExecutor inner) {
|
||||
return _run('rollback', () => inner.rollback());
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> runBatched(
|
||||
QueryExecutor executor,
|
||||
BatchedStatements statements,
|
||||
) {
|
||||
return _run(
|
||||
'batch with $statements',
|
||||
() => executor.runBatched(statements),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> runInsert(
|
||||
QueryExecutor executor,
|
||||
String statement,
|
||||
List<Object?> args,
|
||||
) {
|
||||
return _run(
|
||||
'$statement with $args',
|
||||
() => executor.runInsert(statement, args),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> runUpdate(
|
||||
QueryExecutor executor,
|
||||
String statement,
|
||||
List<Object?> args,
|
||||
) {
|
||||
return _run(
|
||||
'$statement with $args',
|
||||
() => executor.runUpdate(statement, args),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> runDelete(
|
||||
QueryExecutor executor,
|
||||
String statement,
|
||||
List<Object?> args,
|
||||
) {
|
||||
return _run(
|
||||
'$statement with $args',
|
||||
() => executor.runDelete(statement, args),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> runCustom(
|
||||
QueryExecutor executor,
|
||||
String statement,
|
||||
List<Object?> args,
|
||||
) {
|
||||
return _run(
|
||||
'$statement with $args',
|
||||
() => executor.runCustom(statement, args),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Map<String, Object?>>> runSelect(
|
||||
QueryExecutor executor,
|
||||
String statement,
|
||||
List<Object?> args,
|
||||
) {
|
||||
return _run(
|
||||
'$statement with $args',
|
||||
() => executor.runSelect(statement, args),
|
||||
);
|
||||
}
|
||||
}
|
||||
48
lib/util/logger.dart
Normal file
48
lib/util/logger.dart
Normal file
@ -0,0 +1,48 @@
|
||||
import 'package:logger/logger.dart';
|
||||
|
||||
class LogLevelFilter extends LogFilter {
|
||||
@override
|
||||
bool shouldLog(LogEvent event) {
|
||||
return event.level >= level!;
|
||||
}
|
||||
}
|
||||
|
||||
class SubtracksLogger extends Logger {
|
||||
SubtracksLogger({
|
||||
super.filter,
|
||||
super.printer,
|
||||
super.output,
|
||||
required Level level,
|
||||
}) : _level = level,
|
||||
super(level: level);
|
||||
|
||||
final Level _level;
|
||||
Level get level => _level;
|
||||
}
|
||||
|
||||
SubtracksLogger createLogger() {
|
||||
var isDebug = false;
|
||||
assert(() {
|
||||
isDebug = true;
|
||||
return true;
|
||||
}());
|
||||
|
||||
if (isDebug) {
|
||||
return SubtracksLogger(
|
||||
filter: DevelopmentFilter(),
|
||||
printer: PrettyPrinter(),
|
||||
output: ConsoleOutput(),
|
||||
level: Level.debug,
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: production logger
|
||||
return SubtracksLogger(
|
||||
filter: DevelopmentFilter(),
|
||||
printer: PrettyPrinter(),
|
||||
output: ConsoleOutput(),
|
||||
level: Level.debug,
|
||||
);
|
||||
}
|
||||
|
||||
final logger = createLogger();
|
||||
@ -565,6 +565,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.0"
|
||||
logger:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: logger
|
||||
sha256: a7967e31b703831a893bbc3c3dd11db08126fe5f369b5c648a36f821979f5be3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.2"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@ -26,6 +26,7 @@ dependencies:
|
||||
infinite_scroll_pagination: ^5.1.1
|
||||
intl: any
|
||||
json_annotation: ^4.9.0
|
||||
logger: ^2.6.2
|
||||
material_color_utilities: ^0.11.1
|
||||
material_symbols_icons: ^4.2874.0
|
||||
octo_image: ^2.1.0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user