Learn R Programming

lgr (version 0.3.4)

AppenderDt: Log to an in-memory data.table

Description

An Appender that outputs to an in-memory data.table. This kind of Appender is useful for interactive use, and has very little overhead.

Arguments

Custom Fields

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 discarded. If you want an Appender that retains all custom fields (at the cost of slightly less performance), take a look at AppenderBuffer.

With the default settings, the custom field value is included in the data.table as a list column to store arbitrary R objects (see example). It is recommended to use this feature only TRACE level.

Usage

x <- 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_, .custom =
  list(list())), buffer_size = 1e+05, filters = NULL)

x$add_filter(filter, name = NULL) x$append(event) x$filter(event) x$format(color = FALSE, ...) x$remove_filter(pos) x$set_filters(filters) x$set_layout(layout) x$set_threshold(level) x$show(threshold = NA_integer_, n = 20L)

x$data x$destination x$dt x$filters x$layout x$threshold

Creating a Data Table Appender

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 Layout for this Appender is used only to format console output of its $show() method.

buffer_size

integer scalar. Number of rows of the in-memory data.table

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 columns that have special meaning, based on their name:

  • .id: integer (mandatory). Must always be the first column and is used internally by the Appender

  • .custom: list (optional). If present all custom values of the event (that are not already part of the prototype) are stored in this list column.

Fields

dt

Get the log recorded by this Appender as a data.table with a maximum of buffer_size rows

data

Get the log recorded by this Appender as a data.frame

threshold, set_threshold(level)

character or integer scalar. The minimum log level that triggers this logger. See log_levels

layout, set_layout(layout)

a Layout that will be used for formatting the LogEvents passed to this Appender

destination

The output destination of the Appender in human-readable form (mainly for print output)

filters, set_filters(filters)

a list that may contain functions or any R object with a filter() method. These functions must have exactly one argument: event which will get passed the LogEvent when the Filterable's filter() method is invoked. If all of these functions evaluate to TRUE the LogEvent is passed on. Since LogEvents have reference semantics, filters can also be abused to modify them before they are passed on. Look at the source code of with_log_level() or with_log_value() for examples.

Methods

show(n, threshold)

Show the last n log entries with a log level bellow threshold. The log entries will be formatted for console output via this Appenders Layout

append(event)

Tell the Appender to process a LogEvent event. This method is usually not called by the user, but invoked by a Logger

filter(event)

Determine whether the LogEvent x should be passed on to Appenders (TRUE) or not (FALSE). See also the active binding filters

add_filter(filter, name = NULL), remove_filter(pos)

Add or remove a filter. When adding a filter an optional name can be specified. remove_filter() can remove by position or name (if one was specified)

Comparison AppenderBuffer and AppenderDt

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.

In short: Use AppenderDt if you want an in-memory log for interactive use, and AppenderBuffer if you actually want to buffer events

See Also

LayoutFormat, simple_logging, data.table::data.table

Examples

Run this code
# NOT RUN {
lg <- get_logger("test")
lg$config(list(
  appenders = list(memory = AppenderBuffer$new()),
  threshold = NA,
  propagate = FALSE  # to prevent routing to root logger for this example
))
lg$debug("test")
lg$error("test")

# Displaying the log
lg$appenders$memory$data
lg$appenders$memory$show()
show_log(target = lg$appenders$memory)

# If you pass a Logger to show_log(), it looks for the first AppenderDt
# that it can find.
show_log(target = lg)

# Custom fields are stored in the list column .custom by default
lg$info("the iris data frame", caps = LETTERS[1:5])
lg$appenders$memory$data
lg$appenders$memory$data$.custom[[3]]$caps
lg$config(NULL)
# }

Run the code above in your browser using DataLab