Logger: Loggers

LoggerR Documentation

Loggers

Description

A Logger produces a LogEvent that contains a log message along with metadata (timestamp, calling function, ...) and dispatches it to one or more 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 done with get_logger(). It is advisable to instantiate a separate Logger with a descriptive name for each package/script in which you use lgr.

Super class

lgr::Filterable -> Logger

Active bindings

name

A character scalar. The unique name of each logger, which also includes the names of its ancestors (separated by /).

threshold

integer scalar. The threshold of the Logger, or if it NULL the threshold it inherits from its closest ancestor with a non-NULL threshold

propagate

A TRUE or FALSE. The unique name of each logger, which also includes the names of its ancestors (separated by /).

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. ancestry is an S3 class with a custom format()/print() method, so if you want to use the plain logical vector use unclass(lg$ancestry)

parent

a Logger. The direct ancestor of the Logger.

last_event

The last LogEvent produced by the current Logger

appenders

a list of all Appenders of the Logger

inherited_appenders

A list of all appenders that the Logger inherits from its ancestors

exception_handler

a function. See $set_exception_handler and $handle_exception

Methods

Public methods

Inherited methods

Method new()

Loggers should never be instantiated directly with Logger$new() but rather via get_logger("name"). This way new Loggers are registered in a global namespace which ensures uniqueness and facilitates inheritance between Loggers. If "name" does not exist, a new Logger with that name will be created, otherwise the function returns a Reference to the existing Logger.

name is potentially a "/" separated hierarchical value like foo/bar/baz. Loggers further down the hierarchy are descendants of the loggers above and (by default) inherit threshold and Appenders from their ancestors.

Usage
Logger$new(
  name = "(unnamed logger)",
  appenders = list(),
  threshold = NULL,
  filters = list(),
  exception_handler = default_exception_handler,
  propagate = TRUE
)
Arguments
name, appenders, threshold, filters, exception_handler, propagate

See section Active bindings.


Method log()

Log an event.

If level passes the Logger's threshold a new LogEvent with level, msg, timestamp and caller is created. If the new LogEvent also passes the Loggers Filters, it is be dispatched to the relevant Appenders.

Usage
Logger$log(level, msg, ..., timestamp = Sys.time(), caller = get_caller(-7))
Arguments
level

a character or integer scalar. See log_levels.

msg

character. A log message. If unnamed arguments are supplied in ..., msg is passed on to base::sprintf() (which means "%" have to be escaped), otherwise msg is left as-is.

...

unnamed arguments in ... must be character scalars and are passed to base::sprintf(). Named arguments must have unique names but can be arbitrary R objects that are passed to LogEvent$new() and will be turned into custom fields.

timestamp

POSIXct. Timestamp of the event.

caller

a character scalar. The name of the calling function.


Method fatal()

Log an Event fatal priority

Usage
Logger$fatal(msg, ..., caller = get_caller(-8L))
Arguments
msg, ..., caller

see $log()


Method error()

Log an Event error priority

Usage
Logger$error(msg, ..., caller = get_caller(-8L))
Arguments
msg, ..., caller

see $log()


Method warn()

Log an Event warn priority

Usage
Logger$warn(msg, ..., caller = get_caller(-8L))
Arguments
msg, ..., caller

see $log()


Method info()

Log an Event info priority

Usage
Logger$info(msg, ..., caller = get_caller(-8L))
Arguments
msg, ..., caller

see $log()


Method debug()

Log an Event debug priority

Usage
Logger$debug(msg, ..., caller = get_caller(-8L))
Arguments
msg, ..., caller

see $log()


Method trace()

Log an Event trace priority

Usage
Logger$trace(msg, ..., caller = get_caller(-8L))
Arguments
msg, ..., caller

see $log()


Method list_log()

list_log() is a shortcut for do.call(Logger$log, x). See https://github.com/s-fleck/joblog for an R package that leverages this feature to create custom log event types for tracking the status of cron jobs.

Usage
Logger$list_log(x)
Arguments
x

a named list that must at least contain the named elements level and timestamp

Examples
lg <- get_logger("test")
lg$list_log(list(level = 400, msg = "example"))

Method config()

Load a Logger configuration.

Usage
Logger$config(cfg, file, text, list)
Arguments
cfg
  • a special list object with any or all of the the following elements: appenders, threshold, filters, propagate, exception_handler,

  • the path to a YAML/JSON config file,

  • a character scalar containing YAML/JSON,

  • NULL (to reset the logger config to the default/unconfigured state)

file, text, list

can be used as an alternative to cfg that enforces that the supplied argument is of the specified type. See logger_config for details.


Method add_appender()

Add an Appender to the Logger

