Logger {lgr} | R 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 theLogger
, or if itNULL
the threshold it inherits from its closest ancestor with a non-NULL
thresholdpropagate
A
TRUE
orFALSE
. 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 customformat()
/print()
method, so if you want to use the plain logical vector useunclass(lg$ancestry)
parent
a
Logger
. The direct ancestor of theLogger
.last_event
The last LogEvent produced by the current Logger
appenders
a
list
of all Appenders of the Loggerinherited_appenders
A
list
of all appenders that the Logger inherits from its ancestorsexception_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
orinteger
scalar. See log_levels.msg
character
. A log message. If unnamed arguments are supplied in...
,msg
is passed on tobase::sprintf()
(which means"%"
have to be escaped), otherwisemsg
is left as-is....
unnamed arguments in
...
must becharacter
scalars and are passed tobase::sprintf()
. Named arguments must have unique names but can be arbitrary R objects that are passed toLogEvent$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 elementslevel
andtimestamp
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 containingYAML/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 orcharacter
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 argumente
(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
orFALSE
. 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
orinteger
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 (seevignette("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 loggerget_logger("foo/bar")$spawn("baz")
is equivalent toget_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
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"))