To make a successful log record, logger
requires the
below components:
-
a log request, eg
log_error('Oops')
- including the log level (importance) of the record, which will be
later used to decide if the log record is to be delivered or not:
ERROR
in this case - R objects to be logged: a simple string in this case, although it
could be a character vector or any R object(s) that can be converted
into a character vector by the
formatter
function
- including the log level (importance) of the record, which will be
later used to decide if the log record is to be delivered or not:
-
the environment and meta-information of the log request, eg actual timestamp, hostname of the computer, the name of the user running the R script, the pid of the R process, calling function and the actual call etc.
f <- function() get_logger_meta_variables(log_level = INFO) f() #> $ns #> [1] NA #> #> $ans #> [1] "global" #> #> $topenv #> [1] "R_GlobalEnv" #> #> $fn #> [1] "f" #> #> $call #> [1] "f()" #> #> $time #> [1] "2024-10-21 07:31:25 UTC" #> #> $levelr #> Log level: INFO #> #> $level #> [1] "INFO" #> #> $pid #> [1] 9957 #> #> $r_version #> [1] "4.4.1" #> #> $ns_pkg_version #> [1] NA #> #> $node #> [1] "fv-az1198-739" #> #> $arch #> [1] "x86_64" #> #> $os_name #> [1] "Linux" #> #> $os_release #> [1] "6.5.0-1025-azure" #> #> $os_version #> [1] "#26~22.04.1-Ubuntu SMP Thu Jul 11 22:33:04 UTC 2024" #> #> $user #> [1] "runner"
-
a logger definition to process the log request, including
-
log level
threshold
, egINFO
, which defines the minimum log level required for actual logging – all log requests with lower log level will be thrown awaylog_threshold() #> Log level: INFO ERROR <= INFO #> [1] TRUE log_error("Oops") #> ERROR [2024-10-21 07:31:25] Oops
-
formatter
function, which takes R objects and converts those into actual log message(s) to be then passed to thelayout
function for the log record rendering – such aspaste
,sprintf
,glue
or eg the below custom example: -
layout
function, which takes log message(s) and further information on the log request (such as timestamp, hostname, username, calling function etc) to render the actual log records eg human-readable text, JSON etc -
appender
function, which takes fully-rendered log record(s) and delivers to somewhere, egstdout
, a file or a streaming service, egappender <- function(line) cat(line, "\n") appender("INFO [now] I am a log message") #> INFO [now] I am a log message
-
Putting all these together (by explicitly setting the default config
in the global
namespace):
log_threshold(INFO)
log_formatter(formatter_glue)
log_layout(layout_simple)
log_appender(appender_stdout)
log_debug("I am a low level log message that will not be printed with a high log level threshold")
log_warn("I am a higher level log message that is very likely to be printed")
#> WARN [2024-10-21 07:31:26] I am a higher level log message that is very likely to be printed
Note, that all logger
definitions and requests are tied
to a logging namespace, and one log request might trigger multiple
logger
definitions as well (stacking). Find more
information on these in the Customizing
the format and destination of log records vignette.