mirror of
https://github.com/immich-app/immich.git
synced 2025-02-04 01:09:14 -05:00
refactor: logging
This commit is contained in:
parent
2e337265ff
commit
d438e333d5
14 changed files with 105 additions and 72 deletions
|
@ -4,22 +4,24 @@ import 'package:logging/logging.dart';
|
||||||
/// Log levels according to dart logging [Level]
|
/// Log levels according to dart logging [Level]
|
||||||
enum LogLevel {
|
enum LogLevel {
|
||||||
// do not change this order!
|
// do not change this order!
|
||||||
all,
|
verbose,
|
||||||
finest,
|
debug,
|
||||||
finer,
|
|
||||||
fine,
|
|
||||||
config,
|
|
||||||
info,
|
info,
|
||||||
warning,
|
warning,
|
||||||
severe,
|
error,
|
||||||
shout,
|
wtf,
|
||||||
off,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension LevelExtension on Level {
|
extension LevelExtension on Level {
|
||||||
LogLevel toLogLevel() =>
|
LogLevel toLogLevel() => switch (this) {
|
||||||
LogLevel.values.elementAtOrNull(Level.LEVELS.indexOf(this)) ??
|
Level.FINEST => LogLevel.verbose,
|
||||||
LogLevel.info;
|
Level.FINE => LogLevel.debug,
|
||||||
|
Level.INFO => LogLevel.info,
|
||||||
|
Level.WARNING => LogLevel.warning,
|
||||||
|
Level.SEVERE => LogLevel.error,
|
||||||
|
Level.SHOUT => LogLevel.wtf,
|
||||||
|
_ => LogLevel.info,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@immutable
|
@immutable
|
||||||
|
|
|
@ -8,9 +8,9 @@ import 'package:immich_mobile/domain/models/render_list.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/render_list_element.model.dart';
|
import 'package:immich_mobile/domain/models/render_list_element.model.dart';
|
||||||
import 'package:immich_mobile/domain/repositories/database.repository.dart';
|
import 'package:immich_mobile/domain/repositories/database.repository.dart';
|
||||||
import 'package:immich_mobile/utils/extensions/drift.extension.dart';
|
import 'package:immich_mobile/utils/extensions/drift.extension.dart';
|
||||||
import 'package:immich_mobile/utils/mixins/log_context.mixin.dart';
|
import 'package:immich_mobile/utils/mixins/log.mixin.dart';
|
||||||
|
|
||||||
class RemoteAssetDriftRepository with LogContext implements IAssetRepository {
|
class RemoteAssetDriftRepository with LogMixin implements IAssetRepository {
|
||||||
final DriftDatabaseRepository _db;
|
final DriftDatabaseRepository _db;
|
||||||
|
|
||||||
const RemoteAssetDriftRepository(this._db);
|
const RemoteAssetDriftRepository(this._db);
|
||||||
|
@ -25,7 +25,7 @@ class RemoteAssetDriftRepository with LogContext implements IAssetRepository {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
log.severe("Cannot insert remote assets into table", e, s);
|
log.e("Cannot insert remote assets into table", e, s);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ class RemoteAssetDriftRepository with LogContext implements IAssetRepository {
|
||||||
await _db.asset.deleteAll();
|
await _db.asset.deleteAll();
|
||||||
return true;
|
return true;
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
log.severe("Cannot clear remote assets", e, s);
|
log.e("Cannot clear remote assets", e, s);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,9 @@ import 'package:immich_mobile/domain/entities/store.entity.drift.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/store.interface.dart';
|
import 'package:immich_mobile/domain/interfaces/store.interface.dart';
|
||||||
import 'package:immich_mobile/domain/models/store.model.dart';
|
import 'package:immich_mobile/domain/models/store.model.dart';
|
||||||
import 'package:immich_mobile/domain/repositories/database.repository.dart';
|
import 'package:immich_mobile/domain/repositories/database.repository.dart';
|
||||||
import 'package:immich_mobile/utils/mixins/log_context.mixin.dart';
|
import 'package:immich_mobile/utils/mixins/log.mixin.dart';
|
||||||
|
|
||||||
class StoreDriftRepository with LogContext implements IStoreRepository {
|
class StoreDriftRepository with LogMixin implements IStoreRepository {
|
||||||
final DriftDatabaseRepository _db;
|
final DriftDatabaseRepository _db;
|
||||||
|
|
||||||
const StoreDriftRepository(this._db);
|
const StoreDriftRepository(this._db);
|
||||||
|
@ -42,7 +42,7 @@ class StoreDriftRepository with LogContext implements IStoreRepository {
|
||||||
));
|
));
|
||||||
return true;
|
return true;
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
log.severe("Cannot set store value - ${key.name}; id - ${key.id}", e, s);
|
log.e("Cannot set store value - ${key.name}; id - ${key.id}", e, s);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,9 @@ import 'package:immich_mobile/domain/entities/user.entity.drift.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/user.interface.dart';
|
import 'package:immich_mobile/domain/interfaces/user.interface.dart';
|
||||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
import 'package:immich_mobile/domain/models/user.model.dart';
|
||||||
import 'package:immich_mobile/domain/repositories/database.repository.dart';
|
import 'package:immich_mobile/domain/repositories/database.repository.dart';
|
||||||
import 'package:immich_mobile/utils/mixins/log_context.mixin.dart';
|
import 'package:immich_mobile/utils/mixins/log.mixin.dart';
|
||||||
|
|
||||||
class UserDriftRepository with LogContext implements IUserRepository {
|
class UserDriftRepository with LogMixin implements IUserRepository {
|
||||||
final DriftDatabaseRepository _db;
|
final DriftDatabaseRepository _db;
|
||||||
|
|
||||||
const UserDriftRepository(this._db);
|
const UserDriftRepository(this._db);
|
||||||
|
@ -40,7 +40,7 @@ class UserDriftRepository with LogContext implements IUserRepository {
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
log.severe("Cannot insert User into table - $user", e, s);
|
log.e("Cannot insert User into table - $user", e, s);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,11 @@ import 'package:immich_mobile/utils/collection_util.dart';
|
||||||
import 'package:immich_mobile/utils/constants/globals.dart';
|
import 'package:immich_mobile/utils/constants/globals.dart';
|
||||||
import 'package:immich_mobile/utils/immich_api_client.dart';
|
import 'package:immich_mobile/utils/immich_api_client.dart';
|
||||||
import 'package:immich_mobile/utils/isolate_helper.dart';
|
import 'package:immich_mobile/utils/isolate_helper.dart';
|
||||||
import 'package:immich_mobile/utils/mixins/log_context.mixin.dart';
|
import 'package:immich_mobile/utils/log_manager.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:immich_mobile/utils/mixins/log.mixin.dart';
|
||||||
import 'package:openapi/api.dart';
|
import 'package:openapi/api.dart';
|
||||||
|
|
||||||
class AssetSyncService with LogContext {
|
class AssetSyncService with LogMixin {
|
||||||
const AssetSyncService();
|
const AssetSyncService();
|
||||||
|
|
||||||
Future<bool> doFullRemoteSyncForUserDrift(
|
Future<bool> doFullRemoteSyncForUserDrift(
|
||||||
|
@ -23,7 +23,7 @@ class AssetSyncService with LogContext {
|
||||||
}) async {
|
}) async {
|
||||||
return await IsolateHelper.run(() async {
|
return await IsolateHelper.run(() async {
|
||||||
try {
|
try {
|
||||||
final logger = Logger("SyncService <Isolate>");
|
final logger = LogManager.I.get("SyncService <Isolate>");
|
||||||
final syncClient = di<ImmichApiClient>().getSyncApi();
|
final syncClient = di<ImmichApiClient>().getSyncApi();
|
||||||
|
|
||||||
final chunkSize = limit ?? kFullSyncChunkSize;
|
final chunkSize = limit ?? kFullSyncChunkSize;
|
||||||
|
@ -32,7 +32,7 @@ class AssetSyncService with LogContext {
|
||||||
String? lastAssetId;
|
String? lastAssetId;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
logger.info(
|
logger.d(
|
||||||
"Requesting more chunks from lastId - ${lastAssetId ?? "<initial_fetch>"}",
|
"Requesting more chunks from lastId - ${lastAssetId ?? "<initial_fetch>"}",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ class AssetSyncService with LogContext {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
log.severe("Error performing full sync for user - ${user.name}", e, s);
|
log.e("Error performing full sync for user - ${user.name}", e, s);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,10 +9,10 @@ import 'package:immich_mobile/domain/models/store.model.dart';
|
||||||
import 'package:immich_mobile/domain/services/user.service.dart';
|
import 'package:immich_mobile/domain/services/user.service.dart';
|
||||||
import 'package:immich_mobile/service_locator.dart';
|
import 'package:immich_mobile/service_locator.dart';
|
||||||
import 'package:immich_mobile/utils/immich_api_client.dart';
|
import 'package:immich_mobile/utils/immich_api_client.dart';
|
||||||
import 'package:immich_mobile/utils/mixins/log_context.mixin.dart';
|
import 'package:immich_mobile/utils/mixins/log.mixin.dart';
|
||||||
import 'package:openapi/api.dart';
|
import 'package:openapi/api.dart';
|
||||||
|
|
||||||
class LoginService with LogContext {
|
class LoginService with LogMixin {
|
||||||
const LoginService();
|
const LoginService();
|
||||||
|
|
||||||
Future<bool> isEndpointAvailable(Uri uri, {ImmichApiClient? client}) async {
|
Future<bool> isEndpointAvailable(Uri uri, {ImmichApiClient? client}) async {
|
||||||
|
@ -27,7 +27,7 @@ class LoginService with LogContext {
|
||||||
try {
|
try {
|
||||||
await serverAPI.pingServer();
|
await serverAPI.pingServer();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.severe("Exception occured while validating endpoint", e);
|
log.e("Exception occured while validating endpoint", e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -52,7 +52,7 @@ class LoginService with LogContext {
|
||||||
return endpoint.startsWith('/') ? "$baseUrl$endpoint" : endpoint;
|
return endpoint.startsWith('/') ? "$baseUrl$endpoint" : endpoint;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.fine("Could not locate /.well-known/immich at $baseUrl", e);
|
log.e("Could not locate /.well-known/immich at $baseUrl", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// No well-known, return the baseUrl
|
// No well-known, return the baseUrl
|
||||||
|
@ -68,7 +68,7 @@ class LoginService with LogContext {
|
||||||
|
|
||||||
return loginResponse?.accessToken;
|
return loginResponse?.accessToken;
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
log.severe("Exception occured while performing password login", e, s);
|
log.e("Exception occured while performing password login", e, s);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ class LoginService with LogContext {
|
||||||
|
|
||||||
final oAuthUrlRes = oAuthUrl?.url;
|
final oAuthUrlRes = oAuthUrl?.url;
|
||||||
if (oAuthUrlRes == null) {
|
if (oAuthUrlRes == null) {
|
||||||
log.severe(
|
log.e(
|
||||||
"oAuth Server URL not available. Kindly ensure oAuth login is enabled in the server",
|
"oAuth Server URL not available. Kindly ensure oAuth login is enabled in the server",
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
|
@ -102,7 +102,7 @@ class LoginService with LogContext {
|
||||||
|
|
||||||
return loginResponse?.accessToken;
|
return loginResponse?.accessToken;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.severe("Exception occured while performing oauth login", e);
|
log.e("Exception occured while performing oauth login", e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import 'package:immich_mobile/domain/models/server-info/server_config.model.dart';
|
import 'package:immich_mobile/domain/models/server-info/server_config.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/server-info/server_features.model.dart';
|
import 'package:immich_mobile/domain/models/server-info/server_features.model.dart';
|
||||||
import 'package:immich_mobile/utils/mixins/log_context.mixin.dart';
|
import 'package:immich_mobile/utils/mixins/log.mixin.dart';
|
||||||
import 'package:openapi/api.dart';
|
import 'package:openapi/api.dart';
|
||||||
|
|
||||||
class ServerInfoService with LogContext {
|
class ServerInfoService with LogMixin {
|
||||||
final ServerApi _serverInfo;
|
final ServerApi _serverInfo;
|
||||||
|
|
||||||
const ServerInfoService(this._serverInfo);
|
const ServerInfoService(this._serverInfo);
|
||||||
|
@ -15,7 +15,7 @@ class ServerInfoService with LogContext {
|
||||||
return ServerFeatures.fromDto(dto);
|
return ServerFeatures.fromDto(dto);
|
||||||
}
|
}
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
log.severe("Error while fetching server features", e, s);
|
log.e("Error while fetching server features", e, s);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ class ServerInfoService with LogContext {
|
||||||
return ServerConfig.fromDto(dto);
|
return ServerConfig.fromDto(dto);
|
||||||
}
|
}
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
log.severe("Error while fetching server config", e, s);
|
log.e("Error while fetching server config", e, s);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import 'package:immich_mobile/domain/models/user.model.dart';
|
import 'package:immich_mobile/domain/models/user.model.dart';
|
||||||
import 'package:immich_mobile/utils/mixins/log_context.mixin.dart';
|
import 'package:immich_mobile/utils/mixins/log.mixin.dart';
|
||||||
import 'package:openapi/api.dart';
|
import 'package:openapi/api.dart';
|
||||||
|
|
||||||
class UserService with LogContext {
|
class UserService with LogMixin {
|
||||||
final UsersApi _userApi;
|
final UsersApi _userApi;
|
||||||
|
|
||||||
const UserService(this._userApi);
|
const UserService(this._userApi);
|
||||||
|
@ -18,13 +18,13 @@ class UserService with LogContext {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (userDto == null) {
|
if (userDto == null) {
|
||||||
log.severe("Cannot fetch my user.");
|
log.e("Cannot fetch my user.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return User.fromAdminDto(userDto, preferencesDto);
|
return User.fromAdminDto(userDto, preferencesDto);
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
log.severe("Error while fetching my user", e, s);
|
log.e("Error while fetching my user", e, s);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,10 @@ import 'package:immich_mobile/presentation/modules/common/states/server_info/ser
|
||||||
import 'package:immich_mobile/presentation/modules/login/models/login_page.model.dart';
|
import 'package:immich_mobile/presentation/modules/login/models/login_page.model.dart';
|
||||||
import 'package:immich_mobile/service_locator.dart';
|
import 'package:immich_mobile/service_locator.dart';
|
||||||
import 'package:immich_mobile/utils/immich_api_client.dart';
|
import 'package:immich_mobile/utils/immich_api_client.dart';
|
||||||
import 'package:immich_mobile/utils/mixins/log_context.mixin.dart';
|
import 'package:immich_mobile/utils/mixins/log.mixin.dart';
|
||||||
import 'package:immich_mobile/utils/snackbar_manager.dart';
|
import 'package:immich_mobile/utils/snackbar_manager.dart';
|
||||||
|
|
||||||
class LoginPageCubit extends Cubit<LoginPageState> with LogContext {
|
class LoginPageCubit extends Cubit<LoginPageState> with LogMixin {
|
||||||
LoginPageCubit() : super(LoginPageState.reset());
|
LoginPageCubit() : super(LoginPageState.reset());
|
||||||
|
|
||||||
String _appendSchema(String url) {
|
String _appendSchema(String url) {
|
||||||
|
@ -96,7 +96,7 @@ class LoginPageCubit extends Cubit<LoginPageState> with LogContext {
|
||||||
await _postLogin(accessToken);
|
await _postLogin(accessToken);
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
SnackbarManager.showError(t.login.error.error_login);
|
SnackbarManager.showError(t.login.error.error_login);
|
||||||
log.severe("Cannot perform password login", e, s);
|
log.e("Cannot perform password login", e, s);
|
||||||
} finally {
|
} finally {
|
||||||
emit(state.copyWith(isValidationInProgress: false));
|
emit(state.copyWith(isValidationInProgress: false));
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ class LoginPageCubit extends Cubit<LoginPageState> with LogContext {
|
||||||
await _postLogin(accessToken);
|
await _postLogin(accessToken);
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
SnackbarManager.showError(t.login.error.error_login_oauth);
|
SnackbarManager.showError(t.login.error.error_login_oauth);
|
||||||
log.severe("Cannot perform oauth login", e, s);
|
log.e("Cannot perform oauth login", e, s);
|
||||||
} finally {
|
} finally {
|
||||||
emit(state.copyWith(isValidationInProgress: false));
|
emit(state.copyWith(isValidationInProgress: false));
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import 'package:immich_mobile/presentation/components/image/immich_logo.widget.d
|
||||||
import 'package:immich_mobile/presentation/modules/login/states/login_page.state.dart';
|
import 'package:immich_mobile/presentation/modules/login/states/login_page.state.dart';
|
||||||
import 'package:immich_mobile/presentation/router/router.dart';
|
import 'package:immich_mobile/presentation/router/router.dart';
|
||||||
import 'package:immich_mobile/service_locator.dart';
|
import 'package:immich_mobile/service_locator.dart';
|
||||||
import 'package:immich_mobile/utils/mixins/log_context.mixin.dart';
|
import 'package:immich_mobile/utils/mixins/log.mixin.dart';
|
||||||
|
|
||||||
@RoutePage()
|
@RoutePage()
|
||||||
class SplashScreenWrapperPage extends AutoRouter implements AutoRouteWrapper {
|
class SplashScreenWrapperPage extends AutoRouter implements AutoRouteWrapper {
|
||||||
|
@ -30,7 +30,7 @@ class SplashScreenPage extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SplashScreenState extends State<SplashScreenPage>
|
class _SplashScreenState extends State<SplashScreenPage>
|
||||||
with SingleTickerProviderStateMixin, LogContext {
|
with SingleTickerProviderStateMixin, LogMixin {
|
||||||
late final AnimationController _animationController;
|
late final AnimationController _animationController;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -65,7 +65,7 @@ class _SplashScreenState extends State<SplashScreenPage>
|
||||||
if (snap.hasData) {
|
if (snap.hasData) {
|
||||||
_tryLogin();
|
_tryLogin();
|
||||||
} else if (snap.hasError) {
|
} else if (snap.hasError) {
|
||||||
log.severe(
|
log.wtf(
|
||||||
"Error while initializing the app",
|
"Error while initializing the app",
|
||||||
snap.error,
|
snap.error,
|
||||||
snap.stackTrace,
|
snap.stackTrace,
|
||||||
|
|
|
@ -9,10 +9,10 @@ import 'package:immich_mobile/domain/models/store.model.dart';
|
||||||
import 'package:immich_mobile/presentation/router/router.dart';
|
import 'package:immich_mobile/presentation/router/router.dart';
|
||||||
import 'package:immich_mobile/service_locator.dart';
|
import 'package:immich_mobile/service_locator.dart';
|
||||||
import 'package:immich_mobile/utils/constants/globals.dart';
|
import 'package:immich_mobile/utils/constants/globals.dart';
|
||||||
import 'package:immich_mobile/utils/mixins/log_context.mixin.dart';
|
import 'package:immich_mobile/utils/mixins/log.mixin.dart';
|
||||||
import 'package:openapi/api.dart';
|
import 'package:openapi/api.dart';
|
||||||
|
|
||||||
class ImmichApiClient extends ApiClient with LogContext {
|
class ImmichApiClient extends ApiClient with LogMixin {
|
||||||
ImmichApiClient({required String endpoint}) : super(basePath: endpoint);
|
ImmichApiClient({required String endpoint}) : super(basePath: endpoint);
|
||||||
|
|
||||||
Map<String, String> get headers => defaultHeaderMap;
|
Map<String, String> get headers => defaultHeaderMap;
|
||||||
|
@ -58,7 +58,7 @@ class ImmichApiClient extends ApiClient with LogContext {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (res.statusCode == HttpStatus.unauthorized) {
|
if (res.statusCode == HttpStatus.unauthorized) {
|
||||||
log.severe("Token invalid. Redirecting to login route");
|
log.e("Token invalid. Redirecting to login route");
|
||||||
await di<AppRouter>().replaceAll([const LoginRoute()]);
|
await di<AppRouter>().replaceAll([const LoginRoute()]);
|
||||||
throw ApiException(res.statusCode, "Unauthorized");
|
throw ApiException(res.statusCode, "Unauthorized");
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import 'package:flutter/foundation.dart';
|
||||||
import 'package:immich_mobile/domain/interfaces/log.interface.dart';
|
import 'package:immich_mobile/domain/interfaces/log.interface.dart';
|
||||||
import 'package:immich_mobile/domain/models/log.model.dart';
|
import 'package:immich_mobile/domain/models/log.model.dart';
|
||||||
import 'package:immich_mobile/service_locator.dart';
|
import 'package:immich_mobile/service_locator.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart' as logging;
|
||||||
|
|
||||||
/// [LogManager] is a custom logger that is built on top of the [logging] package.
|
/// [LogManager] is a custom logger that is built on top of the [logging] package.
|
||||||
/// The logs are written to the database and onto console, using `debugPrint` method.
|
/// The logs are written to the database and onto console, using `debugPrint` method.
|
||||||
|
@ -14,14 +14,16 @@ import 'package:logging/logging.dart';
|
||||||
class LogManager {
|
class LogManager {
|
||||||
LogManager._();
|
LogManager._();
|
||||||
static final LogManager _instance = LogManager._();
|
static final LogManager _instance = LogManager._();
|
||||||
|
static final Map<String, Logger> _loggers = <String, Logger>{};
|
||||||
|
|
||||||
// ignore: match-getter-setter-field-names
|
// ignore: match-getter-setter-field-names
|
||||||
static LogManager get I => _instance;
|
static LogManager get I => _instance;
|
||||||
|
|
||||||
List<LogMessage> _msgBuffer = [];
|
List<LogMessage> _msgBuffer = [];
|
||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
late final StreamSubscription<LogRecord> _subscription;
|
late final StreamSubscription<logging.LogRecord> _subscription;
|
||||||
|
|
||||||
void _onLogRecord(LogRecord record) {
|
void _onLogRecord(logging.LogRecord record) {
|
||||||
// Only print in development
|
// Only print in development
|
||||||
assert(() {
|
assert(() {
|
||||||
debugPrint('[${record.level.name}] [${record.time}] ${record.message}');
|
debugPrint('[${record.level.name}] [${record.time}] ${record.message}');
|
||||||
|
@ -55,11 +57,17 @@ class LogManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
_subscription = Logger.root.onRecord.listen(_onLogRecord);
|
_subscription = logging.Logger.root.onRecord.listen(_onLogRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger get(String? loggerName) => _loggers.putIfAbsent(
|
||||||
|
loggerName ?? 'main',
|
||||||
|
() => Logger(loggerName ?? 'main'),
|
||||||
|
);
|
||||||
|
|
||||||
void updateLevel(LogLevel level) {
|
void updateLevel(LogLevel level) {
|
||||||
Logger.root.level = Level.LEVELS.elementAtOrNull(level.index);
|
logging.Logger.root.level =
|
||||||
|
logging.Level.LEVELS.elementAtOrNull(level.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
@ -75,7 +83,7 @@ class LogManager {
|
||||||
|
|
||||||
static void setGlobalErrorCallbacks() {
|
static void setGlobalErrorCallbacks() {
|
||||||
FlutterError.onError = (details) {
|
FlutterError.onError = (details) {
|
||||||
Logger("FlutterError").severe(
|
LogManager.I.get("FlutterError").wtf(
|
||||||
'Unknown framework error occured in library ${details.library ?? "<unknown>"} at node ${details.context ?? "<unkown>"}',
|
'Unknown framework error occured in library ${details.library ?? "<unknown>"} at node ${details.context ?? "<unkown>"}',
|
||||||
details.exception,
|
details.exception,
|
||||||
details.stack,
|
details.stack,
|
||||||
|
@ -84,9 +92,32 @@ class LogManager {
|
||||||
};
|
};
|
||||||
|
|
||||||
PlatformDispatcher.instance.onError = (error, stack) {
|
PlatformDispatcher.instance.onError = (error, stack) {
|
||||||
Logger("PlatformDispatcher")
|
LogManager.I
|
||||||
.severe('Unknown error occured in root isolate', error, stack);
|
.get("PlatformDispatcher")
|
||||||
|
.wtf('Unknown error occured in root isolate', error, stack);
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Logger {
|
||||||
|
final String _loggerName;
|
||||||
|
const Logger(this._loggerName);
|
||||||
|
|
||||||
|
logging.Logger get _logger => logging.Logger(_loggerName);
|
||||||
|
|
||||||
|
// Highly detailed
|
||||||
|
void v(String message) => _logger.finest(message);
|
||||||
|
// Troubleshooting
|
||||||
|
void d(String message) => _logger.fine(message);
|
||||||
|
// General purpose
|
||||||
|
void i(String message) => _logger.info(message);
|
||||||
|
// Potential issues
|
||||||
|
void w(String message) => _logger.warning(message);
|
||||||
|
// Error
|
||||||
|
void e(String message, [Object? error, StackTrace? stack]) =>
|
||||||
|
_logger.severe(message, error, stack);
|
||||||
|
// Crash / Serious failure
|
||||||
|
void wtf(String message, [Object? error, StackTrace? stack]) =>
|
||||||
|
_logger.shout(message, error, stack);
|
||||||
|
}
|
||||||
|
|
8
mobile-v2/lib/utils/mixins/log.mixin.dart
Normal file
8
mobile-v2/lib/utils/mixins/log.mixin.dart
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:immich_mobile/utils/log_manager.dart';
|
||||||
|
|
||||||
|
mixin LogMixin {
|
||||||
|
@protected
|
||||||
|
@nonVirtual
|
||||||
|
Logger get log => LogManager.I.get(runtimeType.toString());
|
||||||
|
}
|
|
@ -1,8 +0,0 @@
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:logging/logging.dart';
|
|
||||||
|
|
||||||
mixin LogContext {
|
|
||||||
@protected
|
|
||||||
@nonVirtual
|
|
||||||
Logger get log => Logger(runtimeType.toString());
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue