Logging in Flutter
I am sure that every developer out there has heard this phrase ‘Check the logs’ at least once in their career and checking the logs have saved us several times in many different situations. But what exactly a log message is and what are the advantages and disadvantages of logging? Let’s try to find out!
What is logging?
Logging is the process of printing or saving information about what exactly your code is doing and what is the current data it works with.
While developing mobile applications we, as developers, tend to put a lot of different logging priorities into our code. The reason why we do this is that we want to analyze certain activity in our apps. E.G. logic flows, stack-trace of methods execution, network requests, etc. This helps us to quickly identify and fix the issues that are hard to debug and reproduce.
Pros & cons of logging
If used properly, logging can be a life-saving mechanism for discovering bugs, performance issues and other problems. But if done poorly, it can make your life miserable… We all know that feeling of going through thousands and thousands of lines of log messages without any useful info at all.
Logging options in Flutter
In Flutter there are different sets of options available for logging, one of which is FLog. FLog is an advanced logging framework that provides a quick & simple logging solution.
FLog is written in Dart and provides many of the advanced features needed for logging. Logs are saved in a database, which can then be exported as a zip file, which can then be uploaded to a server or to use locally to identify and debug issues. The logs can be filtered and sorted easily based on many useful filters available.
There are also several different types of log messages, which can be used in different situations:
- FLog.error — used for logging messages of type ERROR. This type is usually used inside of catch statements. It notifies us that something bad happened.
- FLog.warning — used for logging messages of type WARN (warning). A common use-case for this type is when something strange happened, but it is not necessarily an error.
- FLog.info — used for logging messages of type INFO. It’s perfect when we want to log some useful info like connecting to a server, successfully finishing a process, successfully receiving info from another universe, etc.
- FLog.severe — It looks like FLog.error, but it’s way more severe. It’s to be used in these strange cases, which should never happen but… they do from time to time.
How to use
To add FLogs to your flutter project, just paste in the below line in to pubspec.yaml
file and get the dependencies.
dependencies:
f_logs: ^1.1.1
Runtime Permissions:
Log files are exported to a storage directory, so it’s very important to add storage permission to your project:
Android:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
iOS:
<key>NSPhotoLibraryAddUsageDescription</key>
<string>FLogs would like to save photos from the app to your gallery</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>FLogs would like to access your photo gallery for uploading images to the app</string>
Configuration
In-order to use logs, you can either provide your own configuration or use the one provided by FLogs. The default configuration can be requested by calling FLog.getDefaultConfigurations()
method, which you can then override by providing your own set of values against each variable. Logs can be disabled by simply setting isLogsEnabled = false.
A complete list of configurable variables is available here.
LogsConfig config = FLog.getDefaultConfigurations()
..isLogsEnabled = true
..timestampFormat = TimestampFormat.TIME_FORMAT_FULL_2;
FLog.applyConfigurations(config);
Available Methods
To save logs, simply call any of the convenient methods mentioned below:
1. Simple Info Log
FLog.info(
className: "HomePage",
methodName: "_buildRow1",
text: "My log text");
2. Simple Warning Log
FLog.warning(
className: "HomePage",
methodName: "_buildRow1",
text: "My log text";
3. Error Log
FLog.error(
className: "HomePage",
methodName: "_buildRow1",
text: "My log text");
4. Severe Log
FLog.severe(
className: "HomePage",
methodName: "_buildRow1",
text: "My log text");
5. Exception Log
FLog.logThis(
className: "HomePage",
methodName: "_buildRow1",
text: "My log text",
type: LogLevel.SEVERE,
exception: Exception("This is an Exception!"));
6. Data Log
FLog.logThis(
className: "HomePage",
methodName: "_buildRow1",
text: "My log text",
type: LogLevel.INFO,
dataLogType: DataLogType.DEVICE.toString());
In above methods className and methodName are optional and, if not provided, will automatically be taken by getting calling class/method
7. printLogs
static printLogs() async {}
8. getAllLogsByCustomFilter
List<Filter> filters = [Filter.greaterThan('[FieldName]', '[Value]')]
static Future<List<Log>> getAllLogsByCustomFilter(
{List<Filter> filters}) async {}
9. getAllLogsByFilter
static Future<List<Log>> getAllLogsByFilter(
{List<String> dataLogsType,
List<String> logLevels,
int startTimeInMillis,
int endTimeInMillis,
FilterType filterType}}) async {}
10. clearLogs
static clearLogs() {}
11. applyConfigurations
static applyConfigurations(LogsConfig config) {}
A detail list of all the methods is available here
Resources
That's it for this article! If you liked it then don’t forget to clap, comment and share with friends!