Skip to content

Commit

Permalink
version 0.1.3
Browse files Browse the repository at this point in the history
  • Loading branch information
gogonzo authored and cran-robot committed Sep 8, 2023
0 parents commit c71c387
Show file tree
Hide file tree
Showing 31 changed files with 1,578 additions and 0 deletions.
30 changes: 30 additions & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Package: teal.logger
Title: Logging Setup for the 'teal' Family of Packages
Version: 0.1.3
Date: 2023-09-05
Authors@R: c(
person("Dawid", "Kaledkowski", , "dawid.kaledkowski@roche.com", role = c("aut", "cre")),
person("Konrad", "Pagacz", role = "aut"),
person("F. Hoffmann-La Roche AG", role = c("cph", "fnd"))
)
Description:
Utilizing the 'logger' framework to record events within a package, specific to 'teal' family of packages.
Supports logging namespaces, hierarchical logging, various log destinations, vectorization, and more.
License: Apache License 2.0
Depends: R (>= 3.6)
Imports: glue, lifecycle, logger (>= 0.2.0), shiny, withr
Suggests: knitr, rmarkdown, testthat (>= 2.0)
VignetteBuilder: knitr
RdMacros: lifecycle
Config/Needs/website: insightsengineering/nesttemplate
Encoding: UTF-8
Language: en-US
RoxygenNote: 7.2.3
NeedsCompilation: no
Packaged: 2023-09-05 17:59:33 UTC; unardid
Author: Dawid Kaledkowski [aut, cre],
Konrad Pagacz [aut],
F. Hoffmann-La Roche AG [cph, fnd]
Maintainer: Dawid Kaledkowski <dawid.kaledkowski@roche.com>
Repository: CRAN
Date/Publication: 2023-09-08 06:40:02 UTC
30 changes: 30 additions & 0 deletions MD5
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
8aac0484f14224ed1118f369749b44d7 *DESCRIPTION
346ff2a4686d632d4cd4adb3478bc732 *NAMESPACE
f437bf5308a68abbb3e5a885a1f1a4f9 *NEWS.md
9c81c8c66f7df75597d8627429992f02 *R/register_logger.R
41309da5a0e6b0c2d15994dba455e427 *R/supress_logs.R
5b752c53088baae6db056b93ab6a2e2e *R/teal.logger-package.R
b10c512afddc91afc9cc2d71717f9f65 *R/utils.R
78700804ed8413b0ad603e9c08eb9add *R/zzz.R
44a274e4cdffb5d1c345345cb6f4454a *README.md
b4373d78847032c61f170b56a96e5e25 *build/vignette.rds
5a110f2b7582ff433659c0bf85ce9f84 *inst/WORDLIST
4485e9faea3a2bc533194712d54140dc *inst/doc/teal-logger.Rmd
802c58e4b1f3042ec698bd5a07d3f637 *inst/doc/teal-logger.html
cb1e46f469cfbbbde29c8b5113e1d789 *man/figures/lifecycle-archived.svg
c0d2e5a54f1fa4ff02bf9533079dd1f7 *man/figures/lifecycle-defunct.svg
a1b8c987c676c16af790f563f96cbb1f *man/figures/lifecycle-deprecated.svg
c3978703d8f40f2679795335715e98f4 *man/figures/lifecycle-experimental.svg
952b59dc07b171b97d5d982924244f61 *man/figures/lifecycle-maturing.svg
27b879bf3677ea76e3991d56ab324081 *man/figures/lifecycle-questioning.svg
6902bbfaf963fbc4ed98b86bda80caa2 *man/figures/lifecycle-soft-deprecated.svg
53b3f893324260b737b3c46ed2a0e643 *man/figures/lifecycle-stable.svg
1c1fe7a759b86dc6dbcbe7797ab8246c *man/figures/lifecycle-superseded.svg
9b93cf7f7b46395b65a156ffbae95548 *man/layout_teal_glue_generator.Rd
88e172c9bbb203bfa96674948c23d7fd *man/log_system_info.Rd
4faf6ce2a3b622f771c5b540cea2c69a *man/register_logger.Rd
4909df4d0ff1e3ecabce46b0f808db86 *man/suppress_logs.Rd
4f2303722e4a2370d0a2e5f0e56de8aa *man/teal.logger-package.Rd
51f235687662ac0bb11b6fa3aedc69e5 *tests/testthat.R
08e22a159c278b732ac30d15d8187ea9 *tests/testthat/test-register_logger.R
4485e9faea3a2bc533194712d54140dc *vignettes/teal-logger.Rmd
6 changes: 6 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Generated by roxygen2: do not edit by hand

