lgr v0.3.3

0

Monthly downloads

0th

Percentile

A Fully Featured Logging Framework

A flexible, feature-rich yet light-weight logging framework based on 'R6' classes. It supports hierarchical loggers, custom log levels, arbitrary data fields in log events, logging to plaintext, 'JSON', (rotating) files, memory buffers, and databases, as well as email and push notifications. For a full list of features with examples please refer to the package vignette.

Readme

lgr

CRAN
status Lifecycle:
maturing Travis build
status Codecov test
coverage

lgr is a logging package for R built on the back of R6 classes. It is designed to be flexible, performant and extensible. The package vignette contains a comprehensive description of the features of lgr (some of them unique among R logging packages) along with many code examples.

Users that have not worked with R6 classes before, will find configuring Loggers a bit strange and verbose, but care was taken to keep the syntax for common logging tasks and interactive usage simple and concise. User that have experience with shiny, plumber, python logging or Apache Log4j will feel at home. User that are proficient with R6 classes will also find it easy to extend and customize lgr, for example with their own appenders Loggers or Appenders.

Features

  • Hierarchical loggers like in log4j and python logging. This is useful if you want to be able to configure logging on a per-package basis.
  • An arbitrary number of appenders for each logger. A single logger can write to the console, a logfile, a database, etc… .
  • Allow for custom fields in log events. As opposed to many other logging packages for R a log event is not just a message with a timestamp, but an object that can contain arbitrary data fields. This is useful for producing machine readable logs.
  • Vectorized logging (so lgr$fatal(capture.output(iris)) works)
  • Lightning fast in-memory logs for interactive use.
  • Appenders that write logs to a wide range of destinations:
    • databases (buffered or directly)
    • email or pushbullet
    • plaintext files (with a powerful formatting syntax)
    • JSON files with arbitrary data fields
    • Rotating files that are reset and backed-up after they reach a certain file size or age
    • memory buffers
    • (colored) console output
  • Optional support to use glue instead of sprintf() for composing log messages.

Usage

To log an event with with lgr we call lgr$<logging function>(). Unnamed arguments to the logging function are interpreted by sprintf(). For a way to create loggers that glue instead please refer to the vignette.

lgr$fatal("A critical error")
#> FATAL [08:25:07.182] A critical error
lgr$error("A less severe error")
#> ERROR [08:25:07.211] A less severe error
lgr$warn("A potentially bad situation")
#> WARN  [08:25:07.221] A potentially bad situation
lgr$info("iris has %s rows", nrow(iris))
#> INFO  [08:25:07.223] iris has 150 rows

# the following log levels are hidden by default
lgr$debug("A debug message")
lgr$trace("A finer grained debug message")

A Logger can have several Appenders. For example, we can add a JSON appender to log to a file with little effort.

tf <- tempfile()
lgr$add_appender(AppenderFile$new(tf, layout = LayoutJson$new()))
lgr$info("cars has %s rows", nrow(cars))
#> INFO  [08:25:07.239] cars has 50 rows
cat(readLines(tf))
#> {"level":400,"timestamp":"2019-06-11 08:25:07","logger":"root","caller":"eval","msg":"cars has 50 rows"}

By passing a named argument to info(), warn(), and co you can log not only text but arbitrary R objects. Not all appenders handle such custom fields perfectly, but JSON does. This way you can create logfiles that are machine as well as (somewhat) human readable.

lgr$info("loading cars", "cars", rows = nrow(cars), cols = ncol(cars))
#> INFO  [08:25:07.258] loading cars {rows: 50, cols: 2}
cat(readLines(tf), sep = "\n")
#> {"level":400,"timestamp":"2019-06-11 08:25:07","logger":"root","caller":"eval","msg":"cars has 50 rows"}
#> {"level":400,"timestamp":"2019-06-11 08:25:07","logger":"root","caller":"eval","msg":"loading cars","rows":50,"cols":2}

For more examples please see the package vignette and documentation

See lgr in action

lgr is used to govern console output in my shiny based csv editor shed

# install.packages("remotes")
remotes::install_github("s-fleck/shed")
library(shed)

# log only output from the "shed" logger to a file
logfile <- tempfile()
lgr::get_logger("shed")$add_appender(AppenderFile$new(logfile))
lgr::threshold("all")

# edit away and watch the rstudio console!
lgr$info("starting shed")
shed(iris)  
lgr$info("this will not end up in the log file")

readLines(logfile)

# cleanup
file.remove(logfile)

Development status

The api of lgr is stable and safe for use. The internal implementation of the database logging features still needs some refinement, and if you are using lgr with a database, I would be grateful for any kind of feedback.[1]

lgr is currently very actively developed, and feature requests are encouraged.

Dependencies

R6: The R6 class system provides the framework on which lgr is built and the only Package lgr will ever depend on. If you are a package developer and want to add logging to your package, this is the only transitive dependency you have to worry about, as configuring of the loggers should be left to the user of your package.

Optional dependencies

lgr comes with a long list of optional dependencies that make a wide range of appenders possible. You only need the dependencies for the Appenders you actually want to use. Care was taken to choose packages that are slim, stable, have minimal dependencies, and are well maintained :

