AppenderDt.Rd
An Appender that outputs to an in-memory data.table
. It fulfill a similar
purpose as the more flexible AppenderBuffer and is mainly included for
historical reasons/backwards compatibility with older version of lgr.
NOTE: AppenderDt has been superseded by lgr::AppenderBuffer and is kept mainly for archival purposes.
The $new()
method returns an R6::R6 that inherits from
lgr::Appender and can be uses as an appender by a lgr::Logger.
AppenderDt
supports custom fields, but they have to be
pre-allocated in the prototype
argument. Custom fields that are not
part of the prototype are inserted in the list-column .fields
if it
exists.
In addition to the usual fields, AppenderDt$new()
requires that you supply
a buffer_size
and a prototype
. These determine the structure of the
data.table
used to store the log this appender creates and cannot be
modified anymore after the instantiation of the appender.
The lgr::Layout for this Appender is used only to format console output of
its $show()
method.
Both AppenderBuffer and AppenderDt do in memory buffering of events.
AppenderBuffer retains a copies of the events it processes and has the
ability to pass the buffered events on to other Appenders. AppenderDt
converts the events to rows in a data.table
and is a bit harder to
configure. Used inside loops (several hundred iterations),
AppenderDt has much less overhead than AppenderBuffer. For single logging
calls and small loops, AppenderBuffer is more performant. This is related to
how memory pre-allocation is handled by the appenders.
lgr::Filterable
-> lgr::Appender
-> AppenderDt
new()
Creating a new AppenderDt
AppenderDt$new(
threshold = NA_integer_,
layout = LayoutFormat$new(fmt = "%L [%t] %m %f", timestamp_fmt = "%H:%M:%OS3",
colors = getOption("lgr.colors", list())),
prototype = data.table::data.table(.id = NA_integer_, level = NA_integer_, timestamp =
Sys.time(), logger = NA_character_, caller = NA_character_, msg = NA_character_,
.fields = list(list())),
buffer_size = 1e+05,
filters = NULL
)
prototype
A prototype data.table
. The prototype must be a
data.table
with the same columns and column types as the data
you want to log. The actual content of the columns is irrelevant.
There are a few reserved column names that have special meaning:
* .id
: integer
(mandatory). Must always be the first column
and is used internally by the Appender
* .fields
: list
(optional). If present all custom values of the
event (that are not already part of the prototype) are stored in
this list column.
buffer_size
integer
scalar. Number of rows of the in-memory data.table
append()
lg <- lgr::get_logger("test")
lg$config(list(
appenders = list(memory = AppenderDt$new()),
threshold = NA,
propagate = FALSE # to prevent routing to root logger for this example
))
#> <Logger> [all] test
#>
#> appenders:
#> memory: <AppenderDt> [all] -> in memory data.table
lg$debug("test")
lg$error("test")
# Displaying the log
lg$appenders$memory$data
#> .id level timestamp logger caller msg .fields
#> 1 1 500 2023-01-04 14:24:58 test eval test NULL
#> 2 2 200 2023-01-04 14:24:58 test eval test NULL
lg$appenders$memory$show()
#> DEBUG [14:24:58.105] test
#> ERROR [14:24:58.160] test
lgr::show_log(target = lg$appenders$memory)
#> DEBUG [14:24:58.105] test
#> ERROR [14:24:58.160] test
# If you pass a Logger to show_log(), it looks for the first AppenderDt
# that it can find.
lgr::show_log(target = lg)
#> DEBUG [14:24:58.105] test
#> ERROR [14:24:58.160] test
# Custom fields are stored in the list column .fields by default
lg$info("the iris data frame", caps = LETTERS[1:5])
lg$appenders$memory$data
#> .id level timestamp logger caller msg .fields
#> 1 1 500 2023-01-04 14:24:58 test eval test NULL
#> 2 2 200 2023-01-04 14:24:58 test eval test NULL
#> 3 3 400 2023-01-04 14:24:58 test eval the iris data frame A, B, C, D, E
lg$appenders$memory$data$.fields[[3]]$caps
#> [1] "A" "B" "C" "D" "E"
lg$config(NULL)
#> <Logger> [info] test
#>
#> inherited appenders:
#> console: <AppenderConsole> [all] -> console