export(log_system_info)
export(register_logger)
export(suppress_logs)
importFrom(lifecycle,badge)
21 changes: 21 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# teal.logger 0.1.3

* Fixed CRAN requirements for the first CRAN submission.

# teal.logger 0.1.2

* Updated usage and installation instructions in `README`.
* Updated phrasing of the `Getting Started` vignette.

# teal.logger 0.1.1

* Updated installation instruction in `README`.

# teal.logger 0.1.0

* Initial release of `teal.logger`, a package for the logging setup for `teal` applications.

## Changes (from behavior when functionality was part of `teal`)

### Misc
* The functions `suppress_logs` and `log_system_info` are now part of the API of the package as they are now exported.
128 changes: 128 additions & 0 deletions R/register_logger.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#' Registers a logger instance in a given logging namespace.
#'
#' @description `r lifecycle::badge("experimental")`
#'
#' @note It's a thin wrapper around the `logger` package.
#'
#' @details Creates a new logging namespace specified by the `namespace` argument.
#' When the `layout` and `level` arguments are set to `NULL` (default), the function
#' gets the values for them from system variables or R options.
#' When deciding what to use (either argument, an R option or system variable), the function
#' picks the first non `NULL` value, checking in order:
#' 1. Function argument.
#' 2. System variable.
#' 3. R option.
#'
#' `layout` and `level` can be set as system environment variables, respectively:
#' * `teal.log_layout` as `TEAL.LOG_LAYOUT`,
#' * `teal.log_level` as `TEAL.LOG_LEVEL`.
#'
#' If neither the argument nor the environment variable is set the function uses the following R options:
#' * `options(teal.log_layout)`, which is passed to [logger::layout_glue_generator()],
#' * `options(teal.log_level)`, which is passed to [logger::log_threshold()]
#'
#'
#' The logs are output to `stdout` by default. Check `logger` for more information
#' about layouts and how to use `logger`.
#'
#' @seealso The package vignettes for more help: `browseVignettes("teal.logger")`.
#'
#' @param namespace (`character(1)` or `NA`)\cr
#' the name of the logging namespace
#' @param layout (`character(1)`)\cr
#' the log layout. Alongside the standard logging variables provided by the `logging` package
#' (e.g. `pid`) the `token` variable can be used which will write the last 8 characters of the
#' shiny session token to the log.
#' @param level (`character(1)` or `call`) the log level. Can be passed as
#' character or one of the `logger`'s objects.
#' See [logger::log_threshold()] for more information.
#'
#' @return `invisible(NULL)`
#' @export
#'
#' @examples
#' options(teal.log_layout = "{msg}")
#' options(teal.log_level = "ERROR")
#' register_logger(namespace = "new_namespace")
#' \donttest{
#' logger::log_info("Hello from new_namespace", namespace = "new_namespace")
#' }
#'
register_logger <- function(namespace = NA_character_,
layout = NULL,
level = NULL) {
if (!((is.character(namespace) && length(namespace) == 1) || is.na(namespace))) {
stop("namespace argument to register_logger must be a scalar character or NA.")
}

if (is.null(level)) level <- Sys.getenv("TEAL.LOG_LEVEL")
if (is.null(level) || level == "") level <- getOption("teal.log_level", default = "INFO")

tryCatch(
logger::log_threshold(level, namespace = namespace),
error = function(condition) {
stop(paste(
"The log level passed to logger::log_threshold was invalid.",
"Make sure you pass or set the correct log level.",
"See `logger::log_threshold` for more information"
))
}
)

if (is.null(layout)) layout <- Sys.getenv("TEAL.LOG_LAYOUT")
if (is.null(layout) || layout == "") {
layout <- getOption(
"teal.log_layout",
default = "[{level}] {format(time, \"%Y-%m-%d %H:%M:%OS4\")} pid:{pid} token:[{token}] {ans} {msg}"
)
}
tryCatch(
expr = {
logger::log_layout(layout_teal_glue_generator(layout), namespace = namespace)
logger::log_appender(logger::appender_file(nullfile()), namespace = namespace)
logger::log_success("Set up the logger", namespace = namespace)
logger::log_appender(logger::appender_stdout, namespace = namespace)
},
error = function(condition) {
stop(paste(
"Error setting the layout of the logger.",
"Make sure you pass or set the correct log layout.",
"See `logger::layout` for more information."
))
}
)

invisible(NULL)
}


