Logging
The Ballerina log module has four log levels with their priority in descending order as follows.
- ERROR
- WARN
- INFO
- DEBUG By default, all logs of the application that are INFO level and above are logged to the console.
Logging or Printing?
The io:println
is a better option than logging when the goal is to display a help statement for a command line application.
- Logs contain readily available diagnostic information, such as the time, module name, etc., of the logging event.
- Logging can be selectively silenced by using the proper log levels.
- Can set up log analytics.
Logging Best Practices
Set proper log level based on the application requirements.
Can have different log levels for different modules in the same package as well.
Suppose you want to set DEBUG
level to the foo
module, the ERROR level to the bar
module, and WARN
level to the rest of the modules in the package. You can achieve this by updating the Config.toml
file as follows.
[ballerina.log]
level = "WARN"
[[ballerina.log.modules]]
name = "myorgname/mypackagename.foo"
level = "DEBUG"
[[ballerina.log.modules]]
name = "myorg/mypackagename.bar"
level = "ERROR"
Make use of string templates if the values need to be concatenated
Bad Code
int delay = 15;
int timeout = 30;
log:printInfo("Application started with delay " + delay.toString() + " seconds and timeout " + timeout.toString() + "seconds" );
Good Code
int delay = 15;
int timeout = 30;
log:printInfo(string `Application started with delay ${delay} seconds and timeout ${timeout} seconds`);
Make use of key-value pairs when logging
Even better log outputs can be generated if the key-value pairs are used.
Good Code
int delay = 15;
int timeout = 30;
log:printInfo("Application started", Delay = delay, Timeout = timeout);
Make use of function pointers to improve the performance
Bad Code
- Suppose the current log level is INFO and there is a DEBUG log that logs a value returned from a function with heavy computations.
- Since DEBUG level logs are not printed due to log level; ideally, the function with heavy computations should not be executed.
- But in the below code, still, the
getDuration
function is executed even though the debug log line is printed.
import ballerina/log;
import ballerina/random;
public function main() {
float duration = getDutration();
log:printDebug("Checking the duration", duration = duration);
}
function getDutration() returns float {
log:printInfo("Calculating duration");
return random:createDecimal() * 100.0;
}
Good Code
- Can avoid this by passing a pointer to the function as a value in a key/value pair like follows.
import ballerina/log;
import ballerina/random;
public function main() {
log:printDebug("Checking the duration", duration = isolated function() returns float {
log:printInfo("Calculating duration optimally");
return random:createDecimal() * 100.0;});
}