Skip to content

Commit

Permalink
Merge branch 'main' into mnt/dev_version
Browse files Browse the repository at this point in the history
  • Loading branch information
MEO265 authored May 3, 2024
2 parents 98c87fb + f50b26f commit 0ac0365
Show file tree
Hide file tree
Showing 22 changed files with 110 additions and 33 deletions.
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
Package: loggit2
Title: Easy-to-Use, Dependencyless Logger for R
Title: Easy-to-Use, Dependencyless Logger
Description:
An easy-to-use 'ndjson' (newline-delimited 'JSON') logger.
It provides a set of wrappings for base R's message(), warning(), and
stop() functions that maintain identical functionality, but also log
the handler message to an 'ndjson' log file.
No change in existing code is necessary to use this package, and should
only require additions to fully leverage the power of the logging system.
Version: 2.2.1.9999
Version: 2.2.2.9999
Authors@R: c(
person("Matthias", "Ollech", role = c("cre", "aut"), email = "[email protected]"),
person("Ryan", "Price", role = c("fnd", "aut"))
Expand Down
2 changes: 1 addition & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# loggit2 DEV

# loggit2 2.2.1
# loggit2 2.2.2

## Breaking changes
* Custom sanitizers and unsanitizers must be able to process character vectors.
Expand Down
12 changes: 11 additions & 1 deletion R/configurations.R
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,28 @@
#' @details No logs outside of a temporary directory will be written until this is set explicitly, as per CRAN policy.

Check warning on line 15 in R/configurations.R

View workflow job for this annotation

GitHub Actions / lint

file=R/configurations.R,line=15,col=81,[line_length_linter] Lines should not be more than 80 characters. This line is 118 characters.
#' Therefore, the default behavior is to create a file named `loggit.log` in your system's temporary directory.

Check warning on line 16 in R/configurations.R

View workflow job for this annotation

GitHub Actions / lint

file=R/configurations.R,line=16,col=81,[line_length_linter] Lines should not be more than 80 characters. This line is 111 characters.
#'
#' @return Invisible `NULL`.
#'
#' @examples set_logfile(file.path(tempdir(), "loggit.log"))
#'
#' @export
set_logfile <- function(logfile = NULL, confirm = TRUE, create = TRUE) {
if (is.null(logfile)) {
logfile <- file.path(tempdir(), "loggit.log")
}
if(create && !file.exists(logfile)) file.create(logfile)
if (create && !file.exists(logfile)) file.create(logfile)
.config$logfile <- normalizePath(logfile, winslash = "/", mustWork = FALSE)
if (confirm) base::message("Log file set to ", .config$logfile)
invisible(NULL)
}


#' Get Log File
#'
#' Return the log file that `loggit()` will write to.
#'
#' @return The log file path.
#'
#' @examples get_logfile()
#'
#' @export
Expand All @@ -56,6 +61,8 @@ get_logfile <- function() {
#' @param confirm Print confirmation message of timestamp format? Defaults to
#' `TRUE`.
#'
#' @return Invisible `NULL`.
#'
#' @examples set_timestamp_format("%Y-%m-%d %H:%M:%S")
#'
#' @export
Expand All @@ -67,13 +74,16 @@ set_timestamp_format <- function(ts_format = "%Y-%m-%dT%H:%M:%S%z", confirm = TR
"Current time in this format: ", format(Sys.time(), format = ts_format)
)
}
invisible(NULL)
}


#' Get Timestamp Format
#'
#' Get timestamp format for use in output logs.
#'
#' @return The timestamp format.
#'
#' @examples get_timestamp_format()
#'
#' @export
Expand Down
6 changes: 5 additions & 1 deletion R/handlers.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
#' This function is identical to base R's [`message`][base::message],
#' but it includes logging of the exception message via `loggit()`.
#'
#' @inherit base::message params return
#' @inherit base::message params
#'
#' @param .loggit Should `loggit()` execute? Defaults to `TRUE`.
#' @param echo Should `loggit()`'s log entry be echoed to the console, as well? Defaults to `TRUE`.

Check warning on line 9 in R/handlers.R

View workflow job for this annotation

GitHub Actions / lint

file=R/handlers.R,line=9,col=81,[line_length_linter] Lines should not be more than 80 characters. This line is 99 characters.
#'
#' @return Invisible `NULL`.
#'
#' @family handlers
#'
#' @examples
Expand Down Expand Up @@ -92,6 +94,8 @@ warning <- function(..., call. = TRUE, immediate. = FALSE, noBreaks. = FALSE,
#' @inherit base::stop params
#' @inheritParams message
#'
#' @return No return value.
#'
#' @family handlers
#'
#' @examples
Expand Down
9 changes: 7 additions & 2 deletions R/json.R
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ default_ndjson_sanitizer <- function(string) {
string <- gsub(pattern = k, replacement = sanitizer_map[[k]], string, fixed = TRUE)
}

# Explicit NAs must be marked so that no new ones are inserted when rotating the log
string[is.na(string)] <- "__NA__"

string
}

Expand All @@ -54,6 +57,8 @@ default_ndjson_unsanitizer <- function(string) {
string <- gsub(pattern = sanitizer_map[[k]], replacement = k, string, fixed = TRUE)
}