#' Generate log layout function using common variables available via glue syntax including shiny session token
#'
#' @inheritParams register_logger
#' @return function taking `level` and `msg` arguments - keeping the original call creating the generator
#' in the generator attribute that is returned when calling log_layout for the currently used layout
#' @details this function behaves in the same way as [logger::layout_glue_generator()]
#' but allows the shiny session token (last 8 chars) to be included in the logging layout
#' @keywords internal
layout_teal_glue_generator <- function(layout) {
force(layout)
structure(
function(level, msg, namespace = NA_character_, .logcall = sys.call(), .topcall = sys.call(-1),
.topenv = parent.frame()) {
if (!inherits(level, "loglevel")) {
stop("Invalid log level, see ?logger::log_levels")
}
with(logger::get_logger_meta_variables(
log_level = level, namespace = namespace, .logcall = .logcall, .topcall = .topcall,
.topenv = .topenv
), {
token <- substr(shiny::getDefaultReactiveDomain()$token, 25, 32)
if (length(token) == 0) {
token <- ""
}
glue::glue(layout)
})
},
generator = deparse(match.call())
)
}
22 changes: 22 additions & 0 deletions R/supress_logs.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#' Suppress logger logs
#'
#' This function suppresses `logger` when running tests via `testthat`.
#' To suppress logs for a single test, add this function
#' call within the `testthat::test_that` expression. To suppress logs for an entire
#' test file, call this function at the start of the file.
#'
#' @return `NULL` invisible
#' @export
#' @examples
#' testthat::test_that("An example test", {
#' suppress_logs()
#' testthat::expect_true(TRUE)
#' })
#'
suppress_logs <- function() {
old_log_appenders <- lapply(logger::log_namespaces(), function(ns) logger::log_appender(namespace = ns))
old_log_namespaces <- logger::log_namespaces()
logger::log_appender(logger::appender_file(nullfile()), namespace = logger::log_namespaces())
withr::defer_parent(mapply(logger::log_appender, old_log_appenders, old_log_namespaces))
invisible(NULL)
}
8 changes: 8 additions & 0 deletions R/teal.logger-package.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#' @description Logging Setup for the `teal` Family of Packages.
#'
#' @keywords internal
"_PACKAGE"

# To silence R CMD checks.
#' @importFrom lifecycle badge
NULL
29 changes: 29 additions & 0 deletions R/utils.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#' Logs the basic information about the session.
#'
#' @return `invisible(NULL)`
#' @export
#'
log_system_info <- function() {
paste_pkgs_name_with_version <- function(names) {
vapply(
names,
FUN = function(name) paste(name, utils::packageVersion(name)),
FUN.VALUE = character(1),
USE.NAMES = FALSE
)
}

info <- utils::sessionInfo()

logger::log_trace("Platform: { info$platform }")
logger::log_trace("Running under: { info$running }")
logger::log_trace("{ info$R.version$version.string }")
logger::log_trace("Base packages: { paste(info$basePkgs, collapse = ' ') }")

# Paste package names and versions
pasted_names_and_versions <- paste(paste_pkgs_name_with_version(names(info$otherPkgs)), collapse = ", ")
logger::log_trace("Other attached packages: { pasted_names_and_versions }")

pasted_names_and_versions <- paste(paste_pkgs_name_with_version(names(info$loadedOnly)), collapse = ", ")
logger::log_trace("Loaded packages: { pasted_names_and_versions }")
}
5 changes: 5 additions & 0 deletions R/zzz.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.onLoad <- function(libname, pkgname) { # nolint
# Set up the teal logger instance
register_logger("teal.logger")
invisible()
}
92 changes: 92 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# teal.logger

<!-- start badges -->

