Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/s-fleck/rotor
Rotate logfiles (and other files) from R
https://github.com/s-fleck/rotor
backup logging logrotate logrotation r
Last synced: 3 months ago
JSON representation
Rotate logfiles (and other files) from R
- Host: GitHub
- URL: https://github.com/s-fleck/rotor
- Owner: s-fleck
- License: other
- Created: 2019-03-27T20:25:33.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2022-10-17T08:13:57.000Z (about 2 years ago)
- Last Synced: 2024-06-04T23:55:33.952Z (5 months ago)
- Topics: backup, logging, logrotate, logrotation, r
- Language: R
- Homepage: https://s-fleck.github.io/rotor/reference/index.html
- Size: 896 KB
- Stars: 12
- Watchers: 2
- Forks: 1
- Open Issues: 6
-
Metadata Files:
- Readme: README.Rmd
- License: LICENSE
Awesome Lists containing this project
- jimsghstars - s-fleck/rotor - Rotate logfiles (and other files) from R (R)
README
---
output: github_document
---```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
```
# rotor[![Lifecycle: maturing](https://img.shields.io/badge/lifecycle-maturing-blue.svg)](https://lifecycle.r-lib.org/articles/stages.html#maturing)
[![CRAN status](https://www.r-pkg.org/badges/version/rotor)](https://cran.r-project.org/package=rotor)**rotor** provides a cross platform R reimagination of
[logrotate](https://linux.die.net/man/8/logrotate). It is a companion package to
the logging package [lgr](https://github.com/s-fleck/lgr). In
contrast to logrotate, rotor relies solely on information encoded in a suffixes
of file names for conditionally creating backups (i.e. a timestamp or index). It
therefore also works with backups created by other tools, as long as the
filename has a format that rotor can understand.`rotate()`, `rotate_date()`, and `rotate_time()` move a file and insert a suffix
(either an integer or a timestamp) into the filename. In addition, they create
an empty file in place of the original one. This is useful for log rotation.
`backup()`, `backup_date()` and `backup_time()` do the same but keep the
original file.rotor also includes utility functions for finding and examining the backups of a
file: `list_backups()`, `backup_info()`, `n_backups`, `newest_backup()`,
`oldest_backup()`. See the
[function reference](https://s-fleck.github.io/rotor/reference/index.html) for
details.## Installation
You can install the released version of rotor from [CRAN](https://CRAN.R-project.org) with:
``` r
install.packages("rotor")
```And the development version from [GitHub](https://github.com/) with:
``` r
# install.packages("remotes")
remotes::install_github("s-fleck/rotor")
```
## ExampleFirst we create a temporary directory for the files created by the code examples
```{r setup, results = "hide"}
library(rotor)# create a directory
td <- file.path(tempdir(), "rotor")
dir.create(td, recursive = TRUE)# create an example logfile
tf <- file.path(td, "mylogfile.log")
writeLines("An important message", tf)
```### Indexed backups
`backup()` makes a copy of a file and inserts an index between the filename
and the file extension. The file with the index `1` is always the most recently
made backup.
```{r backup index, collapse=TRUE}
backup(tf)# backup and rotate also support compression
backup(tf, compression = TRUE)# display backups of a file
list_backups(tf)
````rotate()` also backs up a file, but replaces the original file with an empty
one.```{r rotate index, collapse=TRUE}
rotate(tf)
list_backups(tf)# the original file is now empty
readLines(tf)# its content was moved to the first backup
readLines(list_backups(tf)[[1]])# we can now safely write to the original file
writeLines("another important message", tf)
```The `max_backups` parameter limits the maximum number of backups rotor will
keep of a file. Notice how the zipped backup we created above moves to index 4
as we create two new backups.
```{r}
backup(tf, max_backups = 4)
backup(tf, max_backups = 4)list_backups(tf)
```We can also use `prune_backups()` to delete old backups. Other than ensuring
that no new backups is created, it works identically to using `backup()` with
the `max_backups` parameter. By setting it to `0`, we delete all backups.
```{r}
prune_backups(tf, max_backups = 0)
```## Timestamped backups
**rotor** can also create timestamped backups. `backup_date()` creates uses a
Date (`yyyy-mm-dd`) timestamp, `backup_time()` uses a full datetime-stamp by
default (`yyyy-mm-dd--hh-mm-ss`). The format of the timestamp can be modified
with a subset of the formatting tokens understood by `strftime()` (within
certain restrictions). Backups created with both functions are compatible with
each other (but not with those created with `backup_index()`).```{r timestamp}
# be default backup_date() only makes a backup if the last backups is younger
# than 1 day, so we set `age` to -1 for this example
backup_date(tf, age = -1)
backup_date(tf, format = "%Y-%m", age = -1)
backup_time(tf)
backup_time(tf, format = "%Y-%m-%d_%H-%M-%S") # Python logging
backup_time(tf, format = "%Y%m%dT%H%M%S") # ISO 8601 compatiblebackup_info(tf)
```
If we examine the "timestamp" column in the example above, we see that missing
date information is always interpreted as the start of the period; i.e. so
`"2019-01"` is equivalent to `"2019-01-01--00--00--00"` for all intents and
purposes.```{r}
prune_backups(tf, max_backups = 0) # cleanup
list_backups(tf)
```Besides passing a total number of backups to keep, `max_backups` can also be
a period or a date / datetime for timestamped backups.
```{r eval = FALSE}
# keep all backups younger than one year
prune_backups(tf, "1 year")
# keep all backups from April 4th, 2018 and onwards
prune_backups(tf, "2018-04-01")
``````{r cleanup, include = FALSE}
unlink(td, recursive = TRUE)
```## Cache
rotor also provides a simple on-disk key-value store that can be pruned by size,
age or number of files.
```{r}
cache <- Cache$new(file.path(tempdir(), "cache-test"), hashfun = digest::digest)
key1 <- cache$push(iris)
key2 <- cache$push(cars)
key3 <- cache$push(mtcars)cache$files$path
head(cache$read(key1))
cache$prune(max_files = 1)
cache$files$path
cache$purge() # deletes all cached files
cache$destroy() # deletes the cache directory
```# Dependencies
**rotor**'s dependencies are intentionally kept slim. It only comes with two
non-base dependencies:* [R6](https://github.com/r-lib/R6): A light weight system for
encapsulated object-oriented programming.
* [dint](https://github.com/s-fleck/dint): A toolkit for working year-quarter
and year-month dates that I am also the author of. It is used by
`rotate_date()` and `rotate_time()` to deal with calendar periods (such as
weeks or months).
Both packages have no transitive dependencies (i.e they do not depend on
anything outside of base R)Optional dependencies:
* [digest](https://github.com/eddelbuettel/digest),
[ulid](https://cran.r-project.org/package=ulid), or
[uuid](https://CRAN.R-project.org/package=uuid ) for generating
hashes or UIDs when using `Cache`. Storage keys for cache files can also be set
manually, in which case no external dependencies are required.
* [zip](https://CRAN.R-project.org/package=zip) is supported as an alternative
to the integrated zip function in R. Might work better on some systems and
worse on others.
* [crayon](https://cran.r-project.org/package=crayon) for
terminal colors