Web example
Flutter plugin for logging
- Simple logging to logcat.
- Network request intercepting.
- Log exporting (JSON format).
- Proxy settings for "Charles".
- Logs by level.
Supported Dart http client plugins:
✔️ Dio
✔️ Chopper
✔️ Http from http/http package
✔️ HttpClient from dart:io package
-
Add plugin to the project:
dependencies: cr_logger: ^1.1.0
-
Initialize the logger. main.dart:
void main() { ... CRLoggerInitializer.instance.init( theme: ThemeData.light(), levelColors: { Level.debug: Colors.grey.shade300, Level.warning: Colors.orange, }, hiddenFields: [ 'token', ], logFileName: 'my_logs', shouldPrintLogs: true, shouldPrintInReleaseMode: false, ); }
shouldPrintLogs
- Prints all logs while [shouldPrintLogs] is trueshouldPrintInReleaseMode
- Will all logs be printed when [kReleaseMode] is truetheme
- Custom logger themelevelColors
- Colors for message types levelColors (debug, verbose, info, warning, error, wtf)hiddenFields
- List of keys, whose value need to be replaced by string 'Hidden'logFileName
- File name when sharing logsmaxLogsCount
- Maximum number of each type of logs (http, debug, info, error), by default = 50logger
- Custom logger -
Provide functions to handle cr_logger jobs in separate Isolates (e.g. printing logs or parsing jsons). When writing a lot of logs and printing it to the console UI may lag a lot. Isolates helps to improve performance for debug builds with cr_logger enabled. Example is using worker_manager package for convenient work with Dart Isolates:
Future<void> main() async { // Call this first if main function is async WidgetsFlutterBinding.ensureInitialized(); ... await Executor().warmUp(); CRLoggerInitializer.instance.handleFunctionInIsolate = (fun, data) async { return await Executor().execute( arg1: data, fun1: fun, ); }; CRLoggerInitializer.instance.parseiOSJsonStringInIsolate = (fun, data) async { return await Executor().execute( arg1: data, fun1: fun, ); }; ... }
-
Initialize Inspector (optional):
return MaterialApp( home: const MainPage(), builder: (context, child) => CrInspector(child: child!), );
-
Initialize the following callbacks (optional):
5.1
LogoutCallback
- when needed to log out from appCRLoggerInitializer.instance.onLogout = () async { // logout simulation await Future.delayed(const Duration(seconds: 1)); };
5.2
ShareLogsFileCallback
- when needed to share logs file on the app's sideCRLoggerInitializer.instance.onShareLogsFile = (path) async { await Share.shareFiles([path]); };
-
Define the variables:
6.1
appInfo
- you can provide custom information to be displayed on the AppInfo pageCRLoggerInitializer.instance.appInfo = { 'Build type': buildType.toString(), 'Endpoint': 'https/cr_logger/example/', };
6.2
logFileName
- file name when exporting logs6.3
hiddenFields
- list of keys for headers to hide when showing network logs -
Add the overlay button:
CRLoggerInitializer.instance.showDebugButton(context);
button
- Custom floating buttonleft
- X-axis start positiontop
- Y-axis start position -
You can turn on/off the printing logs in the isolate, by default enabled:
CRLoggerInitializer.instance.isIsolateHttpLogsPrinting = false;
-
Support for importing logs from json:
await CRLoggerInitializer.instance.createLogsFromJson(json);
-
You can get the current proxy settings to initialise Charles:
final proxy = CRLoggerInitializer.instance.getProxySettings();
if (proxy != null) {
RestClient.instance.init(proxy);
}
If the logger is enabled, a floating button appears on the screen; it also indicates the project build number.
It's quite easy to use, just click on the floating button to show the main screen of the logger
You can also double tap
on the button to invoke Quick Actions.
Using this popup menu, you can quickly access the desired CRLogger options. Called by a long press or double tap on the debug button.
Allows you to view Package name, app version, build version and
Clears application logs
If the inspector is enabled, then a panel appears on the right side of the screen, with buttons to toggle size inspection and the color picker.
Needed to set proxy settings for Charles
Provides search by logs (Debug, Info, Error)
Share logs with your team
Opens a page that contains action buttons and value notifiers.
Action buttons allows you to add different callbacks for testing
-
Add actions:
CRLoggerInitializer.instance.addActionButton('Log Hi', () => log.i('Hi')); CRLoggerInitializer.instance.addActionButton( 'Log By', () => log.i('By'), connectedWidgetId: 'some identifier', );
-
Remove actions by specified id:
CRLoggerInitializer.instance.removeActionsById('some identifier');
Value notifiers help keep track of changes to variables of ValueNotifier type. The value can be either a simple type or a Widget and etc.
-
Type notifiers:
final integerNotifier = ValueNotifier<int>(0); final doubleNotifier = ValueNotifier<double>(0); final boolNotifier = ValueNotifier<bool>(false); final stringNotifier = ValueNotifier<String>('integer: '); final iconNotifier = ValueNotifier<Icon>(Icon(Icons.clear)); final textNotifier = ValueNotifier<Text>(Text('Widget text'));
-
Add notifiers:
CRLoggerInitializer.instance.addValueNotifier('Integer', integerNotifier); CRLoggerInitializer.instance.addValueNotifier('Double', doubleNotifier); CRLoggerInitializer.instance.addValueNotifier('Bool', boolNotifier); CRLoggerInitializer.instance.addValueNotifier('String', stringNotifier); CRLoggerInitializer.instance.addValueNotifier('Icon', iconNotifier); CRLoggerInitializer.instance.addValueNotifier( 'Text', textNotifier, connectedWidgetId: 'some identifier', );
-
Remove notifiers by specified id:
CRLoggerInitializer.instance.removeNotifiersById('some identifier');
-
Clear all notifiers:
CRLoggerInitializer.instance.notifierListClear();
Opens application settings
A quick way to quit your application by providing an onLogout callback
In IntelliJ/Studio you can collapse the request/response body:
Set up this is by going to Preferences -> Editor -> General -> Console
and under Fold console lines that contain
add these 2 rules: ║
, ╟
and under Exceptions
add 1 rule: ╔╣