[![CRAN Version](https://www.r-pkg.org/badges/version/teal.logger?color=green)](https://cran.r-project.org/package=teal.logger)
[![Total Downloads](http://cranlogs.r-pkg.org/badges/grand-total/teal.logger?color=green)](https://cran.r-project.org/package=teal.logger)
[![Last Month Downloads](http://cranlogs.r-pkg.org/badges/last-month/teal.logger?color=green)](https://cran.r-project.org/package=teal.logger)
[![Last Week Downloads](http://cranlogs.r-pkg.org/badges/last-week/teal.logger?color=green)](https://cran.r-project.org/package=teal.logger)

[![Check 🛠](https://github.com/insightsengineering/teal.logger/actions/workflows/check.yaml/badge.svg)](https://insightsengineering.github.io/teal.logger/main/unit-test-report/)
[![Docs 📚](https://github.com/insightsengineering/teal.logger/actions/workflows/docs.yaml/badge.svg)](https://insightsengineering.github.io/teal.logger/)
[![Code Coverage 📔](https://raw.githubusercontent.com/insightsengineering/teal.logger/_xml_coverage_reports/data/main/badge.svg)](https://insightsengineering.github.io/teal.logger/main/coverage-report/)

![GitHub forks](https://img.shields.io/github/forks/insightsengineering/teal.logger?style=social)
![GitHub repo stars](https://img.shields.io/github/stars/insightsengineering/teal.logger?style=social)

![GitHub commit activity](https://img.shields.io/github/commit-activity/m/insightsengineering/teal.logger)
![GitHub contributors](https://img.shields.io/github/contributors/insightsengineering/teal.logger)
![GitHub last commit](https://img.shields.io/github/last-commit/insightsengineering/teal.logger)
![GitHub pull requests](https://img.shields.io/github/issues-pr/insightsengineering/teal.logger)
![GitHub repo size](https://img.shields.io/github/repo-size/insightsengineering/teal.logger)
![GitHub language count](https://img.shields.io/github/languages/count/insightsengineering/teal.logger)
[![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)
[![Current Version](https://img.shields.io/github/r-package/v/insightsengineering/teal.logger/main?color=purple\&label=package%20version)](https://github.com/insightsengineering/teal.logger/tree/main)
[![Open Issues](https://img.shields.io/github/issues-raw/insightsengineering/teal.logger?color=red\&label=open%20issues)](https://github.com/insightsengineering/teal.logger/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc)
<!-- end badges -->

`teal.logger` is an `R` package providing a unified setup for generating logs using the `logger` package.

## Installation

From July 2023 `insightsengineering` packages are available on [r-universe](https://r-universe.dev/).

```r
# stable versions
install.packages('teal.logger', repos = c('https://insightsengineering.r-universe.dev', 'https://cloud.r-project.org'))

# install.packages("pak")
pak::pak("insightsengineering/teal.logger@*release")
```

Alternatively, you might also use the development version.

```r
# beta versions
install.packages('teal.logger', repos = c('https://pharmaverse.r-universe.dev', 'https://cloud.r-project.org'))

# install.packages("pak")
pak::pak("insightsengineering/teal.logger")
```

## Usage

To understand how to use this package, please refer to the [Getting Started](https://insightsengineering.github.io/teal.logger/latest-tag/articles/teal-logger.html) article, which provides multiple examples of code implementation.

Below is the showcase of the example usage

```r
library(teal.logger)
register_logger(namespace = "namespace1", level = "INFO")
logger::log_info("Hello from namespace1", namespace = "namespace1")
logger::log_warn("Hello from namespace1", namespace = "namespace1")
logger::log_success("Hello from namespace1", namespace = "namespace1")
# [INFO] 2023-08-31 12:02:41.0678 pid:7128 token:[] namespace1 Hello from namespace1
# [WARN] 2023-08-31 12:02:42.4872 pid:7128 token:[] namespace1 Hello from namespace
# [SUCCESS] 2023-08-31 12:02:58.7155 pid:7128 token:[] namespace1 Hello from namespace

register_logger(namespace = "namespace2", level = "WARN")
logger::log_info("Hello from namespace2", namespace = "namespace2")
logger::log_warn("Hello from namespace2", namespace = "namespace2")
logger::log_error("Hello from namespace2", namespace = "namespace2")
# [WARN] 2023-08-31 12:04:34.9361 pid:7128 token:[] namespace2 Hello from namespace2
# [ERROR] 2023-08-31 12:04:35.5721 pid:7128 token:[] namespace2 Hello from namespace2
```

## Getting help

If you encounter a bug or you have a feature request - please file an issue. For questions, discussions and staying up to date, please use the "teal" channel in the [`pharmaverse` slack workspace](https://pharmaverse.slack.com).

## Stargazers and Forkers

### Stargazers over time

[![Stargazers over time](https://starchart.cc/insightsengineering/teal.logger.svg)](https://starchart.cc/insightsengineering/teal.logger)

### Stargazers

[![Stargazers repo roster for @insightsengineering/teal.logger](https://reporoster.com/stars/insightsengineering/teal.logger)](https://github.com/insightsengineering/teal.logger/stargazers)

### Forkers

[![Forkers repo roster for @insightsengineering/teal.logger](https://reporoster.com/forks/insightsengineering/teal.logger)](https://github.com/insightsengineering/teal.logger/network/members)
Binary file added build/vignette.rds
Binary file not shown.
5 changes: 5 additions & 0 deletions inst/WORDLIST
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Forkers
Hoffmann
funder
repo
vectorization

0 comments on commit c71c387

Please sign in to comment.