diff --git a/lib/fa_dart_logger.dart b/lib/fa_dart_logger.dart index 1e60a7d..acdb6de 100644 --- a/lib/fa_dart_logger.dart +++ b/lib/fa_dart_logger.dart @@ -2,3 +2,5 @@ library fa_dart_logger; export 'src/app_log_impl.dart'; export 'src/base/app_log.dart'; +export 'src/logger/helper/log_helper.dart'; +export 'src/logger/model/index.dart'; diff --git a/lib/src/app_log_impl.dart b/lib/src/app_log_impl.dart index cfdb688..ff37032 100644 --- a/lib/src/app_log_impl.dart +++ b/lib/src/app_log_impl.dart @@ -1,6 +1,8 @@ +import 'package:fa_dart_logger/src/logger/helper/log_helper.dart'; import 'package:logger/logger.dart'; import 'base/app_log.dart'; +import 'logger/model/index.dart'; import 'logger/output/my_console_output.dart'; import 'logger/printer/my_pretty_printer.dart'; @@ -17,6 +19,13 @@ class AppLogImpl implements AppLog { final String? packageName; late Logger _logger; + UserInfo? _userInfo; + + // ignore: avoid_setters_without_getters + set userInfo(UserInfo userInfo) { + _userInfo = userInfo; + } + @override void d(object) { _logger.d(object); @@ -46,4 +55,29 @@ class AppLogImpl implements AppLog { void wtf(object) { _logger.wtf(object); } + + /// [userInfo] must be set, before calling this method + @override + void r( + LogInfo logInfo, { + Severity severity = Severity.high, + }) { + if (_userInfo == null) { + d("Initialise user info before calling this method"); + return; + } + + /// TODO(@singhtaranjeet): Will capture the priority from remote config + const remotePriority = Severity.high; + + if (shouldCaptureLog( + remoteSeverity: remotePriority, logSeverity: severity)) { + // Log the data to API Logger + final logData = + ApiLogInfo.fromLogInfo(logInfo: logInfo, userInfo: _userInfo!); + + /// TODO(@singhtaranjeet): call remote log api + _logger.i(logData); + } + } } diff --git a/lib/src/base/app_log.dart b/lib/src/base/app_log.dart index e7e28db..61c44fb 100644 --- a/lib/src/base/app_log.dart +++ b/lib/src/base/app_log.dart @@ -1,3 +1,7 @@ +import 'package:fa_dart_logger/src/logger/helper/log_helper.dart'; + +import '../logger/model/index.dart'; + /// [AppLog] is used to provide an abstract logger base for various /// logging needs. Extend this class to create your own logging /// class for every logging usage. You can replace [print] and use @@ -24,4 +28,10 @@ abstract class AppLog { /// For logging some Unusual Behaviour void wtf(dynamic object); + + ///For logging events remotely + void r( + LogInfo logInfo, { + Severity severity = Severity.high, + }); } diff --git a/lib/src/logger/helper/log_helper.dart b/lib/src/logger/helper/log_helper.dart new file mode 100644 index 0000000..45c03af --- /dev/null +++ b/lib/src/logger/helper/log_helper.dart @@ -0,0 +1,47 @@ +enum Severity { + /// High Priority logs are Most important logs like errors, exceptions + /// Agenda of high tag is to `capture less but capture rock solid information` + high, + + /// Medium priority logs are all the things that are good to have like + /// warnings, api logs, and all sorts of things. + medium, + + /// Low priority logs are everything + /// be it widget push, route information, snapshot of data. + /// Agenda of these logs are to + /// `Capture everything and make goldmine of data to resolve the issues` + low, +} + +Severity getSeverity(String severity) { + switch (severity) { + case "high": + return Severity.high; + case "medium": + return Severity.medium; + case "low": + return Severity.low; + default: + return Severity.high; + } +} + +/// It is used to determine whether to capture the log or not +bool shouldCaptureLog( + {required Severity remoteSeverity, required Severity logSeverity}) { + if (remoteSeverity == Severity.low) { + return true; + } + + if (remoteSeverity == Severity.medium && + (logSeverity == Severity.medium || logSeverity == Severity.high)) { + return true; + } + + if (remoteSeverity == Severity.high && logSeverity == Severity.high) { + return true; + } + + return false; +} diff --git a/lib/src/logger/model/index.dart b/lib/src/logger/model/index.dart new file mode 100644 index 0000000..0d5f314 --- /dev/null +++ b/lib/src/logger/model/index.dart @@ -0,0 +1,2 @@ +export 'log_info.dart'; +export 'user_info.dart'; diff --git a/lib/src/logger/model/log_info.dart b/lib/src/logger/model/log_info.dart new file mode 100644 index 0000000..3399d4d --- /dev/null +++ b/lib/src/logger/model/log_info.dart @@ -0,0 +1,105 @@ +import 'package:fa_dart_logger/fa_dart_logger.dart'; + +/// Use this for logging remotely logger.r() +class LogInfo { + LogInfo({ + this.endpoint, + this.method, + this.response, + this.request, + this.error, + this.stackTrace, + this.warning, + this.message, + String? severity, + }) : severity = severity ?? Severity.high.name.toLowerCase(), + date = DateTime.now().toIso8601String(); + + final String? endpoint; + final String? method; + final String? response; + final String? request; + final String? error; + final StackTrace? stackTrace; + final String? warning; + final String? message; + final String severity; + final String date; + + @override + String toString() { + return """LogInfo{endpoint: $endpoint, method: $method, response: $response, request: $request, error: $error, stackTrace: $stackTrace, warning: $warning, message: $message}, severity: $severity date: $date"""; + } +} + +/// Use this for send log to remote logging server +class ApiLogInfo extends LogInfo { + ApiLogInfo({ + required this.userInfo, + String? endpoint, + String? method, + String? response, + String? request, + String? error, + StackTrace? stackTrace, + String? warning, + String? message, + String? severity, + }) : userInfoBatch = userInfo.getUcid(), + super( + endpoint: endpoint, + method: method, + response: response, + request: request, + error: error, + stackTrace: stackTrace, + warning: warning, + message: message, + severity: severity, + ); + + factory ApiLogInfo.fromLogInfo({ + required LogInfo logInfo, + required UserInfo userInfo, + }) { + return ApiLogInfo( + endpoint: logInfo.endpoint, + method: logInfo.method, + response: logInfo.response, + request: logInfo.request, + error: logInfo.error, + stackTrace: logInfo.stackTrace, + warning: logInfo.warning, + message: logInfo.message, + userInfo: userInfo, + ); + } + + final UserInfo userInfo; + + /// This batch is just user info seperated by underscore for better searching + /// for example: userName_id_companyId + final String userInfoBatch; + + @override + String toString() { + return """ApiLogInfo{endpoint: $endpoint, method: $method, response: $response, request: $request, error: $error, stackTrace: $stackTrace, warning: $warning, message: $message, userInfo: $userInfo} userInfoBatch: $userInfoBatch, severity: $severity date: $date"""; + } + + Map toJson() { + return { + "endpoint": endpoint, + "method": method, + "response": response, + "request": request, + "error": error, + "stackTrace": stackTrace.toString(), + "warning": warning, + "message": message, + "userInfo": userInfo.toJson(), + "userInfoBatch": userInfoBatch, + "severity": severity, + "date": date, + }; + } +} diff --git a/lib/src/logger/model/user_info.dart b/lib/src/logger/model/user_info.dart new file mode 100644 index 0000000..155fbc4 --- /dev/null +++ b/lib/src/logger/model/user_info.dart @@ -0,0 +1,25 @@ +class UserInfo { + UserInfo({ + required this.name, + required this.id, + required this.companyId, + }); + + final String name; + final String id; + final String companyId; + + @override + String toString() => 'UserInfo{name: $name, id: $id, companyId: $companyId}'; + + /// Short for user_id company_companyId + String getUcid() => "${id}_${companyId}_"; + + Map toJson() { + return { + "name": name, + "id": id, + "companyId": companyId, + }; + } +} diff --git a/pubspec.yaml b/pubspec.yaml index a9394eb..881635d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -13,6 +13,5 @@ dependencies: dev_dependencies: pedantic: ^1.11.0 - # For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec \ No newline at end of file +# following page: https://dart.dev/tools/pub/pubspec