Skip to content

Merge Upstream #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 47 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
30d06fa
Use `0` as the initial log
kstrafe Jul 6, 2020
55c7436
Cargo fmt
archis-polyverse Nov 24, 2020
5ed34a6
Merge pull request #3 from polyverse/upstream-pr-branch
kstrafe Nov 24, 2020
d9e1158
Add license, fix grammar
kstrafe Dec 6, 2020
a23035e
Fix the arbitrary_bytes test
kstrafe Dec 6, 2020
b48f906
Extensible suffix behaviour (timestamp, count) through trait SuffixSc…
Ploppz Dec 13, 2021
23539fa
SuffixScheme implementations are lighter, more logic in FileRotate
Ploppz Aug 29, 2021
f34a416
test rotate_to_deleted_directory
Ploppz Aug 31, 2021
802bedd
Propagate IO errors
Ploppz Aug 31, 2021
54b3396
Compression
Ploppz Sep 1, 2021
213f6ac
Don't truncate log file in FileRotate::new
Ploppz Sep 1, 2021
85e4619
Remove patch number from flate2 dep
Ploppz Sep 2, 2021
f4e8413
Move tests to their own file
Ploppz Sep 2, 2021
21c1d89
Expose SuffixInfo and move scan_suffix fn into SuffixScheme
Ploppz Sep 2, 2021
c658133
Fix bug in scan_suffixes, that doesn't register the compressed filenames
Ploppz Sep 14, 2021
85eee2d
Make fields of TimestampSuffix public
Ploppz Dec 10, 2021
a0cad14
Bugfix: If log file already exists, update self.count to reflect its …
Ploppz Dec 13, 2021
b5ee443
Bump version number and publish
Ploppz Dec 15, 2021
a613020
Fixed bug where a log file's size was used as its line count
mmponn Dec 31, 2021
689812b
Bump version number
Ploppz Jan 6, 2022
c50940f
Improve documentation - add compression example
Ploppz Jan 12, 2022
2c9a264
More docs
Ploppz Jan 12, 2022
f82cd14
derive Debug for FileRotate
Ploppz Jan 17, 2022
340c4e5
Fix bug: scan_suffixes panicked if given path only has one component
Ploppz Jan 31, 2022
8e14ece
Fix bug in `scan_suffixes` (not fixed in previous commit)
Ploppz Feb 4, 2022
eeafc74
s/CountSuffix/AppendCount, s/TimestampSuffixScheme/AppendTimestamp
Ploppz Feb 4, 2022
cf713f7
add rotate by date
jb-alvarado May 5, 2022
8df55c6
Add possibility to specify UNIX file permissions
Apr 27, 2022
0416ad1
Create rust.yml for github actions
Ploppz May 13, 2022
be183d4
Fix compilation error on Windows
Ploppz May 14, 2022
c587c38
Update README examples
Ploppz May 14, 2022
4d60140
Fix one test that failed in Windows
Ploppz May 14, 2022
7b45ca1
Add support for manual log rotation.
runfalk Jun 15, 2022
81c006d
Fix AppendTimestamp::parse to work with any format
Ploppz May 12, 2022
30f0ecc
Update chrono from 0.4.20 rc to release
Ploppz Aug 8, 2022
ff27734
Add Limitations in README.md
Ploppz Aug 8, 2022
6340dae
Fix issue #20: panic due to subtraction overflow
Ploppz Oct 14, 2022
405f6d8
Bump version to 0.7.1
Ploppz Oct 14, 2022
5f904d8
Remove time dependency to fix CVE-2020-26235
rharish101 Jan 27, 2023
f9967d8
Bump version to 0.7.2
Ploppz Mar 1, 2023
1f02211
replace tempdir with tempfile
alexanderkjall Mar 9, 2023
f776977
Chrono dep no longer optional
Ploppz Mar 12, 2023
5b4f7d1
Bump to 0.7.3
Ploppz Mar 14, 2023
08b2a43
Move repository
kstrafe May 14, 2023
3acb684
Fix readme examples to include compression
kstrafe Jun 8, 2023
fc60342
Add FileLimit::Unlimited (implements #26)
Ploppz May 16, 2024
8ee371f
Issue 29: Consistent number of arguments across OSes
Ploppz Feb 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Rust

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

env:
CARGO_TERM_COLOR: always

jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Check
run: cargo check
test:
runs-on: '${{ matrix.os }}'
strategy:
matrix:
include:
- os: macos-latest
- os: ubuntu-latest
- os: windows-latest
steps:
- uses: actions/checkout@v3
- name: Test
run: cargo test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
Cargo.lock
logs/
target/
20 changes: 13 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
[package]
name = "file-rotate"
version = "0.2.0"
authors = ["Kevin Robert Stravers <macocio@gmail.com>"]
version = "0.8.0"
authors = ["Kevin Robert Stravers <[email protected]>", "Erlend Langseth <3rlendhl@gmail.com>"]
edition = "2018"
description = "Log rotation for files"
homepage = "https://github.com/BourgondAries/file-rotate"
repository = "https://github.com/BourgondAries/file-rotate"
homepage = "https://github.com/kstrafe/file-rotate"
repository = "https://github.com/kstrafe/file-rotate"
keywords= ["log", "rotate", "logrotate"]
license = "LGPL-3.0-or-later"
license = "MIT"

[dependencies]
chrono = { version = "0.4.20", default-features = false, features = ["clock"] }
flate2 = "1.0"

[dev-dependencies]
quickcheck = "0.9"
quickcheck_macros = "0.9"
filetime = "0.2"
quickcheck = "0.9.2"
quickcheck_macros = "0.9.1"
tempfile = "3"
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2020 BourgondAries

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
98 changes: 98 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# file-rotate

Rotate files with configurable suffix.

Look to the [docs](https://docs.rs/file-rotate/latest/file_rotate/index.html) for explanatory examples of all features, like:
* Using count or timestamp as suffix
* Age-based deletion of log files
* Optional compression
* Getting a list of log files

Limitations / known issues:
* `file-rotate` assumes that no other process or user moves files around in the logging directory, but we want to find a way to [support this](https://github.com/BourgondAries/file-rotate/issues/17)

Following are some supplementary examples to get started.

## Basic example

```rust
use file_rotate::{FileRotate, ContentLimit, compression::Compression, suffix::AppendCount};
use std::{fs, io::Write, path::PathBuf};

fn main() {
let mut log = FileRotate::new("logs/log", AppendCount::new(2), ContentLimit::Lines(3), Compression::None, None);

// Write a bunch of lines
writeln!(log, "Line 1: Hello World!");
for idx in 2..=10 {
writeln!(log, "Line {}", idx);
}
}
```

```
$ ls logs
log log.1 log.2

$ cat log.2 log.1 log
Line 4
Line 5
Line 6
Line 7
Line 8
Line 9
Line 10
```

## Example with timestamp suffixes

```rust
let mut log = FileRotate::new(
"logs/log",
AppendTimestamp::default(FileLimit::MaxFiles(3)),
ContentLimit::Lines(3),
Compression::None,
None,
);

// Write a bunch of lines
writeln!(log, "Line 1: Hello World!");
for idx in 2..=10 {
std::thread::sleep(std::time::Duration::from_millis(200));
writeln!(log, "Line {}", idx);
}
```

```
$ ls logs
log log.20210825T151133.1
log.20210825T151133 log.20210825T151134

$ cat logs/*
Line 10
Line 1: Hello World!
Line 2
Line 3
Line 4
Line 5
Line 6
Line 7
Line 8
Line 9
```

The timestamp format (including the extra trailing `.N`) works by default so that the lexical ordering of filenames equals the chronological ordering.
So it almost works perfectly with `cat logs/*`, except that `log` is smaller (lexically "older") than all the rest. This can of course be fixed with a more complex script to assemble the logs.


## License

This project is licensed under the [MIT license].

[MIT license]: https://github.com/BourgondAries/file-rotate/blob/master/LICENSE

### Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in file-rotate by you, shall be licensed as MIT, without any additional
terms or conditions.
23 changes: 23 additions & 0 deletions examples/rotate_by_date.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use file_rotate::{
compression::Compression,
suffix::{AppendTimestamp, DateFrom, FileLimit},
ContentLimit, FileRotate, TimeFrequency,
};
use std::io::Write;

fn main() {
let mut log = FileRotate::new(
"logs/log",
AppendTimestamp::with_format("%Y-%m-%d", FileLimit::MaxFiles(7), DateFrom::DateYesterday),
ContentLimit::Time(TimeFrequency::Daily),
Compression::None,
None,
);

// Write a bunch of lines
writeln!(log, "Line 1: Hello World!").expect("write log");
for idx in 2..=10 {
std::thread::sleep(std::time::Duration::from_millis(500));
writeln!(log, "Line {}", idx).expect("write log");
}
}
37 changes: 37 additions & 0 deletions src/compression.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//! Compression - configuration and implementation
use flate2::write::GzEncoder;
use std::{
fs::{self, File, OpenOptions},
io,
path::{Path, PathBuf},
};

/// Compression mode - when to compress files.
#[derive(Debug, Clone)]
pub enum Compression {
/// No compression
None,
/// Look for files to compress when rotating.
/// First argument: How many files to keep uncompressed (excluding the original file)
OnRotate(usize),
}

pub(crate) fn compress(path: &Path) -> io::Result<()> {
let dest_path = PathBuf::from(format!("{}.gz", path.display()));

let mut src_file = File::open(path)?;
let dest_file = OpenOptions::new()
.write(true)
.create(true)
.append(false)
.open(&dest_path)?;

assert!(path.exists());
assert!(dest_path.exists());
let mut encoder = GzEncoder::new(dest_file, flate2::Compression::default());
io::copy(&mut src_file, &mut encoder)?;

fs::remove_file(path)?;

Ok(())
}
Loading