string[string == "__NA__"] <- NA_character_

string
}

Expand Down Expand Up @@ -136,9 +141,9 @@ read_ndjson <- function(logfile, unsanitizer = default_ndjson_unsanitizer) {
# is the corresponding key.
if (logfieldnum %% 2L == 0L) {
colname <- rowdata[logfieldnum - 1L]
# If the field doesn't exist, create it with the right length
# If the field doesn't exist, create it (filled with NAs) with the right length
if (!(colname %in% names(log_df))) {
log_df[[colname]] <- character(length = rowcount)
log_df[[colname]] <- rep(NA_character_, length = rowcount)
}
# Unsanitize text, and store to df
rowdata[logfieldnum] <- unsanitizer(rowdata[logfieldnum])
Expand Down
2 changes: 2 additions & 0 deletions R/loggit.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#' @param sanitizer [Sanitizer function][sanitizers] to run over elements in log data.
#' Defaults to [default_ndjson_sanitizer()].
#'
#' @return Invisible `NULL`.
#'
#' @examples
#' loggit("INFO", "This is a message", but_maybe = "you want more fields?",
#' sure = "why not?", like = 2, or = 10, what = "ever")
Expand Down
4 changes: 3 additions & 1 deletion R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ read_logs <- function(logfile = get_logfile(), unsanitizer = default_ndjson_unsa
#' @param rotate_lines The number of log entries to keep in the logfile.
#' @param logfile Log file to truncate.
#'
#' @return Invisible `NULL`.
#'
#' @examples
#' # Truncate "default" log file to 100 lines
#' set_logfile()
Expand All @@ -49,7 +51,7 @@ rotate_logs <- function(rotate_lines = 100000L, logfile = get_logfile()) {
cat(NULL, file = logfile)
return(invisible(NULL))
}
log_df <- read_logs(logfile)
log_df <- read_logs(logfile, unsanitizer = identity)
if (nrow(log_df) <= rotate_lines) {
return(invisible(NULL))
}
Expand Down
10 changes: 7 additions & 3 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
options(width = 150)
old <- options(width = 150)
```

Easy-to-use, dependencyless Logger for R
Expand Down Expand Up @@ -105,6 +105,10 @@ or, get the latest development version from GitHub via

Acknowledgments
-----------
This package is based on the [eponymous package by Ryan Price](https://github.com/ryapric/loggit2), specifically version 2.1.1.
This package is based on the [eponymous package by Ryan Price](https://github.com/ryapric/loggit), specifically version 2.1.1.

Due to technical reasons, this repository is not a GitHub fork of [Ryan's repository](https://github.com/ryapric/loggit2).
Due to technical reasons, this repository is not a GitHub fork of [Ryan's repository](https://github.com/ryapric/loggit).

```{r, include = FALSE}
options(old)
```
32 changes: 16 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<!-- badges: start -->

[![CRAN_Status_Badge](http://www.r-pkg.org/badges/version/loggit2)](https://cran.r-project.org/package=loggit2)
[![Downloads](https://cranlogs.r-pkg.org/badges/last-week/loggit2)](https://cran.r-project.org/package=loggit2)
[![Downloads](https://cranlogs.r-pkg.org/badges/grand-total/loggit2)](https://cran.r-project.org/package=loggit2)
[![R-CMD-check](https://github.com/MEO265/loggit2/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/MEO265/loggit2/actions/workflows/R-CMD-check.yaml)
[![codecov](https://codecov.io/gh/MEO265/loggit2/graph/badge.svg)](https://codecov.io/gh/MEO265/loggit2)
<!-- badges: end -->
Expand All @@ -29,7 +29,7 @@ for the Getting Started guide.

Additionally, the boilerplate to get going with `loggit2` is minimal at
worst. No need to write custom formatters, handlers, levels, etc. –
***just loggit!***
***just loggit2!***

## Usage

Expand All @@ -44,13 +44,13 @@ at the desired locations.

``` r
loggit2::message("This is a message")
#> {"timestamp": "2024-04-30T18:19:08+0200", "log_lvl": "INFO", "log_msg": "This is a message__LF__"}
#> {"timestamp": "2024-05-02T18:27:28+0200", "log_lvl": "INFO", "log_msg": "This is a message__LF__"}
#> This is a message
loggit2::warning("This is a warning")
#> {"timestamp": "2024-04-30T18:19:08+0200", "log_lvl": "WARN", "log_msg": "This is a warning"}
#> {"timestamp": "2024-05-02T18:27:28+0200", "log_lvl": "WARN", "log_msg": "This is a warning"}
#> Warning: This is a warning
loggit2::stop("This is an error")
#> {"timestamp": "2024-04-30T18:19:08+0200", "log_lvl": "ERROR", "log_msg": "This is an error"}
#> {"timestamp": "2024-05-02T18:27:28+0200", "log_lvl": "ERROR", "log_msg": "This is an error"}
#> Error in eval(expr, envir, enclos): This is an error
```

Expand Down Expand Up @@ -83,18 +83,18 @@ it’ll become a structured log.

``` r
loggit2::loggit("ERROR", "This will log an error", anything_else = "you want to include")
#> {"timestamp": "2024-04-30T18:19:08+0200", "log_lvl": "ERROR", "log_msg": "This will log an error", "anything_else": "you want to include"}
#> {"timestamp": "2024-05-02T18:27:28+0200", "log_lvl": "ERROR", "log_msg": "This will log an error", "anything_else": "you want to include"}

# Read log file into data frame to implement logic based on entries
loggit2::read_logs()
#> timestamp log_lvl log_msg anything_else
#> 1 2024-04-30T18:19:08+0200 INFO This is a message\n
#> 2 2024-04-30T18:19:08+0200 WARN This is a warning
#> 3 2024-04-30T18:19:08+0200 ERROR This is an error
#> 4 2024-04-30T18:19:08+0200 INFO This is another message\n
#> 5 2024-04-30T18:19:08+0200 WARN This is another warning
#> 6 2024-04-30T18:19:08+0200 ERROR This is another error
#> 7 2024-04-30T18:19:08+0200 ERROR This will log an error you want to include
#> 1 2024-05-02T18:27:28+0200 INFO This is a message\n
#> 2 2024-05-02T18:27:28+0200 WARN This is a warning
#> 3 2024-05-02T18:27:28+0200 ERROR This is an error
#> 4 2024-05-02T18:27:28+0200 INFO This is another message\n
#> 5 2024-05-02T18:27:28+0200 WARN This is another warning
#> 6 2024-05-02T18:27:28+0200 ERROR This is another error
#> 7 2024-05-02T18:27:28+0200 ERROR This will log an error you want to include
```

Check out the
Expand All @@ -113,8 +113,8 @@ or, get the latest development version from GitHub via

## Acknowledgments

This package is based on the ["loggit" package by Ryan
Price](https://github.com/ryapric/loggit2), specifically version 2.1.1.
This package is based on the [eponymous package by Ryan
Price](https://github.com/ryapric/loggit), specifically version 2.1.1.

Due to technical reasons, this repository is not a GitHub fork of
[Ryan’s repository](https://github.com/ryapric/loggit2).
[Ryan’s repository](https://github.com/ryapric/loggit).
3 changes: 3 additions & 0 deletions man/get_logfile.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions man/get_timestamp_format.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions man/loggit.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions man/message.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions man/rotate_logs.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions man/set_logfile.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions man/set_timestamp_format.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions man/stop.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions tests/testthat/_snaps/utils/test.loggit
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{"timestamp": "2024-05-01T20:09:27+0200", "log_lvl": "INFO", "log_msg": "log_98"}
{"timestamp": "2024-05-01T20:09:27+0200", "log_lvl": "INFO", "log_msg": "log_99"}
{"timestamp": "2024-05-01T20:09:27+0200", "log_lvl": "INFO", "log_msg": "log_100 __LF__", "extra": "extra"}
2 changes: 1 addition & 1 deletion tests/testthat/test-json.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ test_that("write_logs() and read_logs() work in tandem", {
log_df_want <- data.frame(
log_lvl = "INFO",
log_msg = c("msg1", "msg2", "msg3", "msg4: should: be :displayed:"),
extra = c("", "", "", "fields"),
extra = c(NA_character_, NA_character_, NA_character_, "fields"),
stringsAsFactors = FALSE
)

Expand Down
22 changes: 18 additions & 4 deletions tests/testthat/test-utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ test_that("rotate_logs works on default log file", {

rotate_lines <- 50L
rotate_logs(rotate_lines = rotate_lines)
log_df <- read_logs()
log_df <- read_logs()
expect_identical(nrow(log_df), rotate_lines)

rotate_lines <- 0L
Expand Down Expand Up @@ -38,13 +38,13 @@ test_that("rotate_logs works on non-default log file", {

rotate_lines <- 150L
rotate_logs(rotate_lines = rotate_lines, other_logfile)
log_df <- read_logs( other_logfile)
expect_identical(nrow(log_df), 100L)
log_df <- read_logs(other_logfile)
expect_identical(nrow(log_df), 100L)

rotate_lines <- 50L
rotate_logs(rotate_lines = rotate_lines, other_logfile)
log_df <- read_logs(other_logfile)
expect_identical(nrow(log_df), rotate_lines)
expect_identical(nrow(log_df), rotate_lines)

rotate_lines <- 0L
rotate_logs(rotate_lines = rotate_lines, other_logfile)
Expand All @@ -56,3 +56,17 @@ expect_identical(nrow(log_df), rotate_lines)
expect_identical(nrow(log_df), 1L)
})
cleanup()

test_that("rotate_logs preserves sanitization", {

tmp_log <- file.path(tempdir(), "test.loggit")
file.copy("testdata/test.loggit", tmp_log)
on.exit(file.remove(tmp_log))

bevor <- read_logs(tmp_log)

rotate_lines <- 3L
rotate_logs(rotate_lines = rotate_lines, logfile = tmp_log)
expect_snapshot_file(tmp_log)

})
Loading

0 comments on commit 0ac0365

Please sign in to comment.