Merge: Introduce `Logger`, a simple yet powerful logging system
# A simple logger for Nit
## Basic Usage
Create a new `Logger` with a severity level threshold set to `warn_level`:
~~~nit
var logger = new Logger(warn_level)
~~~
Messages with a severity equal or higher than `warn_level` will be displayed:
~~~nit
logger.error "Displays an error."
logger.warn "Displays a warning."
~~~
Messages with a lower severity are silenced:
~~~nit
logger.info "Displays nothing."
~~~
`FileLogger` can be used to output the messages into a file:
~~~nit
var log_file = "my.log"
logger = new FileLogger(warn_level, log_file, append = false)
logger.error("An error")
logger.info("Some info")
logger.close
assert log_file.to_path.read_all == "An error\n"
log_file.to_path.delete
~~~
## Severity levels
Each message is associated with a level that indicate its severity.
Only messages with a severity equal to or higher than the logger `level`
threshold will be displayed.
Severity levels from the most severe to the least severe:
* `unknown_level`: An unknown message that should always be outputted.
* `fatal_level`: An unhandleable error that results in a program crash.
* `error_level`: A handleable error condition.
* `warn_level`: A warning.
* `info_level`: Generic (useful) information about system operation.
* `debug_level`: Low-level information for developpers.
## Formatting messages
You can create custom formatters by implementing the `Formatter` interface.
~~~nit
class MyFormatter
super Formatter
redef fun format(level, message) do
if level < warn_level then return message
return "!!!{message}!!!"
end
end
~~~
See `DefaultFormatter` for a more advanced implementation example.
Each Logger can be given a default formatter used to format the every messages
before outputting them:
~~~nit
var formatter = new MyFormatter
var stderr = new StringWriter
var logger = new Logger(warn_level, stderr, formatter)
logger.warn("This is a warning.")
assert stderr.to_s.trim.split("\n").last == "!!!This is a warning.!!!"
~~~
Optionally, a `Formatter` can be given to replace the `default_formatter`
used by default:
~~~nit
# Create a formatter with no default decorator
logger = new Logger(warn_level, stderr, null)
# Display a message without any formatter
logger.warn("This is a warning.")
assert stderr.to_s.trim.split("\n").last == "This is a warning."
# Display a message with a custom formatter
logger.warn("This is a warning.", formatter)
assert stderr.to_s.trim.split("\n").last == "!!!This is a warning.!!!"
~~~
Pull-Request: #2751
Reviewed-by: Jean Privat <jean@pryen.org>