This package provides an easy way to build transformer loggers as defined in LoggingExtras.jl.
A standard log record consists of the following components:
level
: the logging level like Error, Warn, Info, and Debugmessasge
: a stringkwargs
: key-value pairs (where key is a Symbol)
In practice, the log output may need to be enhanced with additional information. Further, it is conceivable that the data in these fields may need to be moved around within the record. For examples:
- Prepend current timestamp to
message
or add it tokwargs
- Format the log as a single line by moving all
kwargs
intomessage
- Format the complete log record as a JSON string in
message
field - etc.
A few commonly used transformer loggers are provided as part of this package. They can be accessed as follows.
Migrate all kwargs fields by appending them to the message string.
julia> with_logger(OneLineTransformerLogger(current_logger())) do
name = "Pluto"
planet = false
@info "hello world" name planet
end
[ Info: hello world name=Pluto planet=false
Add a timestamp at the beginnging or the end of the message string.
julia> with_logger(TimestampTransformerLogger(current_logger(), BeginningMessageLocation();
format = "yyyy-mm-dd HH:MM:SSz")) do
@info "hello"
end
[ Info: 2020-07-04 21:00:58-07:00 hello
The JSONTransformerLogger is a little special in that it is expected to be used with
the MessageOnlyLogger
sink (so that we can e.g. skip adding the log level as a prefix).
The level
and message
data are automatically
included within the JSON string, for which their labels are customizable. See doc string
for details.
julia> with_logger(JSONTransformerLogger(MessageOnlyLogger(); indent = 2)) do
name = "Pluto"
planet = false
@info "hello world" name planet
end
{
"message": "hello world",
"level": "Info",
"name": "Pluto",
"planet": false
}
Color the message string based upon the log level. Try it! :-)
julia> preferred_colors = Dict(
Logging.Debug => ColorSpec(:grey, false),
Logging.Info => ColorSpec(:cyan, true),
Logging.Warn => ColorSpec(:yellow, true),
Logging.Error => ColorSpec(:red, true),
);
julia> clogger = ColorMessageTransformerLogger(current_logger(), preferred_colors);
Fix the width of the message string by padding spaces at the end. If the message string is longer than the specified width, then it is truncated.
julia> logger = compose(
current_logger(),
logger -> FixedMessageWidthTransformerLogger(logger, 40),
OneLineTransformerLogger,
);
julia> with_logger(logger) do
for i in 1:4
x = round(rand(), digits = 10)
y = round(rand(), digits = 10)
@info "Iteration #$i" x y
end
end
[ Info: Iteration #1 x=0.9901128795 y=0.7439288248
[ Info: Iteration #2 x=0.7326098234 y=0.9881316083
[ Info: Iteration #3 x=0.1050601631 y=0.2100138712
[ Info: Iteration #4 x=0.2812764292 y=0.0242226631
This is the whole reason why this package exists! :-)
There are 4 main operations in a transformer:
- Inject - add data to the log record at either
message
orkwargs
location. - Migrate - move data between
level
,message
, orkwargs
. - Mutate - mutate data in
level
,message
, orkwargs
- Remove - empty out
message
or remove all elements inkwargs
.
Examples:
# Inject a timestamp to the beginning of the message
logger = TransformerLogger(current_logger()) do log
inject(log, BeginningMessageLocation(), () -> now())
end
# Inject a timestamp to the kwargs location
logger = TransformerLogger(current_logger()) do log
inject(log, KwargsLocation(), () -> (:timestamp => now(),))
end
# Migrate all kwargs to the message string
logger = TransformerLogger(current_logger()) do log
migrate(log, KwargsProperty(), MessageProperty())
end
# Multiple operations (using Pipe.jl)
logger = TransformerLogger(current_logger()) do log
@pipe log |>
migrate(_log_, KwargsProperty(), MessageProperty())
inject(_, BeginningMessageLocation(), () -> now())
end
This package was originally conceived as part of this coding live stream. Special credit to Chris de Graff for joining the live stream and helping out.
It has been redesigned significantly since v0.2.0.