Usage
Logger$add_appender(appender, name = NULL)
Arguments
appender

a single Appender

name

a character scalar. Optional but recommended.

Examples
lg <- get_logger("test")
lg$add_appender(AppenderConsole$new(), name = "myconsole")
lg$appenders[[1]]
lg$appenders$myconsole
lg$remove_appender("myconsole")
lg$config(NULL)  # reset config

Method remove_appender()

remove an appender

Usage
Logger$remove_appender(pos)
Arguments
pos

integer index or character name of the Appender(s) to remove


Method handle_exception()

To prevent errors in the logging logic from crashing the whole script, Loggers pass errors they encounter to an exception handler. The default behaviour is to demote errors to warnings. See also set_exception_handler().

Usage
Logger$handle_exception(expr)
Arguments
expr

expression to be evaluated.


Method set_exception_handler()

Set the exception handler of a logger

Usage
Logger$set_exception_handler(fun)
Arguments
fun

a function with the single argument e (an error condition)

Examples
lgr$info(stop("this produces a warning instead of an error"))

Method set_propagate()

Should a Logger propagate events to the Appenders of its ancestors?

Usage
Logger$set_propagate(x)
Arguments
x

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


Method set_threshold()

Set the minimum log level of events that a Logger should process

Usage
Logger$set_threshold(level)
Arguments
level

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


Method set_appenders()

Set the Logger's Appenders

Usage
Logger$set_appenders(x)
Arguments
x

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).


Method spawn()

Spawn a child Logger. This is very similar to using get_logger(), but can be useful in some cases where Loggers are created programmatically

Usage
Logger$spawn(name)
Arguments
name

character vector. Name of the child logger get_logger("foo/bar")$spawn("baz") is equivalent to get_logger("foo/bar/baz")

Note

If you are a package developer you should define a new Logger for each package, but you do not need to configure it. The user of the package should decide how and where to output logging, usually by configuring the root Logger (new Appenders added/removed, Layouts modified, etc...).

See Also

glue

get_logger()

Examples

# lgr::lgr is the root logger that is always available
lgr$info("Today is a good day")
lgr$fatal("This is a serious error")

# Loggers use sprintf() for string formatting by default
lgr$info("Today is %s", Sys.Date() )

# If no unnamed `...` are present, msg is not passed through sprintf()
lgr$fatal("100% bad")  # so this works
lgr$fatal("%s%% bad", 100)  # if you use unnamed arguments, you must escape %

# You can create new loggers with get_logger()
tf <- tempfile()
lg <- get_logger("mylogger")$set_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.
child <- get_logger("lg/child")
print(child)
print(child$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")

# cleanup
unlink(c(tf, tf2))
lg$config(NULL)  # reset logger config

# LoggerGlue
# You can also create a new logger that uses the awesome glue library for
# string formatting instead of sprintf

if (requireNamespace("glue")){

  lg <- get_logger_glue("glue")
  lg$fatal("blah ", "fizz is set to: {fizz}", foo = "bar", fizz = "buzz")
  # prevent creation of custom fields with prefixing a dot
  lg$fatal("blah ", "fizz is set to: {.fizz}", foo = "bar", .fizz = "buzz")

  #' # completely reset 'glue' to an unconfigured vanilla Logger
  get_logger("glue", reset = TRUE)

}


# Configuring a Logger
lg <- get_logger("test")
lg$config(NULL)  # resets logger to unconfigured state

# With setters
lg$
  set_threshold("error")$
  set_propagate(FALSE)$
  set_appenders(AppenderConsole$new(threshold = "info"))

lg$config(NULL)

# With a list
lg$config(list(
  threshold = "error",
  propagate = FALSE,
  appenders = list(AppenderConsole$new(threshold = "info"))
))

lg$config(NULL)  # resets logger to unconfigured state

# Via YAML
cfg <- "
Logger:
  threshold: error
  propagate: false
  appenders:
    AppenderConsole:
      threshold: info
"

lg$config(cfg)
lg$config(NULL)

## ------------------------------------------------
## Method `Logger$list_log`
## ------------------------------------------------

lg <- get_logger("test")
lg$list_log(list(level = 400, msg = "example"))

## ------------------------------------------------
## Method `Logger$add_appender`
## ------------------------------------------------

lg <- get_logger("test")
lg$add_appender(AppenderConsole$new(), name = "myconsole")
lg$appenders[[1]]
lg$appenders$myconsole
lg$remove_appender("myconsole")
lg$config(NULL)  # reset config

## ------------------------------------------------
## Method `Logger$set_exception_handler`
## ------------------------------------------------

lgr$info(stop("this produces a warning instead of an error"))

s-fleck/yog documentation built on March 9, 2023, 7:31 p.m.