Learn R Programming

lgr (version 0.1.1)

Logger: Loggers

Description

A Logger produces a LogEvent that contains the log message along with metadata (timestamp, calling function) and dispatches it to one or several Appenders which are responsible for the output (console, file, ...) of the event. lgr comes with a single pre-configured Logger called the root Logger that can be accessed via lgr$<...>. Instantiation of new Loggers is only necessary if you want to take advantage of hierarchical logging as outlined in vignette("lgr", package = "lgr").

Arguments

Usage

x <- x$new(name = "(unnamed logger)", appenders = list(), threshold = 400L,
  filters = list(), parent = lgr::lgr, exception_handler =
  default_exception_handler, propagate = TRUE)

x$log(level, msg, ..., timestamp = Sys.time(), caller = get_caller(-7)) x$fatal(msg, ..., caller = get_caller(-8L)) x$error(msg, ..., caller = get_caller(-8L)) x$warn(msg, ..., caller = get_caller(-8L)) x$info(msg, ..., caller = get_caller(-8L)) x$debug(msg, ..., caller = get_caller(-8L)) x$trace(msg, ..., caller = get_caller(-8L)) x$add_appender(appender, name = NULL) x$remove_appender(pos) x$handle_exception(...) x$set_name(x) x$set_exception_handler(fun) x$set_propagate(x) x$set_parent(logger) x$set_threshold(level) x$set_appenders(x) x$spawn(...) x$filter(event) x$add_filter(filter, name = NULL) x$remove_filter(pos) x$set_filters(filters)

x$ancestry x$appenders x$exception_handler x$full_name x$inherited_appenders x$last_event x$name x$parent x$propagate x$threshold x$filters

Creating Loggers

If you are a package developer you should define a new Logger for each package, but you do not need to configure it. Usually only the root logger needs to be configured (new Appenders added/removed, Layouts modified, etc...).

If you just want to log to an additional output (like a log file), you want a new Appender, not a new Logger.

Fields

You can either specify these fields in Logger$new() or modify them after creation with setter functions of the form logger$set_<fieldname>(value) (see examples)

name, set_name(x)

character scalar. A name for the Logger that should be unique among Loggers. This logger name is used in the Loggers print method and can be used by Appenders to indicate which logger the log message came from. If you define a Logger for an R Package (the most common case for defining new Loggers), the logger name should be the same name as the Package name. If you do not define a Logger name manually, a warning will be thrown.

appenders, set_appenders(x)

A single Appender or a list thereof. Appenders control the output of a Logger. Be aware that a Logger also inherits the Appenders of its ancestors (see vignette("lgr", package = "lgr") for more info about Logger inheritance structures).

threshold, set_threshold(level)

character or integer scalar. The minimum log level that triggers this Logger

parent, set_parent(logger)

a Logger. Usually the root logger. Can also be NULL, but all Loggers must be descendants of the root logger for lgr to work as intended.

exception_handler, set_exception_handler()

a function that takes a single argument e. The function used to handle errors that occur during logging. Defaults to demoting errors to warnings.

propagate, set_propagate()

TRUE or FALSE. Should LogEvents be passed on to the appenders of the ancestral Loggers?

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.

Read-Only Bindings

In addition to the active bindings used to access the fields described above, Loggers also have the following additional read-only bindings:

ancestry

A named logical vector of containing the propagate value of each Logger upper the inheritance tree. The names are the names of the appenders.

inherited_appenders

A list of all inherited appenders from ancestral Loggers of the current Logger

full_name

character scalar. The full or qualified name of the logger: The name of the logger and all loggers it inherits from (except for the root logger)

last_event

The last LogEvent produced by the current Logger

Methods

fatal(msg, ..., caller = get_caller(-8L))

Logs a message with level fatal on this logger. If there are unnamed arguments in ..., they will be passed to base::sprintf() along with message. Named arguments will be passed as custom fields to LogEvent. If there are named arguments the names must be unique. caller refers to the name of the calling function and if specified manually must be a character scalar.

error(msg, ..., caller = get_caller(-8L))

Logs a message with level error on this logger. The arguments are interpreted as for fatal().

warn(msg, ..., caller = get_caller(-8L))

Logs a message with level warn on this logger. The arguments are interpreted as for fatal().

info(msg, ..., caller = get_caller(-8L))

Logs a message with level info on this logger. The arguments are interpreted as for fatal().

debug(msg, ..., caller = get_caller(-8L))

Logs a message with level debug on this logger. The arguments are interpreted as for fatal().

trace(msg, ..., caller = get_caller(-8L))

Logs a message with level trace on this logger. The arguments are interpreted as for fatal().

log(level, msg, ..., timestamp, caller)

If the level passes the Logger threshold a new LogEvent with level, msg, timestamp and caller is created. Unnamed arguments in ... will be combined with msg via base::sprintf(). Named arguments in ... will be passed on to LogEvent$new() as custom fields. If no unnamed arguments are present, msg will not be passed to sprintf(), so in that case you do not have to escape "%" characters. If the new LogEvent passes this Loggers filters, it will be dispatched to the relevant Appenders and checked against their thresholds and filters.

add_appender(appender, name = NULL), remove_appender(pos)

Add or remove an Appender. Supplying a name is optional but recommended. After adding an Appender with logger$add_appender(AppenderConsole$new(), name = "console") you can refer to it via logger$appenders$console. remove_appender() can remove an Appender by position or name.

spawn(...)

Spawn a child Logger. lg <- lgr$spawn("mylogger") is equivalent to lg <- Logger$new("mylogger", parent = lgr)

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)

LoggerGlue

LoggerGlue uses glue::glue() instead of base::sprintf() to construct log messages. glue is a very well designed package for string interpolation. It makes composing log messages more flexible and comfortable at the price of an additional dependency and slightly less performance than sprintf().

glue() lets you define temporary named variables inside the call. As with the normal Logger, these named arguments get turned into custom fields; however, you can suppress this behaviour by making named argument start with a ".". Please refer to vignette("lgr", package = "lgr") for examples.

See Also

glue

Examples

Run this code
# NOT RUN {
# lgr::lgr is the root logger that is always available
lgr$info("Today is %s", Sys.Date() )
lgr$fatal("This is a serious error")

# You can create new loggers with Logger$new(). The following creates a
# logger that logs to a temporary file.
tf <- tempfile()
lg <- Logger$new("mylogger", appenders = AppenderFile$new(tf))

# The new logger passes the log message on to the appenders of its parent
# logger, which is by default the root logger. This is why the following
# writes not only the file 'tf', but also to the console.
lg$fatal("blubb")
readLines(tf)

# This logger's print() method depicts this relationship
lg2 <- Logger$new("child", parent = lg)
print(lg2)
print(lg2$ancestry)
print(lg2$full_name)

# use formatting strings and custom fields
tf2 <- tempfile()
lg$add_appender(AppenderFile$new(tf2, layout = LayoutJson$new()))
lg$info("Not all %s support custom fields", "appenders", type = "test")
cat(readLines(tf), sep = "\n")
cat(readLines(tf2), sep = "\n")

# The following works because if no unnamed `...` are present, msg is not
# passed through sprintf() (otherwise you would have to escape the "%")
lg$fatal("100%")

# LoggerGlue
lg <- LoggerGlue$new("glue")
lg$fatal("blah ", "fizz is set to: {fizz}", foo = "bar", fizz = "buzz")
# }

Run the code above in your browser using DataLab