Extra appenders (and layouts):

  • jsonlite for JSON logging via LayoutJson. JSON is a popular plaintext based file format that is easy to read for humans and machines alike.
  • rotor for log rotation via AppenderFileRotating and co.
  • DBI for logging to databases. lgr is confirmed to work with the following backends:
    • RSQLite,
    • RMariaDB for MariaDB and MySQL,
    • RPostgres,
    • RJDBC for DB2, and
    • odbc also for DB2. In theory all DBI compliant database packages should work. If you are using lgr with a database backend, please report your (positive and negative) experiences, as database support is still somewhat experimental.
  • data.table for fast in-memory logging with AppenderDt, and also by all database / DBI Appenders.
  • gmailr or sendmailR for email notifications.
  • RPushbullet for push notifications.
  • glue for a more flexible formatting syntax via LoggerGlue and LayoutGlue.

Other extra features:

  • yaml for configuring loggers via YAML files
  • crayon for colored console output.
  • whoami for guessing the user name from various sources. You can also set the user name manually if you want to use it for logging.
  • desc for the package development convenience function use_logger()
  • cli for printing the tree structure of registered loggers with logger_tree()

Other Suggests (future, future.apply) do not provide extra functionality but had to be included for some of the automated unit tests run by lgr.

Installation

You can install lgr from CRAN

install.packages("lgr")

Or you can install the current development version directly from github

#install.packages("remotes")
remotes::install_github("s-fleck/lgr")

Outlook

The long term goal is to support (nearly) all features of the python logging module. If you have experience with python logging or Log4j and are missing features/appenders that you’d like to see, please feel free to post a feature request on the issue tracker.

Acknowledgement

  1. The only database logging I can currently test extensively is DB2 via RJDBC. I do not recommend this setup if you have other options.

Functions in lgr

Name Description
AppenderDbi Log to databases via DBI
Appender Appenders
AppenderFile Log to a file
AppenderFileRotating Log to a rotating file
AppenderDigest Abstract class for digests
AppenderDt Log to an in-memory data.table
AppenderGmail Send emails via gmailr
AppenderConsole Log to the console
AppenderBuffer Log to a memory buffer
AppenderJson Log to a JSON file
AppenderTable Abstract class for logging to tabular structures
AppenderRjdbc Log to databases via RJDBC
AppenderPushbullet Send push-notifications via RPushbullet
EventFilter Event Filters
AppenderMemory Abstract class for logging to memory buffers
AppenderMail Abstract class for email appenders
as.data.frame.LogEvent Coerce LogEvents to Data Frames
basic_config Basic Setup for the Logging System
Logger Loggers
AppenderSendmail Send emails via sendmailR
AppenderSyslog Log to the POSIX System Log
LogEvent Events - The Atomic Unit of Logging
colorize_levels Colorize Levels
get_logger Get/Create a Logger
LayoutFormat Format Log Events as Text
LayoutDbi Format Log Events for Output to Databases
default_should_flush Default should_flush function
Filterable Abstract Class for Filterables
Layout Abstract Class for Layouts
print.Appender Print an Appender object
get_caller Information About the System
suspend_logging Suspend All Logging
pad_right Pad Character Vectors
LayoutGlue Format Log Events as Text via glue
logger_config Logger Configuration Objects
LayoutJson Format LogEvents as JSON
logger_tree Logger Tree
print.LogEvent Print or Format Logging Data
get_log_levels Manage Log Levels
label_levels Label/Unlabel Log Levels
use_logger Setup a Simple Logger for a Package
with_log_level Inject Values into Logging Calls
is_filter Check if an R Object is a Filter
print.Logger Print a Logger Object
select_dbi_layout Select Appropriate Database Table Layout
simple_logging Simple Logging
default_exception_handler Demote an exception to a warning
lgr-package A Fully Featured Logging Framework for R
read_json_lines Read a JSON logfile
print.logger_tree Print Logger Trees
No Results!

Vignettes of lgr

Name
lgr.Rmd
log_flow.svg
No Results!

Last month downloads

Details

Type Package
License MIT + file LICENSE
URL https://s-fleck.github.io/lgr
BugReports https://github.com/s-fleck/lgr/issues
VignetteBuilder knitr
Encoding UTF-8
LazyData true
RoxygenNote 6.1.1
Collate 'Filterable.R' 'utils-sfmisc.R' 'utils.R' 'Appender.R' 'Filter.R' 'log_levels.R' 'print_LogEvent.R' 'Layout.R' 'LogEvent.R' 'Logger.R' 'basic_config.R' 'default_functions.R' 'get_logger.R' 'lgr-package.R' 'logger_config.R' 'logger_tree.R' 'print_Appender.R' 'print_Logger.R' 'read_json_log.R' 'simple_logging.R' 'use_logger.R' 'utils-formatting.R' 'utils-logging.R' 'utils-rd.R' 'utils-rotor.R' 'utils-test.R'
NeedsCompilation no
Packaged 2019-09-26 17:14:55 UTC; hoelk
Repository CRAN
Date/Publication 2019-09-27 09:10:05 UTC

Include our badge in your README

[![Rdoc](http://www.rdocumentation.org/badges/version/lgr)](http://www.rdocumentation.org/packages/lgr)