diff --git a/DESCRIPTION b/DESCRIPTION index 2bfd6b4..38fbb33 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -29,7 +29,7 @@ Suggests: testthat (>= 2.0.0) URL: https://github.com/ryapric/loggit BugReports: https://github.com/ryapric/loggit/issues -RoxygenNote: 7.1.1 +RoxygenNote: 7.1.2 Encoding: UTF-8 Roxygen: list(markdown = TRUE) VignetteBuilder: knitr diff --git a/NAMESPACE b/NAMESPACE index 03cf87f..c1c706d 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,12 +1,14 @@ # Generated by roxygen2: do not edit by hand export(get_logfile) +export(get_rotate_lines) export(get_timestamp_format) export(loggit) export(message) export(read_logs) export(rotate_logs) export(set_logfile) +export(set_rotate_lines) export(set_timestamp_format) export(stop) export(warning) diff --git a/R/configurations.R b/R/configurations.R index 3c1ec29..99a2a91 100644 --- a/R/configurations.R +++ b/R/configurations.R @@ -81,3 +81,46 @@ set_timestamp_format <- function(ts_format = "%Y-%m-%dT%H:%M:%S%z", confirm = TR get_timestamp_format <- function() { .config$ts_format } + +#' Set Log File Rotation +#' +#' Set configuration for the number of lines after which log files are. +#' truncated. The function will echo out the currently set line number if +#' is set, or else it will echo that there is no limit set. +#' +#' This function provides a means of setting automatic log file truncation. +#' Log files are not truncated when the value is set to `NULL`, which is +#' also the default setting. +#' +#' @param rotate_lines The number of log entries to keep in the logfile. +#' Defaults to `NULL`, see `rotate_logs()` for implementation. +#' @param confirm Print confirmation message of timestamp format? Defaults to +#' `TRUE`. +#' +#' @examples +#' set_rotate_lines(100) # set limit to 100 lines +#' set_rotate_lines(NULL) # turn off auto-truncation +#' +#' @export +set_rotate_lines <- function(rotate_lines = NULL, confirm = TRUE) { + .config$rotate_lines <- rotate_lines + if (confirm) { + if (is.null(rotate_lines)) { + print(paste0("Log file is not auto-truncated")) + } else { + print(paste0("Truncate log file after ", rotate_lines, " lines")) + } + } +} + +#' Get Log File Rotation +#' +#' Get the configuration for the number of lines after which log files are +#' truncated. +#' +#' @examples get_rotate_lines() +#' +#' @export +get_rotate_lines <- function() { + .config$rotate_lines +} diff --git a/R/loggit.R b/R/loggit.R index 2339f58..71ce740 100644 --- a/R/loggit.R +++ b/R/loggit.R @@ -81,4 +81,9 @@ loggit <- function(log_lvl, log_msg, ..., echo = TRUE, custom_log_lvl = FALSE, s } write_ndjson(log_df, echo = echo) + + # Truncate log files if needed + if (!is.null(get_rotate_lines())) { + rotate_logs(get_rotate_lines(), get_logfile()) + } } diff --git a/R/utils.R b/R/utils.R index 1293e98..f71323f 100644 --- a/R/utils.R +++ b/R/utils.R @@ -80,8 +80,11 @@ read_logs <- function(logfile, unsanitizer) { #' #' @export rotate_logs <- function(rotate_lines = 100000, logfile) { - if (missing(logfile)) logfile <- get_logfile() - log_df <- read_logs(logfile) - log_df <- log_df[(nrow(log_df) - rotate_lines + 1):nrow(log_df), ] - write_ndjson(log_df, logfile, echo = FALSE, overwrite = TRUE) + if (!is.null(rotate_lines)) { + rotate_lines <- as.integer(rotate_lines) + if (missing(logfile)) logfile <- get_logfile() + log_df <- read_logs(logfile) + log_df <- log_df[max(1L, (nrow(log_df) - rotate_lines + 1)):nrow(log_df), ] + write_ndjson(log_df, logfile, echo = FALSE, overwrite = TRUE) + } } diff --git a/R/zzz.R b/R/zzz.R index 0a83d26..a93df9a 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -1,4 +1,13 @@ .onLoad <- function(libname, pkgname) { set_logfile(confirm = FALSE) set_timestamp_format(confirm = FALSE) + set_rotate_lines(NULL, confirm = FALSE) + invisible(NULL) +} + +.onUnload <- function(libpath) { + for (i in names(.config)) { + .config[[i]] <- NULL + } + invisible(NULL) } diff --git a/man/get_rotate_lines.Rd b/man/get_rotate_lines.Rd new file mode 100644 index 0000000..d444b59 --- /dev/null +++ b/man/get_rotate_lines.Rd @@ -0,0 +1,16 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/configurations.R +\name{get_rotate_lines} +\alias{get_rotate_lines} +\title{Get Log File Rotation} +\usage{ +get_rotate_lines() +} +\description{ +Get the configuration for the number of lines after which log files are +truncated. +} +\examples{ +get_rotate_lines() + +} diff --git a/man/set_rotate_lines.Rd b/man/set_rotate_lines.Rd new file mode 100644 index 0000000..f664b54 --- /dev/null +++ b/man/set_rotate_lines.Rd @@ -0,0 +1,30 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/configurations.R +\name{set_rotate_lines} +\alias{set_rotate_lines} +\title{Set Log File Rotation} +\usage{ +set_rotate_lines(rotate_lines = NULL, confirm = TRUE) +} +\arguments{ +\item{rotate_lines}{The number of log entries to keep in the logfile. +Defaults to \code{NULL}, see \code{rotate_logs()} for implementation.} + +\item{confirm}{Print confirmation message of timestamp format? Defaults to +\code{TRUE}.} +} +\description{ +Set configuration for the number of lines after which log files are. +truncated. The function will echo out the currently set line number if +is set, or else it will echo that there is no limit set. +} +\details{ +This function provides a means of setting automatic log file truncation. +Log files are not truncated when the value is set to \code{NULL}, which is +also the default setting. +} +\examples{ +set_rotate_lines(100) # set limit to 100 lines +set_rotate_lines(NULL) # turn off auto-truncation + +} diff --git a/tests/testthat/test_loggit.R b/tests/testthat/test_loggit.R index e89a98f..6255137 100644 --- a/tests/testthat/test_loggit.R +++ b/tests/testthat/test_loggit.R @@ -39,3 +39,31 @@ test_that("Log file is returned via read_logs()", { expect_true("data.frame" %in% class(log_df)) }) cleanup() + + +# == + +test_that("Automatic log rotation is working", { + + rotate_lines <- 10 + + set_rotate_lines(rotate_lines) # turn on + for (i in 1:(rotate_lines + 10)) { + loggit("INFO", paste0("log_", i), echo = FALSE) + log_df <- read_logs() + if (i <= rotate_lines) { + expect_true(nrow(log_df) == i) + } else { + expect_true(nrow(log_df) == rotate_lines) + } + } + + set_rotate_lines(NULL) # turn off + for (i in 1:(rotate_lines + 10)) { + loggit("INFO", paste0("log_", i), echo = FALSE) + log_df <- read_logs() + expect_true(nrow(log_df) == i + rotate_lines) + } + +}) +cleanup()