From 53398da58b8802d64994ff97f3818c75b66357a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Wed, 15 Dec 2021 15:58:49 +0100
Subject: [PATCH 01/22] Implement compression
---
tracing-appender/Cargo.toml | 1 +
tracing-appender/src/inner.rs | 36 +++++++++++++-----
tracing-appender/src/lib.rs | 2 +
tracing-appender/src/rolling.rs | 66 ++++++++++++++++++++++-----------
tracing-appender/src/writer.rs | 18 +++++++++
5 files changed, 91 insertions(+), 32 deletions(-)
create mode 100644 tracing-appender/src/writer.rs
diff --git a/tracing-appender/Cargo.toml b/tracing-appender/Cargo.toml
index 1023fc412b..9a48724c56 100644
--- a/tracing-appender/Cargo.toml
+++ b/tracing-appender/Cargo.toml
@@ -23,6 +23,7 @@ rust-version = "1.51.0"
[dependencies]
crossbeam-channel = "0.5.0"
time = { version = "0.3", default-features = false, features = ["formatting"] }
+flate2 = { version = "1.0.22" }
[dependencies.tracing-subscriber]
path = "../tracing-subscriber"
diff --git a/tracing-appender/src/inner.rs b/tracing-appender/src/inner.rs
index 1c40eeaae8..43fbc74ce9 100644
--- a/tracing-appender/src/inner.rs
+++ b/tracing-appender/src/inner.rs
@@ -6,14 +6,18 @@ use std::fmt::Debug;
use std::fs::{File, OpenOptions};
use std::path::Path;
use time::OffsetDateTime;
+use flate2::Compression;
+use flate2::write::GzEncoder;
+use crate::writer::WriterChannel;
#[derive(Debug)]
pub(crate) struct InnerAppender {
log_directory: String,
log_filename_prefix: String,
- writer: BufWriter,
+ writer: WriterChannel,
next_date: Option,
rotation: Rotation,
+ compress: bool
}
impl io::Write for InnerAppender {
@@ -23,7 +27,7 @@ impl io::Write for InnerAppender {
}
fn flush(&mut self) -> io::Result<()> {
- self.writer.flush()
+ self.writer.get_writer().flush()
}
}
@@ -32,12 +36,14 @@ impl InnerAppender {
log_directory: &Path,
log_filename_prefix: &Path,
rotation: Rotation,
- now: OffsetDateTime,
+ now: OffsetDateTime
) -> io::Result {
let log_directory = log_directory.to_str().unwrap();
- let log_filename_prefix = log_filename_prefix.to_str().unwrap();
- let filename = rotation.join_date(log_filename_prefix, &now);
+ let compress = log_filename_prefix.to_str().unwrap().ends_with(".gz");
+ let log_filename_prefix = log_filename_prefix.to_str().unwrap().trim_end_matches(".gz");
+
+ let filename = rotation.join_date(log_filename_prefix, &now, compress);
let next_date = rotation.next_date(&now);
Ok(InnerAppender {
@@ -46,6 +52,7 @@ impl InnerAppender {
writer: create_writer(log_directory, &filename)?,
next_date,
rotation,
+ compress
})
}
@@ -54,18 +61,19 @@ impl InnerAppender {
// and proceed with the write.
let buf_len = buf.len();
self.refresh_writer(date);
- self.writer.write_all(buf).map(|_| buf_len)
+ self.writer.get_writer().write_all(buf).map(|_| buf_len)
}
fn refresh_writer(&mut self, now: OffsetDateTime) {
if self.should_rollover(now) {
- let filename = self.rotation.join_date(&self.log_filename_prefix, &now);
+ let filename = self.rotation.join_date(
+ &self.log_filename_prefix, &now, self.compress);
self.next_date = self.rotation.next_date(&now);
match create_writer(&self.log_directory, &filename) {
Ok(writer) => {
- if let Err(err) = self.writer.flush() {
+ if let Err(err) = self.writer.get_writer().flush() {
eprintln!("Couldn't flush previous writer: {}", err);
}
self.writer = writer
@@ -84,9 +92,17 @@ impl InnerAppender {
}
}
-fn create_writer(directory: &str, filename: &str) -> io::Result> {
+fn create_writer(directory: &str, filename: &str) -> io::Result {
let file_path = Path::new(directory).join(filename);
- Ok(BufWriter::new(open_file_create_parent_dirs(&file_path)?))
+ let file = open_file_create_parent_dirs(&file_path)?;
+ if filename.ends_with(".gz") {
+ let buf = BufWriter::new(file);
+ let gzfile = GzEncoder::new(buf, Compression::default());
+ let writer = BufWriter::new(gzfile);
+ Ok(WriterChannel::CompressedFileGzip(writer))
+ } else {
+ Ok(WriterChannel::File(BufWriter::new(file)))
+ }
}
fn open_file_create_parent_dirs(path: &Path) -> io::Result {
diff --git a/tracing-appender/src/lib.rs b/tracing-appender/src/lib.rs
index 536c894a7b..25b349d9eb 100644
--- a/tracing-appender/src/lib.rs
+++ b/tracing-appender/src/lib.rs
@@ -161,6 +161,8 @@ pub mod rolling;
mod worker;
+mod writer;
+
/// Convenience function for creating a non-blocking, off-thread writer.
///
/// See the [`non_blocking` module's docs][mod@non_blocking]'s for more details.
diff --git a/tracing-appender/src/rolling.rs b/tracing-appender/src/rolling.rs
index b38afbb740..4afa9099dc 100644
--- a/tracing-appender/src/rolling.rs
+++ b/tracing-appender/src/rolling.rs
@@ -86,7 +86,7 @@ impl RollingFileAppender {
directory.as_ref(),
file_name_prefix.as_ref(),
rotation,
- OffsetDateTime::now_utc(),
+ OffsetDateTime::now_utc()
)
.expect("Failed to create appender"),
}
@@ -283,7 +283,7 @@ enum RotationKind {
Minutely,
Hourly,
Daily,
- Never,
+ Never
}
impl Rotation {
@@ -331,7 +331,7 @@ impl Rotation {
}
}
- pub(crate) fn join_date(&self, filename: &str, date: &OffsetDateTime) -> String {
+ pub(crate) fn join_date(&self, filename: &str, date: &OffsetDateTime, compress: bool) -> String {
match *self {
Rotation::MINUTELY => {
let format = format_description::parse("[year]-[month]-[day]-[hour]-[minute]")
@@ -340,7 +340,7 @@ impl Rotation {
let date = date
.format(&format)
.expect("Unable to format OffsetDateTime; this is a bug in tracing-appender");
- format!("{}.{}", filename, date)
+ Rotation::format_params(filename, compress, date)
}
Rotation::HOURLY => {
let format = format_description::parse("[year]-[month]-[day]-[hour]")
@@ -349,7 +349,7 @@ impl Rotation {
let date = date
.format(&format)
.expect("Unable to format OffsetDateTime; this is a bug in tracing-appender");
- format!("{}.{}", filename, date)
+ Rotation::format_params(filename, compress, date)
}
Rotation::DAILY => {
let format = format_description::parse("[year]-[month]-[day]")
@@ -357,9 +357,21 @@ impl Rotation {
let date = date
.format(&format)
.expect("Unable to format OffsetDateTime; this is a bug in tracing-appender");
- format!("{}.{}", filename, date)
+ Rotation::format_params(filename, compress, date)
}
- Rotation::NEVER => filename.to_string(),
+ Rotation::NEVER => if compress {
+ format!("{}.gz", filename.to_string())
+ } else {
+ filename.to_string()
+ },
+ }
+ }
+
+ fn format_params(filename: &str, compress: bool, date: String) -> String {
+ if compress {
+ format!("{}.{}.gz", filename, date)
+ } else {
+ format!("{}.{}", filename, date)
}
}
}
@@ -392,7 +404,7 @@ mod test {
appender.flush().expect("Failed to flush!");
}
- fn test_appender(rotation: Rotation, file_prefix: &str) {
+ fn test_appender(rotation: Rotation, file_prefix: &str, compress: bool) {
let directory = tempfile::tempdir().expect("failed to create tempdir");
let mut appender = RollingFileAppender::new(rotation, directory.path(), file_prefix);
@@ -407,23 +419,17 @@ mod test {
#[test]
fn write_minutely_log() {
- test_appender(Rotation::HOURLY, "minutely.log");
+ test_appender(Rotation::HOURLY, "minutely.log", false);
}
#[test]
- fn write_hourly_log() {
- test_appender(Rotation::HOURLY, "hourly.log");
- }
+ fn write_hourly_log() { test_appender(Rotation::HOURLY, "hourly.log", false); }
#[test]
- fn write_daily_log() {
- test_appender(Rotation::DAILY, "daily.log");
- }
+ fn write_daily_log() { test_appender(Rotation::DAILY, "daily.log", false); }
#[test]
- fn write_never_log() {
- test_appender(Rotation::NEVER, "never.log");
- }
+ fn write_never_log() { test_appender(Rotation::NEVER, "never.log", false); }
#[test]
fn test_rotations() {
@@ -468,19 +474,35 @@ mod test {
let now = OffsetDateTime::parse("2020-02-01 10:01:00 +00:00:00", &format).unwrap();
// per-minute
- let path = Rotation::MINUTELY.join_date("app.log", &now);
+ let path = Rotation::MINUTELY.join_date("app.log", &now, false);
assert_eq!("app.log.2020-02-01-10-01", path);
// per-hour
- let path = Rotation::HOURLY.join_date("app.log", &now);
+ let path = Rotation::HOURLY.join_date("app.log", &now, false);
assert_eq!("app.log.2020-02-01-10", path);
// per-day
- let path = Rotation::DAILY.join_date("app.log", &now);
+ let path = Rotation::DAILY.join_date("app.log", &now, false);
assert_eq!("app.log.2020-02-01", path);
// never
- let path = Rotation::NEVER.join_date("app.log", &now);
+ let path = Rotation::NEVER.join_date("app.log", &now, false);
assert_eq!("app.log", path);
+
+ // per-minute compressed
+ let path = Rotation::MINUTELY.join_date("app.log", &now, true);
+ assert_eq!("app.log.2020-02-01-10-01.gz", path);
+
+ // per-hour compressed
+ let path = Rotation::HOURLY.join_date("app.log", &now, true);
+ assert_eq!("app.log.2020-02-01-10.gz", path);
+
+ // per-day compressed
+ let path = Rotation::DAILY.join_date("app.log", &now, true);
+ assert_eq!("app.log.2020-02-01.gz", path);
+
+ // never compressed
+ let path = Rotation::NEVER.join_date("app.log", &now, true);
+ assert_eq!("app.log.gz", path)
}
}
diff --git a/tracing-appender/src/writer.rs b/tracing-appender/src/writer.rs
new file mode 100644
index 0000000000..6da5bdd0d9
--- /dev/null
+++ b/tracing-appender/src/writer.rs
@@ -0,0 +1,18 @@
+use std::io::{BufWriter, Write};
+use std::fs::File;
+use flate2::write::GzEncoder;
+
+#[derive(Debug)]
+pub enum WriterChannel {
+ File(BufWriter),
+ CompressedFileGzip(BufWriter>>),
+}
+
+impl WriterChannel {
+ pub fn get_writer(&mut self) -> &mut dyn Write {
+ match self {
+ WriterChannel::File(x) => x,
+ WriterChannel::CompressedFileGzip(x) => x,
+ }
+ }
+}
\ No newline at end of file
From 992982627ff4df12e494f48f20ba56bd2e1502fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Wed, 15 Dec 2021 16:06:50 +0100
Subject: [PATCH 02/22] Format
---
tracing-appender/src/rolling.rs | 4 ++--
tracing-appender/src/writer.rs | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/tracing-appender/src/rolling.rs b/tracing-appender/src/rolling.rs
index 4afa9099dc..c86ccdd0f1 100644
--- a/tracing-appender/src/rolling.rs
+++ b/tracing-appender/src/rolling.rs
@@ -86,7 +86,7 @@ impl RollingFileAppender {
directory.as_ref(),
file_name_prefix.as_ref(),
rotation,
- OffsetDateTime::now_utc()
+ OffsetDateTime::now_utc(),
)
.expect("Failed to create appender"),
}
@@ -283,7 +283,7 @@ enum RotationKind {
Minutely,
Hourly,
Daily,
- Never
+ Never,
}
impl Rotation {
diff --git a/tracing-appender/src/writer.rs b/tracing-appender/src/writer.rs
index 6da5bdd0d9..170c8c6f36 100644
--- a/tracing-appender/src/writer.rs
+++ b/tracing-appender/src/writer.rs
@@ -15,4 +15,4 @@ impl WriterChannel {
WriterChannel::CompressedFileGzip(x) => x,
}
}
-}
\ No newline at end of file
+}
From ef1bb1007a3a38c88d4d2804d79e99d1557bc70f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Thu, 23 Dec 2021 12:10:00 +0100
Subject: [PATCH 03/22] Compiles after implementing io::Write for
&WriterChannel
---
tracing-appender/Cargo.toml | 5 ++++-
tracing-appender/src/builder.rs | 10 ++++++----
tracing-appender/src/rolling.rs | 17 +++++++++--------
tracing-appender/src/writer.rs | 32 ++++++++++++++++++++++++++------
4 files changed, 45 insertions(+), 19 deletions(-)
diff --git a/tracing-appender/Cargo.toml b/tracing-appender/Cargo.toml
index fcf9273724..6b28260e28 100644
--- a/tracing-appender/Cargo.toml
+++ b/tracing-appender/Cargo.toml
@@ -23,7 +23,7 @@ rust-version = "1.51.0"
[dependencies]
crossbeam-channel = "0.5.0"
time = { version = "0.3", default-features = false, features = ["formatting"] }
-flate2 = { version = "1.0.22" }
+flate2 = { optional = true, version = "1.0.22" }
parking_lot = { optional = true, version = "0.11.2" }
[dependencies.tracing-subscriber]
@@ -36,3 +36,6 @@ features = ["fmt", "std"]
tracing = { path = "../tracing", version = "0.2" }
time = { version = "0.3", default-features = false, features = ["formatting", "parsing"] }
tempfile = "3"
+
+[features]
+compression = ["flate2"]
diff --git a/tracing-appender/src/builder.rs b/tracing-appender/src/builder.rs
index b05959352d..336769bce1 100644
--- a/tracing-appender/src/builder.rs
+++ b/tracing-appender/src/builder.rs
@@ -1,5 +1,3 @@
-use std::io;
-use std::path::Path;
use std::sync::atomic::AtomicUsize;
use time::OffsetDateTime;
use crate::rolling::{create_writer_file, Inner, RollingFileAppender, Rotation};
@@ -25,7 +23,9 @@ impl RollingFileAppenderBuilder {
log_directory: None,
log_filename_prefix: None,
rotation: None,
- next_date: None
+ next_date: None,
+ #[cfg(feature = "compression")]
+ compression: None
}
}
@@ -78,7 +78,9 @@ impl RollingFileAppenderBuilder {
log_directory,
log_filename_prefix,
next_date,
- rotation
+ rotation,
+ #[cfg(feature = "compression")]
+ compression: self.compression
},
writer,
}
diff --git a/tracing-appender/src/rolling.rs b/tracing-appender/src/rolling.rs
index c401550756..a9e3da0769 100644
--- a/tracing-appender/src/rolling.rs
+++ b/tracing-appender/src/rolling.rs
@@ -34,9 +34,10 @@ use std::{
path::Path,
sync::atomic::{AtomicUsize, Ordering},
};
-use std::borrow::BorrowMut;
use time::{format_description, Duration, OffsetDateTime, Time};
use crate::builder::RollingFileAppenderBuilder;
+#[cfg(feature = "compression")]
+use crate::compression::CompressionConfig;
use crate::writer::WriterChannel;
/// A file appender with the ability to rotate log files at a fixed schedule.
@@ -156,11 +157,11 @@ impl io::Write for RollingFileAppender {
debug_assert!(_did_cas, "if we have &mut access to the appender, no other thread can have advanced the timestamp...");
self.state.refresh_writer(now, writer);
}
- writer.get_writer().write(buf)
+ writer.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
- self.writer.get_mut().get_writer().flush()
+ self.writer.get_mut().flush()
}
}
@@ -458,11 +459,11 @@ impl Rotation {
impl io::Write for RollingWriter<'_> {
fn write(&mut self, buf: &[u8]) -> io::Result {
- (&*self.0).get_writer().write(buf)
+ (&*self.0).write(buf)
}
fn flush(&mut self) -> io::Result<()> {
- (&*self.0).get_writer().flush()
+ (&*self.0).flush()
}
}
@@ -506,11 +507,11 @@ impl Inner {
fn refresh_writer_channel(file: &mut WriterChannel, writer: io::Result) {
match writer {
- Ok(new_file) => {
- if let Err(err) = file.get_writer().flush() {
+ Ok(new_writer) => {
+ if let Err(err) = file.flush() {
eprintln!("Couldn't flush previous writer: {}", err);
}
- *file = new_file;
+ *file = new_writer;
}
Err(err) => eprintln!("Couldn't create writer for logs: {}", err),
}
diff --git a/tracing-appender/src/writer.rs b/tracing-appender/src/writer.rs
index cc7e286082..644a6d5e99 100644
--- a/tracing-appender/src/writer.rs
+++ b/tracing-appender/src/writer.rs
@@ -8,6 +8,8 @@ use crate::sync::RwLock;
use crate::rolling::create_writer_file;
#[cfg(feature = "compression")]
use flate2::write::GzEncoder;
+#[cfg(feature = "compression")]
+use crate::compression::CompressionConfig;
#[derive(Debug)]
pub enum WriterChannel {
@@ -51,22 +53,40 @@ impl WriterChannel {
let writer = BufWriter::new(gzfile);
Ok(WriterChannel::CompressedFileGzip(writer))
}
+}
- pub fn get_writer(&mut self) -> &mut dyn Write {
+impl io::Write for WriterChannel {
+ fn write(&mut self, buf: &[u8]) -> io::Result {
match self {
- WriterChannel::File(x) => x,
+ WriterChannel::File(f) => f.write(buf),
#[cfg(feature = "compression")]
- WriterChannel::CompressedFileGzip(x) => x,
+ WriterChannel::CompressedFileGzip(buf) => f.write(buf)
+ }
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ match self {
+ WriterChannel::File(f) => f.flush(),
+ #[cfg(feature = "compression")]
+ WriterChannel::CompressedFileGzip(buf) => buf.flush()
}
}
}
-impl io::Write for WriterChannel {
+impl io::Write for &WriterChannel {
fn write(&mut self, buf: &[u8]) -> io::Result {
- self.borrow_mut().write(buf)
+ match self {
+ WriterChannel::File(f) => (&*f).write(buf),
+ #[cfg(feature = "compression")]
+ WriterChannel::CompressedFileGzip(buf) => f.write(buf)
+ }
}
fn flush(&mut self) -> io::Result<()> {
- self.borrow_mut().flush()
+ match self {
+ WriterChannel::File(f) => (&*f).flush(),
+ #[cfg(feature = "compression")]
+ WriterChannel::CompressedFileGzip(buf) => buf.flush()
+ }
}
}
From 759327788369aaa20da373249cc762c270283d07 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Thu, 23 Dec 2021 12:36:35 +0100
Subject: [PATCH 04/22] Add shortcuts for compression options
---
tracing-appender/src/compression.rs | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/tracing-appender/src/compression.rs b/tracing-appender/src/compression.rs
index fc4be9cf80..5857c45982 100644
--- a/tracing-appender/src/compression.rs
+++ b/tracing-appender/src/compression.rs
@@ -59,4 +59,21 @@ pub struct GzipCompression {
/// Data structure to pass compression parameters
pub enum CompressionConfig {
Gzip(GzipCompression)
-}
\ No newline at end of file
+}
+
+mod compression_options {
+ use super::*;
+ pub const GZIP_NONE: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Literal(GzipCompressionLevelLiteral::None) });
+ pub const GZIP_FAST: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Literal(GzipCompressionLevelLiteral::Fast) });
+ pub const GZIP_BEST: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Literal(GzipCompressionLevelLiteral::Best) });
+ pub const GZIP_0: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level0) });
+ pub const GZIP_1: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level1) });
+ pub const GZIP_2: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level2) });
+ pub const GZIP_3: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level3) });
+ pub const GZIP_4: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level4) });
+ pub const GZIP_5: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level5) });
+ pub const GZIP_6: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level6) });
+ pub const GZIP_7: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level7) });
+ pub const GZIP_8: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level8) });
+ pub const GZIP_9: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level9) });
+}
From 74d36558565cdfe88ebc34e8fe94702d99fb2aa9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Fri, 24 Dec 2021 00:46:26 +0100
Subject: [PATCH 05/22] Fix formatting
---
tracing-appender/src/builder.rs | 31 ++++++----
tracing-appender/src/compression.rs | 96 ++++++++++++++++++-----------
tracing-appender/src/rolling.rs | 76 +++++++++++++----------
tracing-appender/src/writer.rs | 45 +++++++-------
4 files changed, 144 insertions(+), 104 deletions(-)
diff --git a/tracing-appender/src/builder.rs b/tracing-appender/src/builder.rs
index 336769bce1..c9708370fc 100644
--- a/tracing-appender/src/builder.rs
+++ b/tracing-appender/src/builder.rs
@@ -1,9 +1,9 @@
-use std::sync::atomic::AtomicUsize;
-use time::OffsetDateTime;
use crate::rolling::{create_writer_file, Inner, RollingFileAppender, Rotation};
use crate::sync::RwLock;
+use std::sync::atomic::AtomicUsize;
+use time::OffsetDateTime;
-#[cfg(feature="compression")]
+#[cfg(feature = "compression")]
use crate::compression::CompressionConfig;
use crate::writer::WriterChannel;
@@ -14,7 +14,7 @@ pub struct RollingFileAppenderBuilder {
rotation: Option,
next_date: Option,
#[cfg(feature = "compression")]
- compression: Option
+ compression: Option,
}
impl RollingFileAppenderBuilder {
@@ -25,7 +25,7 @@ impl RollingFileAppenderBuilder {
rotation: None,
next_date: None,
#[cfg(feature = "compression")]
- compression: None
+ compression: None,
}
}
@@ -57,15 +57,22 @@ impl RollingFileAppenderBuilder {
pub fn build(self) -> RollingFileAppender {
let now = OffsetDateTime::now_utc();
- let log_directory = self.log_directory.expect("log_directory is required to build RollingFileAppender");
- let log_filename_prefix = self.log_filename_prefix.expect("log_filename_prefix is required to build RollingFileAppender");
- let rotation = self.rotation.expect("rotation is required to build RollingFileAppender");
+ let log_directory = self
+ .log_directory
+ .expect("log_directory is required to build RollingFileAppender");
+ let log_filename_prefix = self
+ .log_filename_prefix
+ .expect("log_filename_prefix is required to build RollingFileAppender");
+ let rotation = self
+ .rotation
+ .expect("rotation is required to build RollingFileAppender");
let filename = rotation.join_date(log_filename_prefix.as_str(), &now, false);
let next_date = rotation.next_date(&now);
- let writer = RwLock::new(
- WriterChannel::File(create_writer_file(log_directory.as_str(), &filename).expect("failed to create appender"))
- );
+ let writer = RwLock::new(WriterChannel::File(
+ create_writer_file(log_directory.as_str(), &filename)
+ .expect("failed to create appender"),
+ ));
let next_date = AtomicUsize::new(
next_date
@@ -80,7 +87,7 @@ impl RollingFileAppenderBuilder {
next_date,
rotation,
#[cfg(feature = "compression")]
- compression: self.compression
+ compression: self.compression,
},
writer,
}
diff --git a/tracing-appender/src/compression.rs b/tracing-appender/src/compression.rs
index 5857c45982..c4c6888aaf 100644
--- a/tracing-appender/src/compression.rs
+++ b/tracing-appender/src/compression.rs
@@ -16,64 +16,86 @@ pub enum GzipCompressionLevelNumerical {
Level6,
Level7,
Level8,
- Level9
+ Level9,
}
pub enum GzipCompressionLevel {
Literal(GzipCompressionLevelLiteral),
- Numerical(GzipCompressionLevelNumerical)
+ Numerical(GzipCompressionLevelNumerical),
}
impl Into for GzipCompressionLevel {
fn into(self) -> Compression {
match GzipCompressionLevel {
- GzipCompressionLevel::Literal(lit) => {
- match lit {
- GzipCompressionLevelLiteral::None => Compression::none(),
- GzipCompressionLevelLiteral::Fast => Compression::fast(),
- GzipCompressionLevelLiteral::Best => Compression::best()
- }
+ GzipCompressionLevel::Literal(lit) => match lit {
+ GzipCompressionLevelLiteral::None => Compression::none(),
+ GzipCompressionLevelLiteral::Fast => Compression::fast(),
+ GzipCompressionLevelLiteral::Best => Compression::best(),
+ },
+ GzipCompressionLevel::Numerical(num) => match num {
+ GzipCompressionLevelNumerical::Level0 => Compression(0),
+ GzipCompressionLevelNumerical::Level1 => Compression(1),
+ GzipCompressionLevelNumerical::Level2 => Compression(2),
+ GzipCompressionLevelNumerical::Level3 => Compression(3),
+ GzipCompressionLevelNumerical::Level4 => Compression(4),
+ GzipCompressionLevelNumerical::Level5 => Compression(5),
+ GzipCompressionLevelNumerical::Level6 => Compression(6),
+ GzipCompressionLevelNumerical::Level7 => Compression(7),
+ GzipCompressionLevelNumerical::Level8 => Compression(8),
+ GzipCompressionLevelNumerical::Level9 => Compression(9),
},
- GzipCompressionLevel::Numerical(num) => {
- match num {
- GzipCompressionLevelNumerical::Level0 => Compression(0),
- GzipCompressionLevelNumerical::Level1 => Compression(1),
- GzipCompressionLevelNumerical::Level2 => Compression(2),
- GzipCompressionLevelNumerical::Level3 => Compression(3),
- GzipCompressionLevelNumerical::Level4 => Compression(4),
- GzipCompressionLevelNumerical::Level5 => Compression(5),
- GzipCompressionLevelNumerical::Level6 => Compression(6),
- GzipCompressionLevelNumerical::Level7 => Compression(7),
- GzipCompressionLevelNumerical::Level8 => Compression(8),
- GzipCompressionLevelNumerical::Level9 => Compression(9)
- }
- }
}
}
}
pub struct GzipCompression {
- pub level: GzipCompressionLevel
+ pub level: GzipCompressionLevel,
}
/// Data structure to pass compression parameters
pub enum CompressionConfig {
- Gzip(GzipCompression)
+ Gzip(GzipCompression),
}
mod compression_options {
use super::*;
- pub const GZIP_NONE: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Literal(GzipCompressionLevelLiteral::None) });
- pub const GZIP_FAST: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Literal(GzipCompressionLevelLiteral::Fast) });
- pub const GZIP_BEST: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Literal(GzipCompressionLevelLiteral::Best) });
- pub const GZIP_0: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level0) });
- pub const GZIP_1: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level1) });
- pub const GZIP_2: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level2) });
- pub const GZIP_3: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level3) });
- pub const GZIP_4: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level4) });
- pub const GZIP_5: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level5) });
- pub const GZIP_6: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level6) });
- pub const GZIP_7: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level7) });
- pub const GZIP_8: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level8) });
- pub const GZIP_9: CompressionConfig = CompressionConfig::Gzip(GzipCompression { level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level9) });
+ pub const GZIP_NONE: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Literal(GzipCompressionLevelLiteral::None),
+ });
+ pub const GZIP_FAST: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Literal(GzipCompressionLevelLiteral::Fast),
+ });
+ pub const GZIP_BEST: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Literal(GzipCompressionLevelLiteral::Best),
+ });
+ pub const GZIP_0: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level0),
+ });
+ pub const GZIP_1: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level1),
+ });
+ pub const GZIP_2: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level2),
+ });
+ pub const GZIP_3: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level3),
+ });
+ pub const GZIP_4: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level4),
+ });
+ pub const GZIP_5: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level5),
+ });
+ pub const GZIP_6: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level6),
+ });
+ pub const GZIP_7: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level7),
+ });
+ pub const GZIP_8: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level8),
+ });
+ pub const GZIP_9: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level9),
+ });
}
diff --git a/tracing-appender/src/rolling.rs b/tracing-appender/src/rolling.rs
index a9e3da0769..ab863ec441 100644
--- a/tracing-appender/src/rolling.rs
+++ b/tracing-appender/src/rolling.rs
@@ -26,7 +26,11 @@
//! let file_appender = RollingFileAppender::new(Rotation::HOURLY, "/some/directory", "prefix.log");
//! # }
//! ```
+use crate::builder::RollingFileAppenderBuilder;
+#[cfg(feature = "compression")]
+use crate::compression::CompressionConfig;
use crate::sync::{RwLock, RwLockReadGuard};
+use crate::writer::WriterChannel;
use std::{
fmt::Debug,
fs::{self, File, OpenOptions},
@@ -35,10 +39,6 @@ use std::{
sync::atomic::{AtomicUsize, Ordering},
};
use time::{format_description, Duration, OffsetDateTime, Time};
-use crate::builder::RollingFileAppenderBuilder;
-#[cfg(feature = "compression")]
-use crate::compression::CompressionConfig;
-use crate::writer::WriterChannel;
/// A file appender with the ability to rotate log files at a fixed schedule.
///
@@ -106,7 +106,7 @@ pub(crate) struct Inner {
pub(crate) rotation: Rotation,
pub(crate) next_date: AtomicUsize,
#[cfg(feature = "compression")]
- pub(crate) compression: Option
+ pub(crate) compression: Option,
}
// === impl RollingFileAppender ===
@@ -410,7 +410,12 @@ impl Rotation {
}
}
- pub(crate) fn join_date(&self, filename: &str, date: &OffsetDateTime, compress: bool) -> String {
+ pub(crate) fn join_date(
+ &self,
+ filename: &str,
+ date: &OffsetDateTime,
+ compress: bool,
+ ) -> String {
match *self {
Rotation::MINUTELY => {
let format = format_description::parse("[year]-[month]-[day]-[hour]-[minute]")
@@ -438,11 +443,13 @@ impl Rotation {
.expect("Unable to format OffsetDateTime; this is a bug in tracing-appender");
Rotation::format_params(filename, compress, date)
}
- Rotation::NEVER => if compress {
- format!("{}.gz", filename.to_string())
- } else {
- filename.to_string()
- },
+ Rotation::NEVER => {
+ if compress {
+ format!("{}.gz", filename.to_string())
+ } else {
+ filename.to_string()
+ }
+ }
}
}
@@ -470,37 +477,34 @@ impl io::Write for RollingWriter<'_> {
// === impl Inner ===
impl Inner {
-
#[cfg(feature = "compression")]
- fn refresh_writer(&self,
- now: OffsetDateTime,
- file: &mut WriterChannel,
- compression: CompressionConfig) {
+ fn refresh_writer(
+ &self,
+ now: OffsetDateTime,
+ file: &mut WriterChannel,
+ compression: CompressionConfig,
+ ) {
debug_assert!(self.should_rollover(now));
- let filename = self.rotation.join_date(&self.log_filename_prefix, &now, false);
+ let filename = self
+ .rotation
+ .join_date(&self.log_filename_prefix, &now, false);
- let writer = WriterChannel::new_with_compression(
- &self.log_directory,
- &filename,
- compression
- );
+ let writer =
+ WriterChannel::new_with_compression(&self.log_directory, &filename, compression);
Self::refresh_writer_channel(file, writer);
}
#[cfg(not(feature = "compression"))]
- fn refresh_writer(&self,
- now: OffsetDateTime,
- file: &mut WriterChannel) {
+ fn refresh_writer(&self, now: OffsetDateTime, file: &mut WriterChannel) {
debug_assert!(self.should_rollover(now));
- let filename = self.rotation.join_date(&self.log_filename_prefix, &now, false);
+ let filename = self
+ .rotation
+ .join_date(&self.log_filename_prefix, &now, false);
- let writer = WriterChannel::new_without_compression(
- &self.log_directory,
- &filename,
- );
+ let writer = WriterChannel::new_without_compression(&self.log_directory, &filename);
Self::refresh_writer_channel(file, writer)
}
@@ -606,13 +610,19 @@ mod test {
}
#[test]
- fn write_hourly_log() { test_appender(Rotation::HOURLY, "hourly.log", false); }
+ fn write_hourly_log() {
+ test_appender(Rotation::HOURLY, "hourly.log", false);
+ }
#[test]
- fn write_daily_log() { test_appender(Rotation::DAILY, "daily.log", false); }
+ fn write_daily_log() {
+ test_appender(Rotation::DAILY, "daily.log", false);
+ }
#[test]
- fn write_never_log() { test_appender(Rotation::NEVER, "never.log", false); }
+ fn write_never_log() {
+ test_appender(Rotation::NEVER, "never.log", false);
+ }
#[test]
fn test_rotations() {
diff --git a/tracing-appender/src/writer.rs b/tracing-appender/src/writer.rs
index 644a6d5e99..96ba291385 100644
--- a/tracing-appender/src/writer.rs
+++ b/tracing-appender/src/writer.rs
@@ -1,15 +1,15 @@
-use std::{fs, io};
+#[cfg(feature = "compression")]
+use crate::compression::CompressionConfig;
+use crate::rolling::create_writer_file;
+use crate::sync::RwLock;
+#[cfg(feature = "compression")]
+use flate2::write::GzEncoder;
use std::borrow::BorrowMut;
-use std::io::{BufWriter, Write};
use std::fs::{File, OpenOptions};
+use std::io::{BufWriter, Write};
use std::ops::{Deref, DerefMut};
use std::path::Path;
-use crate::sync::RwLock;
-use crate::rolling::create_writer_file;
-#[cfg(feature = "compression")]
-use flate2::write::GzEncoder;
-#[cfg(feature = "compression")]
-use crate::compression::CompressionConfig;
+use std::{fs, io};
#[derive(Debug)]
pub enum WriterChannel {
@@ -20,11 +20,11 @@ pub enum WriterChannel {
impl WriterChannel {
#[cfg(feature = "compression")]
- pub fn new(directory: &str,
- filename: &str,
- #[cfg(feature = "compression")]
- compression: CompressionConfig) -> io::Result {
-
+ pub fn new(
+ directory: &str,
+ filename: &str,
+ #[cfg(feature = "compression")] compression: CompressionConfig,
+ ) -> io::Result {
if let Some(compression) = compression {
Self::new_with_compression(directory, filename, compression)
} else {
@@ -33,8 +33,7 @@ impl WriterChannel {
}
#[cfg(not(feature = "compression"))]
- pub fn new(directory: &str,
- filename: &str) -> io::Result {
+ pub fn new(directory: &str, filename: &str) -> io::Result {
Self::new_without_compression(directory, filename)
}
@@ -44,9 +43,11 @@ impl WriterChannel {
}
#[cfg(feature = "compression")]
- pub fn new_with_compression(directory: &str,
- filename: &str,
- compression: CompressionConfig) -> io::Result {
+ pub fn new_with_compression(
+ directory: &str,
+ filename: &str,
+ compression: CompressionConfig,
+ ) -> io::Result {
let file = create_writer_file(directory, filename)?;
let buf = BufWriter::new(file);
let gzfile = GzEncoder::new(buf, compression.into());
@@ -60,7 +61,7 @@ impl io::Write for WriterChannel {
match self {
WriterChannel::File(f) => f.write(buf),
#[cfg(feature = "compression")]
- WriterChannel::CompressedFileGzip(buf) => f.write(buf)
+ WriterChannel::CompressedFileGzip(buf) => f.write(buf),
}
}
@@ -68,7 +69,7 @@ impl io::Write for WriterChannel {
match self {
WriterChannel::File(f) => f.flush(),
#[cfg(feature = "compression")]
- WriterChannel::CompressedFileGzip(buf) => buf.flush()
+ WriterChannel::CompressedFileGzip(buf) => buf.flush(),
}
}
}
@@ -78,7 +79,7 @@ impl io::Write for &WriterChannel {
match self {
WriterChannel::File(f) => (&*f).write(buf),
#[cfg(feature = "compression")]
- WriterChannel::CompressedFileGzip(buf) => f.write(buf)
+ WriterChannel::CompressedFileGzip(buf) => f.write(buf),
}
}
@@ -86,7 +87,7 @@ impl io::Write for &WriterChannel {
match self {
WriterChannel::File(f) => (&*f).flush(),
#[cfg(feature = "compression")]
- WriterChannel::CompressedFileGzip(buf) => buf.flush()
+ WriterChannel::CompressedFileGzip(buf) => buf.flush(),
}
}
}
From 6601402980ec878d14eb92bd2d54fbfed8c34c05 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Fri, 24 Dec 2021 12:45:32 +0100
Subject: [PATCH 06/22] Review fixes - to be continued
---
tracing-appender/Cargo.toml | 6 +--
tracing-appender/src/builder.rs | 59 +++++++++++------------------
tracing-appender/src/compression.rs | 38 +++++++++++++------
tracing-appender/src/lib.rs | 2 +-
tracing-appender/src/rolling.rs | 23 ++++++-----
tracing-appender/src/writer.rs | 38 ++++++++++++-------
6 files changed, 89 insertions(+), 77 deletions(-)
diff --git a/tracing-appender/Cargo.toml b/tracing-appender/Cargo.toml
index 6b28260e28..4579997d37 100644
--- a/tracing-appender/Cargo.toml
+++ b/tracing-appender/Cargo.toml
@@ -20,6 +20,9 @@ keywords = ["logging", "tracing", "file-appender", "non-blocking-writer"]
edition = "2018"
rust-version = "1.51.0"
+[features]
+compression = ["flate2"]
+
[dependencies]
crossbeam-channel = "0.5.0"
time = { version = "0.3", default-features = false, features = ["formatting"] }
@@ -36,6 +39,3 @@ features = ["fmt", "std"]
tracing = { path = "../tracing", version = "0.2" }
time = { version = "0.3", default-features = false, features = ["formatting", "parsing"] }
tempfile = "3"
-
-[features]
-compression = ["flate2"]
diff --git a/tracing-appender/src/builder.rs b/tracing-appender/src/builder.rs
index c9708370fc..3f61f33ee4 100644
--- a/tracing-appender/src/builder.rs
+++ b/tracing-appender/src/builder.rs
@@ -1,3 +1,4 @@
+use std::path::Path;
use crate::rolling::{create_writer_file, Inner, RollingFileAppender, Rotation};
use crate::sync::RwLock;
use std::sync::atomic::AtomicUsize;
@@ -8,48 +9,40 @@ use crate::compression::CompressionConfig;
use crate::writer::WriterChannel;
+
+#[derive(Debug)]
pub struct RollingFileAppenderBuilder {
- log_directory: Option,
- log_filename_prefix: Option,
+ log_directory: String,
+ log_filename_prefix: String,
rotation: Option,
- next_date: Option,
#[cfg(feature = "compression")]
compression: Option,
}
impl RollingFileAppenderBuilder {
- pub fn new() -> Self {
+ /// Creates an instance of RollingFileAppnderBuilder
+ pub fn new(log_directory: impl AsRef,
+ log_filename_prefix: impl AsRef) -> Self {
+ let log_directory = log_directory.as_ref().to_str().expect("Cannot convert log_directory Path to str").to_string();
+ let log_filename_prefix = log_filename_prefix.as_ref().to_str().expect("Cannot convert log_filename_prefix Path to str").to_string();
RollingFileAppenderBuilder {
- log_directory: None,
- log_filename_prefix: None,
+ log_directory,
+ log_filename_prefix,
rotation: None,
- next_date: None,
#[cfg(feature = "compression")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "compression")))]
compression: None,
}
}
- pub fn log_directory(mut self, log_directory: String) -> Self {
- self.log_directory = Some(log_directory);
- self
- }
-
- pub fn log_filename_prefix(mut self, log_filename_prefix: String) -> Self {
- self.log_filename_prefix = Some(log_filename_prefix);
- self
- }
-
+ /// Sets Rotation
pub fn rotation(mut self, rotation: Rotation) -> Self {
self.rotation = Some(rotation);
self
}
- pub fn next_date(mut self, next_date: AtomicUsize) -> Self {
- self.next_date = Some(next_date);
- self
- }
-
#[cfg(feature = "compression")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "compression")))]
pub fn compression(mut self, compression: CompressionConfig) -> Self {
self.compression = Some(compression);
self
@@ -57,20 +50,12 @@ impl RollingFileAppenderBuilder {
pub fn build(self) -> RollingFileAppender {
let now = OffsetDateTime::now_utc();
- let log_directory = self
- .log_directory
- .expect("log_directory is required to build RollingFileAppender");
- let log_filename_prefix = self
- .log_filename_prefix
- .expect("log_filename_prefix is required to build RollingFileAppender");
- let rotation = self
- .rotation
- .expect("rotation is required to build RollingFileAppender");
-
- let filename = rotation.join_date(log_filename_prefix.as_str(), &now, false);
+ let rotation = self.rotation.unwrap_or(Rotation::NEVER);
+ let filename = rotation.join_date(self.log_filename_prefix.as_str(), &now, false);
let next_date = rotation.next_date(&now);
+
let writer = RwLock::new(WriterChannel::File(
- create_writer_file(log_directory.as_str(), &filename)
+ create_writer_file(self.log_directory.as_str(), &filename)
.expect("failed to create appender"),
));
@@ -82,10 +67,10 @@ impl RollingFileAppenderBuilder {
RollingFileAppender {
state: Inner {
- log_directory,
- log_filename_prefix,
+ log_directory: self.log_directory,
+ log_filename_prefix: self.log_filename_prefix,
next_date,
- rotation,
+ rotation: rotation,
#[cfg(feature = "compression")]
compression: self.compression,
},
diff --git a/tracing-appender/src/compression.rs b/tracing-appender/src/compression.rs
index c4c6888aaf..4f203adc94 100644
--- a/tracing-appender/src/compression.rs
+++ b/tracing-appender/src/compression.rs
@@ -1,11 +1,13 @@
use flate2::Compression;
+#[derive(Debug, Clone)]
pub enum GzipCompressionLevelLiteral {
None,
Fast,
Best,
}
+#[derive(Debug, Clone)]
pub enum GzipCompressionLevelNumerical {
Level0,
Level1,
@@ -19,6 +21,7 @@ pub enum GzipCompressionLevelNumerical {
Level9,
}
+#[derive(Debug, Clone)]
pub enum GzipCompressionLevel {
Literal(GzipCompressionLevelLiteral),
Numerical(GzipCompressionLevelNumerical),
@@ -26,37 +29,50 @@ pub enum GzipCompressionLevel {
impl Into for GzipCompressionLevel {
fn into(self) -> Compression {
- match GzipCompressionLevel {
+ match self {
GzipCompressionLevel::Literal(lit) => match lit {
GzipCompressionLevelLiteral::None => Compression::none(),
GzipCompressionLevelLiteral::Fast => Compression::fast(),
GzipCompressionLevelLiteral::Best => Compression::best(),
},
GzipCompressionLevel::Numerical(num) => match num {
- GzipCompressionLevelNumerical::Level0 => Compression(0),
- GzipCompressionLevelNumerical::Level1 => Compression(1),
- GzipCompressionLevelNumerical::Level2 => Compression(2),
- GzipCompressionLevelNumerical::Level3 => Compression(3),
- GzipCompressionLevelNumerical::Level4 => Compression(4),
- GzipCompressionLevelNumerical::Level5 => Compression(5),
- GzipCompressionLevelNumerical::Level6 => Compression(6),
- GzipCompressionLevelNumerical::Level7 => Compression(7),
- GzipCompressionLevelNumerical::Level8 => Compression(8),
- GzipCompressionLevelNumerical::Level9 => Compression(9),
+ GzipCompressionLevelNumerical::Level0 => Compression::new(0),
+ GzipCompressionLevelNumerical::Level1 => Compression::new(1),
+ GzipCompressionLevelNumerical::Level2 => Compression::new(2),
+ GzipCompressionLevelNumerical::Level3 => Compression::new(3),
+ GzipCompressionLevelNumerical::Level4 => Compression::new(4),
+ GzipCompressionLevelNumerical::Level5 => Compression::new(5),
+ GzipCompressionLevelNumerical::Level6 => Compression::new(6),
+ GzipCompressionLevelNumerical::Level7 => Compression::new(7),
+ GzipCompressionLevelNumerical::Level8 => Compression::new(8),
+ GzipCompressionLevelNumerical::Level9 => Compression::new(9),
},
}
}
}
+#[derive(Debug, Clone)]
pub struct GzipCompression {
pub level: GzipCompressionLevel,
}
/// Data structure to pass compression parameters
+#[derive(Debug, Clone)]
pub enum CompressionConfig {
Gzip(GzipCompression),
}
+impl CompressionConfig {
+ pub(crate) fn gz_compress_level(&self) -> Compression {
+ match self {
+ CompressionConfig::Gzip(gz) => {
+ let level = gz.level.into();
+ level
+ }
+ }
+ }
+}
+
mod compression_options {
use super::*;
pub const GZIP_NONE: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
diff --git a/tracing-appender/src/lib.rs b/tracing-appender/src/lib.rs
index 55abdb8747..ae7ecb06f9 100644
--- a/tracing-appender/src/lib.rs
+++ b/tracing-appender/src/lib.rs
@@ -166,7 +166,7 @@ mod writer;
#[cfg(feature = "compression")]
mod compression;
-mod builder;
+pub mod builder;
/// Convenience function for creating a non-blocking, off-thread writer.
///
diff --git a/tracing-appender/src/rolling.rs b/tracing-appender/src/rolling.rs
index ab863ec441..54e69643cf 100644
--- a/tracing-appender/src/rolling.rs
+++ b/tracing-appender/src/rolling.rs
@@ -39,6 +39,7 @@ use std::{
sync::atomic::{AtomicUsize, Ordering},
};
use time::{format_description, Duration, OffsetDateTime, Time};
+use tracing_subscriber::fmt::format::Writer;
/// A file appender with the ability to rotate log files at a fixed schedule.
///
@@ -88,6 +89,8 @@ use time::{format_description, Duration, OffsetDateTime, Time};
pub struct RollingFileAppender {
pub(crate) state: Inner,
pub(crate) writer: RwLock,
+ #[cfg(features = "compression")]
+ pub(crate) compression: Option,
}
/// A [writer] that writes to a rolling log file.
@@ -140,10 +143,8 @@ impl RollingFileAppender {
directory: impl AsRef,
file_name_prefix: impl AsRef,
) -> RollingFileAppender {
- RollingFileAppenderBuilder::new()
+ RollingFileAppenderBuilder::new(directory, file_name_prefix)
.rotation(rotation)
- .log_directory(directory.as_ref().to_str().unwrap().to_string())
- .log_filename_prefix(file_name_prefix.as_ref().to_str().unwrap().to_string())
.build()
}
}
@@ -478,20 +479,18 @@ impl io::Write for RollingWriter<'_> {
impl Inner {
#[cfg(feature = "compression")]
- fn refresh_writer(
- &self,
- now: OffsetDateTime,
- file: &mut WriterChannel,
- compression: CompressionConfig,
- ) {
+ fn refresh_writer(&self, now: OffsetDateTime, file: &mut WriterChannel) {
debug_assert!(self.should_rollover(now));
let filename = self
.rotation
.join_date(&self.log_filename_prefix, &now, false);
- let writer =
- WriterChannel::new_with_compression(&self.log_directory, &filename, compression);
+ let writer = if let Some(compression) = self.compression.clone() {
+ WriterChannel::new_with_compression(&self.log_directory, &filename, compression)
+ } else {
+ WriterChannel::new_without_compression(&self.log_directory, &filename)
+ };
Self::refresh_writer_channel(file, writer);
}
@@ -547,7 +546,7 @@ impl Inner {
}
}
-pub fn create_writer_file(directory: &str, filename: &str) -> io::Result {
+pub(crate) fn create_writer_file(directory: &str, filename: &str) -> io::Result {
let path = Path::new(directory).join(filename);
let mut open_options = OpenOptions::new();
open_options.append(true).create(true);
diff --git a/tracing-appender/src/writer.rs b/tracing-appender/src/writer.rs
index 96ba291385..7c964efc50 100644
--- a/tracing-appender/src/writer.rs
+++ b/tracing-appender/src/writer.rs
@@ -1,21 +1,29 @@
-#[cfg(feature = "compression")]
-use crate::compression::CompressionConfig;
use crate::rolling::create_writer_file;
use crate::sync::RwLock;
-#[cfg(feature = "compression")]
-use flate2::write::GzEncoder;
-use std::borrow::BorrowMut;
+use std::borrow::{Borrow, BorrowMut};
use std::fs::{File, OpenOptions};
use std::io::{BufWriter, Write};
use std::ops::{Deref, DerefMut};
use std::path::Path;
use std::{fs, io};
+#[cfg(feature = "compression")]
+use flate2::write::GzEncoder;
+
+#[cfg(feature = "compression")]
+use crate::compression::CompressionConfig;
+
+#[derive(Debug)]
+struct CompressedGzip {
+ compression: CompressionConfig,
+ buffer: BufWriter>>,
+}
+
#[derive(Debug)]
pub enum WriterChannel {
File(File),
#[cfg(feature = "compression")]
- CompressedFileGzip(BufWriter>>),
+ CompressedFileGzip(CompressedGzip),
}
impl WriterChannel {
@@ -23,7 +31,7 @@ impl WriterChannel {
pub fn new(
directory: &str,
filename: &str,
- #[cfg(feature = "compression")] compression: CompressionConfig,
+ #[cfg(feature = "compression")] compression: Option,
) -> io::Result {
if let Some(compression) = compression {
Self::new_with_compression(directory, filename, compression)
@@ -50,9 +58,13 @@ impl WriterChannel {
) -> io::Result {
let file = create_writer_file(directory, filename)?;
let buf = BufWriter::new(file);
- let gzfile = GzEncoder::new(buf, compression.into());
+ let gzfile = GzEncoder::new(buf, compression.gz_compress_level());
let writer = BufWriter::new(gzfile);
- Ok(WriterChannel::CompressedFileGzip(writer))
+ let compressed_gz = CompressedGzip {
+ compression: compression.clone(),
+ buffer: writer,
+ };
+ Ok(WriterChannel::CompressedFileGzip(compressed_gz))
}
}
@@ -61,7 +73,7 @@ impl io::Write for WriterChannel {
match self {
WriterChannel::File(f) => f.write(buf),
#[cfg(feature = "compression")]
- WriterChannel::CompressedFileGzip(buf) => f.write(buf),
+ WriterChannel::CompressedFileGzip(gz) => gz.buffer.write(buf),
}
}
@@ -69,7 +81,7 @@ impl io::Write for WriterChannel {
match self {
WriterChannel::File(f) => f.flush(),
#[cfg(feature = "compression")]
- WriterChannel::CompressedFileGzip(buf) => buf.flush(),
+ WriterChannel::CompressedFileGzip(gz) => gz.buffer.flush(),
}
}
}
@@ -79,7 +91,7 @@ impl io::Write for &WriterChannel {
match self {
WriterChannel::File(f) => (&*f).write(buf),
#[cfg(feature = "compression")]
- WriterChannel::CompressedFileGzip(buf) => f.write(buf),
+ WriterChannel::CompressedFileGzip(gz) => gz.buffer.write(buf),
}
}
@@ -87,7 +99,7 @@ impl io::Write for &WriterChannel {
match self {
WriterChannel::File(f) => (&*f).flush(),
#[cfg(feature = "compression")]
- WriterChannel::CompressedFileGzip(buf) => buf.flush(),
+ WriterChannel::CompressedFileGzip(gz) => gz.buffer.flush(),
}
}
}
From 2c9f149ef5c2d3f46060d4249e9cb8060b4f3dea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Fri, 24 Dec 2021 14:32:34 +0100
Subject: [PATCH 07/22] Format
---
tracing-appender/src/builder.rs | 18 ++++++++++++------
tracing-appender/src/compression.rs | 2 +-
tracing-appender/src/rolling.rs | 1 -
tracing-appender/src/writer.rs | 10 +++-------
4 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/tracing-appender/src/builder.rs b/tracing-appender/src/builder.rs
index 3f61f33ee4..c26151f20b 100644
--- a/tracing-appender/src/builder.rs
+++ b/tracing-appender/src/builder.rs
@@ -1,6 +1,6 @@
-use std::path::Path;
use crate::rolling::{create_writer_file, Inner, RollingFileAppender, Rotation};
use crate::sync::RwLock;
+use std::path::Path;
use std::sync::atomic::AtomicUsize;
use time::OffsetDateTime;
@@ -9,7 +9,6 @@ use crate::compression::CompressionConfig;
use crate::writer::WriterChannel;
-
#[derive(Debug)]
pub struct RollingFileAppenderBuilder {
log_directory: String,
@@ -21,10 +20,17 @@ pub struct RollingFileAppenderBuilder {
impl RollingFileAppenderBuilder {
/// Creates an instance of RollingFileAppnderBuilder
- pub fn new(log_directory: impl AsRef,
- log_filename_prefix: impl AsRef) -> Self {
- let log_directory = log_directory.as_ref().to_str().expect("Cannot convert log_directory Path to str").to_string();
- let log_filename_prefix = log_filename_prefix.as_ref().to_str().expect("Cannot convert log_filename_prefix Path to str").to_string();
+ pub fn new(log_directory: impl AsRef, log_filename_prefix: impl AsRef) -> Self {
+ let log_directory = log_directory
+ .as_ref()
+ .to_str()
+ .expect("Cannot convert log_directory Path to str")
+ .to_string();
+ let log_filename_prefix = log_filename_prefix
+ .as_ref()
+ .to_str()
+ .expect("Cannot convert log_filename_prefix Path to str")
+ .to_string();
RollingFileAppenderBuilder {
log_directory,
log_filename_prefix,
diff --git a/tracing-appender/src/compression.rs b/tracing-appender/src/compression.rs
index 4f203adc94..98604c74fd 100644
--- a/tracing-appender/src/compression.rs
+++ b/tracing-appender/src/compression.rs
@@ -66,7 +66,7 @@ impl CompressionConfig {
pub(crate) fn gz_compress_level(&self) -> Compression {
match self {
CompressionConfig::Gzip(gz) => {
- let level = gz.level.into();
+ let level = gz.level.clone().into();
level
}
}
diff --git a/tracing-appender/src/rolling.rs b/tracing-appender/src/rolling.rs
index 54e69643cf..a91bbc10a3 100644
--- a/tracing-appender/src/rolling.rs
+++ b/tracing-appender/src/rolling.rs
@@ -39,7 +39,6 @@ use std::{
sync::atomic::{AtomicUsize, Ordering},
};
use time::{format_description, Duration, OffsetDateTime, Time};
-use tracing_subscriber::fmt::format::Writer;
/// A file appender with the ability to rotate log files at a fixed schedule.
///
diff --git a/tracing-appender/src/writer.rs b/tracing-appender/src/writer.rs
index 7c964efc50..aaa04de0fa 100644
--- a/tracing-appender/src/writer.rs
+++ b/tracing-appender/src/writer.rs
@@ -1,11 +1,7 @@
use crate::rolling::create_writer_file;
-use crate::sync::RwLock;
-use std::borrow::{Borrow, BorrowMut};
-use std::fs::{File, OpenOptions};
-use std::io::{BufWriter, Write};
-use std::ops::{Deref, DerefMut};
-use std::path::Path;
-use std::{fs, io};
+use std::fs::File;
+use std::io;
+use std::io::BufWriter;
#[cfg(feature = "compression")]
use flate2::write::GzEncoder;
From 248d923e0249c139ab663893bb76f0b495c1fc69 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Fri, 24 Dec 2021 14:38:29 +0100
Subject: [PATCH 08/22] Use pub(crate)
---
tracing-appender/src/compression.rs | 13 +++++++------
tracing-appender/src/writer.rs | 10 +++++-----
2 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/tracing-appender/src/compression.rs b/tracing-appender/src/compression.rs
index 98604c74fd..2cdf2c5948 100644
--- a/tracing-appender/src/compression.rs
+++ b/tracing-appender/src/compression.rs
@@ -1,14 +1,14 @@
use flate2::Compression;
#[derive(Debug, Clone)]
-pub enum GzipCompressionLevelLiteral {
+enum GzipCompressionLevelLiteral {
None,
Fast,
Best,
}
#[derive(Debug, Clone)]
-pub enum GzipCompressionLevelNumerical {
+enum GzipCompressionLevelNumerical {
Level0,
Level1,
Level2,
@@ -22,7 +22,7 @@ pub enum GzipCompressionLevelNumerical {
}
#[derive(Debug, Clone)]
-pub enum GzipCompressionLevel {
+enum GzipCompressionLevel {
Literal(GzipCompressionLevelLiteral),
Numerical(GzipCompressionLevelNumerical),
}
@@ -52,13 +52,14 @@ impl Into for GzipCompressionLevel {
}
#[derive(Debug, Clone)]
-pub struct GzipCompression {
+struct GzipCompression {
pub level: GzipCompressionLevel,
}
/// Data structure to pass compression parameters
#[derive(Debug, Clone)]
-pub enum CompressionConfig {
+#[non_exhaustive]
+pub(crate) enum CompressionConfig {
Gzip(GzipCompression),
}
@@ -73,7 +74,7 @@ impl CompressionConfig {
}
}
-mod compression_options {
+pub mod compression_options {
use super::*;
pub const GZIP_NONE: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
level: GzipCompressionLevel::Literal(GzipCompressionLevelLiteral::None),
diff --git a/tracing-appender/src/writer.rs b/tracing-appender/src/writer.rs
index aaa04de0fa..76f9cc873e 100644
--- a/tracing-appender/src/writer.rs
+++ b/tracing-appender/src/writer.rs
@@ -16,7 +16,7 @@ struct CompressedGzip {
}
#[derive(Debug)]
-pub enum WriterChannel {
+pub(crate) enum WriterChannel {
File(File),
#[cfg(feature = "compression")]
CompressedFileGzip(CompressedGzip),
@@ -24,7 +24,7 @@ pub enum WriterChannel {
impl WriterChannel {
#[cfg(feature = "compression")]
- pub fn new(
+ pub(crate) fn new(
directory: &str,
filename: &str,
#[cfg(feature = "compression")] compression: Option,
@@ -37,17 +37,17 @@ impl WriterChannel {
}
#[cfg(not(feature = "compression"))]
- pub fn new(directory: &str, filename: &str) -> io::Result {
+ pub(crate) fn new(directory: &str, filename: &str) -> io::Result {
Self::new_without_compression(directory, filename)
}
- pub fn new_without_compression(directory: &str, filename: &str) -> io::Result {
+ pub(crate) fn new_without_compression(directory: &str, filename: &str) -> io::Result {
let file = create_writer_file(directory, filename)?;
Ok(WriterChannel::File(file))
}
#[cfg(feature = "compression")]
- pub fn new_with_compression(
+ pub(crate) fn new_with_compression(
directory: &str,
filename: &str,
compression: CompressionConfig,
From 6f4a6062acc9bbcb79640b1a68d432fc9596f23a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Fri, 24 Dec 2021 15:09:06 +0100
Subject: [PATCH 09/22] Clean up compression options
---
tracing-appender/src/builder.rs | 5 +-
tracing-appender/src/compression.rs | 112 ++++++++++++++++------------
tracing-appender/src/writer.rs | 27 +++++--
3 files changed, 89 insertions(+), 55 deletions(-)
diff --git a/tracing-appender/src/builder.rs b/tracing-appender/src/builder.rs
index c26151f20b..2f0cef69f3 100644
--- a/tracing-appender/src/builder.rs
+++ b/tracing-appender/src/builder.rs
@@ -6,6 +6,7 @@ use time::OffsetDateTime;
#[cfg(feature = "compression")]
use crate::compression::CompressionConfig;
+use crate::compression::CompressionOption;
use crate::writer::WriterChannel;
@@ -49,8 +50,8 @@ impl RollingFileAppenderBuilder {
#[cfg(feature = "compression")]
#[cfg_attr(docsrs, doc(cfg(feature = "compression")))]
- pub fn compression(mut self, compression: CompressionConfig) -> Self {
- self.compression = Some(compression);
+ pub fn compression(mut self, compression: CompressionOption) -> Self {
+ self.compression = Some(compression.into());
self
}
diff --git a/tracing-appender/src/compression.rs b/tracing-appender/src/compression.rs
index 2cdf2c5948..6bcfe23082 100644
--- a/tracing-appender/src/compression.rs
+++ b/tracing-appender/src/compression.rs
@@ -1,14 +1,14 @@
use flate2::Compression;
#[derive(Debug, Clone)]
-enum GzipCompressionLevelLiteral {
+pub(crate) enum GzipCompressionLevelLiteral {
None,
Fast,
Best,
}
#[derive(Debug, Clone)]
-enum GzipCompressionLevelNumerical {
+pub(crate) enum GzipCompressionLevelNumerical {
Level0,
Level1,
Level2,
@@ -22,7 +22,7 @@ enum GzipCompressionLevelNumerical {
}
#[derive(Debug, Clone)]
-enum GzipCompressionLevel {
+pub(crate) enum GzipCompressionLevel {
Literal(GzipCompressionLevelLiteral),
Numerical(GzipCompressionLevelNumerical),
}
@@ -52,8 +52,8 @@ impl Into for GzipCompressionLevel {
}
#[derive(Debug, Clone)]
-struct GzipCompression {
- pub level: GzipCompressionLevel,
+pub(crate) struct GzipCompression {
+ pub(crate) level: GzipCompressionLevel,
}
/// Data structure to pass compression parameters
@@ -74,45 +74,65 @@ impl CompressionConfig {
}
}
-pub mod compression_options {
- use super::*;
- pub const GZIP_NONE: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Literal(GzipCompressionLevelLiteral::None),
- });
- pub const GZIP_FAST: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Literal(GzipCompressionLevelLiteral::Fast),
- });
- pub const GZIP_BEST: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Literal(GzipCompressionLevelLiteral::Best),
- });
- pub const GZIP_0: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level0),
- });
- pub const GZIP_1: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level1),
- });
- pub const GZIP_2: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level2),
- });
- pub const GZIP_3: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level3),
- });
- pub const GZIP_4: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level4),
- });
- pub const GZIP_5: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level5),
- });
- pub const GZIP_6: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level6),
- });
- pub const GZIP_7: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level7),
- });
- pub const GZIP_8: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level8),
- });
- pub const GZIP_9: CompressionConfig = CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level9),
- });
+#[derive(Debug)]
+pub enum CompressionOption {
+ GzipNone,
+ GzipFast,
+ GzipBest,
+ GzipLevel0,
+ GzipLevel1,
+ GzipLevel2,
+ GzipLevel3,
+ GzipLevel4,
+ GzipLevel5,
+ GzipLevel6,
+ GzipLevel7,
+ GzipLevel8,
+ GzipLevel9,
+}
+
+impl Into for CompressionOption {
+ fn into(self) -> CompressionConfig {
+ match self {
+ CompressionOption::GzipNone => CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Literal(GzipCompressionLevelLiteral::None),
+ }),
+ CompressionOption::GzipFast => CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Literal(GzipCompressionLevelLiteral::Fast),
+ }),
+ CompressionOption::GzipBest => CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Literal(GzipCompressionLevelLiteral::Best),
+ }),
+ CompressionOption::GzipLevel0 => CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level0),
+ }),
+ CompressionOption::GzipLevel1 => CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level1),
+ }),
+ CompressionOption::GzipLevel2 => CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level2),
+ }),
+ CompressionOption::GzipLevel3 => CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level3),
+ }),
+ CompressionOption::GzipLevel4 => CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level4),
+ }),
+ CompressionOption::GzipLevel5 => CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level5),
+ }),
+ CompressionOption::GzipLevel6 => CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level6),
+ }),
+ CompressionOption::GzipLevel7 => CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level7),
+ }),
+ CompressionOption::GzipLevel8 => CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level8),
+ }),
+ CompressionOption::GzipLevel9 => CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level9),
+ }),
+ }
+ }
}
diff --git a/tracing-appender/src/writer.rs b/tracing-appender/src/writer.rs
index 76f9cc873e..1dd4e2bd98 100644
--- a/tracing-appender/src/writer.rs
+++ b/tracing-appender/src/writer.rs
@@ -2,6 +2,7 @@ use crate::rolling::create_writer_file;
use std::fs::File;
use std::io;
use std::io::BufWriter;
+use std::sync::{Arc, RwLock};
#[cfg(feature = "compression")]
use flate2::write::GzEncoder;
@@ -10,9 +11,9 @@ use flate2::write::GzEncoder;
use crate::compression::CompressionConfig;
#[derive(Debug)]
-struct CompressedGzip {
+pub(crate) struct CompressedGzip {
compression: CompressionConfig,
- buffer: BufWriter>>,
+ buffer: Arc>>>>,
}
#[derive(Debug)]
@@ -58,7 +59,7 @@ impl WriterChannel {
let writer = BufWriter::new(gzfile);
let compressed_gz = CompressedGzip {
compression: compression.clone(),
- buffer: writer,
+ buffer: Arc::new(RwLock::new(writer)),
};
Ok(WriterChannel::CompressedFileGzip(compressed_gz))
}
@@ -69,7 +70,10 @@ impl io::Write for WriterChannel {
match self {
WriterChannel::File(f) => f.write(buf),
#[cfg(feature = "compression")]
- WriterChannel::CompressedFileGzip(gz) => gz.buffer.write(buf),
+ WriterChannel::CompressedFileGzip(gz) => {
+ let mut buffer = gz.buffer.write().unwrap();
+ buffer.write(buf)
+ }
}
}
@@ -77,7 +81,10 @@ impl io::Write for WriterChannel {
match self {
WriterChannel::File(f) => f.flush(),
#[cfg(feature = "compression")]
- WriterChannel::CompressedFileGzip(gz) => gz.buffer.flush(),
+ WriterChannel::CompressedFileGzip(gz) => {
+ let mut buffer = gz.buffer.write().unwrap();
+ buffer.flush()
+ }
}
}
}
@@ -87,7 +94,10 @@ impl io::Write for &WriterChannel {
match self {
WriterChannel::File(f) => (&*f).write(buf),
#[cfg(feature = "compression")]
- WriterChannel::CompressedFileGzip(gz) => gz.buffer.write(buf),
+ WriterChannel::CompressedFileGzip(gz) => {
+ let mut buffer = gz.buffer.write().unwrap();
+ buffer.write(buf)
+ }
}
}
@@ -95,7 +105,10 @@ impl io::Write for &WriterChannel {
match self {
WriterChannel::File(f) => (&*f).flush(),
#[cfg(feature = "compression")]
- WriterChannel::CompressedFileGzip(gz) => gz.buffer.flush(),
+ WriterChannel::CompressedFileGzip(gz) => {
+ let mut buffer = gz.buffer.write().unwrap();
+ buffer.flush()
+ }
}
}
}
From 271e3b5c684e9eb75705ebbd2d646213c8dd2ee2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Fri, 24 Dec 2021 15:30:21 +0100
Subject: [PATCH 10/22] Clean up imports
---
tracing-appender/src/builder.rs | 2 ++
tracing-appender/src/writer.rs | 11 ++++++-----
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/tracing-appender/src/builder.rs b/tracing-appender/src/builder.rs
index 2f0cef69f3..743d474099 100644
--- a/tracing-appender/src/builder.rs
+++ b/tracing-appender/src/builder.rs
@@ -6,6 +6,8 @@ use time::OffsetDateTime;
#[cfg(feature = "compression")]
use crate::compression::CompressionConfig;
+
+#[cfg(feature = "compression")]
use crate::compression::CompressionOption;
use crate::writer::WriterChannel;
diff --git a/tracing-appender/src/writer.rs b/tracing-appender/src/writer.rs
index 1dd4e2bd98..100741a859 100644
--- a/tracing-appender/src/writer.rs
+++ b/tracing-appender/src/writer.rs
@@ -1,15 +1,16 @@
use crate::rolling::create_writer_file;
use std::fs::File;
use std::io;
-use std::io::BufWriter;
-use std::sync::{Arc, RwLock};
#[cfg(feature = "compression")]
-use flate2::write::GzEncoder;
+use {
+ crate::compression::CompressionConfig,
+ flate2::write::GzEncoder,
+ std::io::BufWriter,
+ std::sync::{Arc, RwLock},
+};
#[cfg(feature = "compression")]
-use crate::compression::CompressionConfig;
-
#[derive(Debug)]
pub(crate) struct CompressedGzip {
compression: CompressionConfig,
From 5ff40aa40b999a67cc41a9cfc22927fc418f4a83 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Mon, 27 Dec 2021 15:18:42 +0100
Subject: [PATCH 11/22] Add some docs
---
tracing-appender/src/builder.rs | 17 ++++++++++++++++-
tracing-appender/src/compression.rs | 18 +++++++++++++++++-
2 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/tracing-appender/src/builder.rs b/tracing-appender/src/builder.rs
index 743d474099..344a7d11f4 100644
--- a/tracing-appender/src/builder.rs
+++ b/tracing-appender/src/builder.rs
@@ -22,7 +22,22 @@ pub struct RollingFileAppenderBuilder {
}
impl RollingFileAppenderBuilder {
- /// Creates an instance of RollingFileAppnderBuilder
+ /// Creates a new `RollingFileAppnderBuilder`
+ ///
+ /// It was introduced to open up the possibility to use `compression` without
+ /// breaking the current interface.
+ ///
+ /// Note that `compression` module is enabled by using an optional feature flag `compression`
+ ///
+ /// # Examples
+ /// ```rust
+ /// use tracing_appender::builder::RollingFileAppenderBuilder;
+ /// use tracing_appender::compression::CompressionOption;
+ /// use tracing_appender::rolling::Rotation;
+ /// let builder = RollingFileAppenderBuilder::new("/var/tmp", "my-app")
+ /// .rotation(Rotation::DAILY)
+ /// .compression(CompressionOption::GzipFast);
+ /// ```
pub fn new(log_directory: impl AsRef, log_filename_prefix: impl AsRef) -> Self {
let log_directory = log_directory
.as_ref()
diff --git a/tracing-appender/src/compression.rs b/tracing-appender/src/compression.rs
index 6bcfe23082..e62da9a13b 100644
--- a/tracing-appender/src/compression.rs
+++ b/tracing-appender/src/compression.rs
@@ -27,6 +27,7 @@ pub(crate) enum GzipCompressionLevel {
Numerical(GzipCompressionLevelNumerical),
}
+/// Defines a conversion between `CompressionOption` and `flate2::Compression`
impl Into for GzipCompressionLevel {
fn into(self) -> Compression {
match self {
@@ -74,7 +75,22 @@ impl CompressionConfig {
}
}
-#[derive(Debug)]
+/// Defines a compression level for gzip algorithm.
+///
+/// Compression levels are defined as they are in `flate2` crate where
+/// - compression level 0 (`CompressionOption::GzipNone` or `CompressionOption::GzipLevel0`)
+/// - compression level 1 (`CompressionOption::GzipFast` or `CompressionOption::GzipLevel1`)
+/// - compression level n (where n is between 2 and 9)
+/// - compression level 9 (`CompressionOption::GzipBest` or `CompressionOption::GzipLevel9`)
+///
+/// ```rust
+/// # fn docs() {
+/// use tracing_appender::compression::CompressionOption;
+/// let compression_level = CompressionOption::GzipBest;
+/// # }
+/// ```
+#[derive(Debug, Clone, Eq, PartialEq)]
+#[non_exhaustive]
pub enum CompressionOption {
GzipNone,
GzipFast,
From 4a470c382dc1f5f0394d365ab216fbbc16fa3363 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Mon, 27 Dec 2021 15:28:53 +0100
Subject: [PATCH 12/22] Rename feature flag compression to compression_gzip
---
tracing-appender/Cargo.toml | 2 +-
tracing-appender/src/builder.rs | 30 +++++++++++++++++++----------
tracing-appender/src/compression.rs | 10 +++++-----
tracing-appender/src/lib.rs | 2 +-
tracing-appender/src/rolling.rs | 8 ++++----
tracing-appender/src/writer.rs | 22 ++++++++++-----------
6 files changed, 42 insertions(+), 32 deletions(-)
diff --git a/tracing-appender/Cargo.toml b/tracing-appender/Cargo.toml
index 4579997d37..2d733a7bd6 100644
--- a/tracing-appender/Cargo.toml
+++ b/tracing-appender/Cargo.toml
@@ -21,7 +21,7 @@ edition = "2018"
rust-version = "1.51.0"
[features]
-compression = ["flate2"]
+compression_gzip = ["flate2"]
[dependencies]
crossbeam-channel = "0.5.0"
diff --git a/tracing-appender/src/builder.rs b/tracing-appender/src/builder.rs
index 344a7d11f4..20ab49e88d 100644
--- a/tracing-appender/src/builder.rs
+++ b/tracing-appender/src/builder.rs
@@ -1,23 +1,31 @@
+//! Builder struct for `RollingFileAppender`
+//!
+//! Gives access to setting additional options which are not avaible using standard interface.
+//! Currently it is the only way to enable compression of logs.
use crate::rolling::{create_writer_file, Inner, RollingFileAppender, Rotation};
use crate::sync::RwLock;
use std::path::Path;
use std::sync::atomic::AtomicUsize;
use time::OffsetDateTime;
-#[cfg(feature = "compression")]
+#[cfg(feature = "compression_gzip")]
use crate::compression::CompressionConfig;
-#[cfg(feature = "compression")]
+#[cfg(feature = "compression_gzip")]
use crate::compression::CompressionOption;
use crate::writer::WriterChannel;
-#[derive(Debug)]
+/// Struct for keeping temporary values of `RollingFileAppender`.
+///
+/// Note that `log_directory` and `log_filename_prefix` are obligatory parameters and should
+/// be passed into the constructor of `RollingFileAppenderBuilder`.
+#[derive(Debug, Clone, Eq, PartialEq)]
pub struct RollingFileAppenderBuilder {
log_directory: String,
log_filename_prefix: String,
rotation: Option,
- #[cfg(feature = "compression")]
+ #[cfg(feature = "compression_gzip")]
compression: Option,
}
@@ -27,7 +35,8 @@ impl RollingFileAppenderBuilder {
/// It was introduced to open up the possibility to use `compression` without
/// breaking the current interface.
///
- /// Note that `compression` module is enabled by using an optional feature flag `compression`
+ /// Note that `compression` module is enabled by using an optional feature flag
+ /// `compression_gzip` (for gzip algorithm)
///
/// # Examples
/// ```rust
@@ -53,8 +62,8 @@ impl RollingFileAppenderBuilder {
log_directory,
log_filename_prefix,
rotation: None,
- #[cfg(feature = "compression")]
- #[cfg_attr(docsrs, doc(cfg(feature = "compression")))]
+ #[cfg(feature = "compression_gzip")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "compression_gzip")))]
compression: None,
}
}
@@ -65,13 +74,14 @@ impl RollingFileAppenderBuilder {
self
}
- #[cfg(feature = "compression")]
- #[cfg_attr(docsrs, doc(cfg(feature = "compression")))]
+ #[cfg(feature = "compression_gzip")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "compression_gzip")))]
pub fn compression(mut self, compression: CompressionOption) -> Self {
self.compression = Some(compression.into());
self
}
+ /// Builds an instance of `RollingFileAppender` using previously defined attributes.
pub fn build(self) -> RollingFileAppender {
let now = OffsetDateTime::now_utc();
let rotation = self.rotation.unwrap_or(Rotation::NEVER);
@@ -95,7 +105,7 @@ impl RollingFileAppenderBuilder {
log_filename_prefix: self.log_filename_prefix,
next_date,
rotation: rotation,
- #[cfg(feature = "compression")]
+ #[cfg(feature = "compression_gzip")]
compression: self.compression,
},
writer,
diff --git a/tracing-appender/src/compression.rs b/tracing-appender/src/compression.rs
index e62da9a13b..3d64691623 100644
--- a/tracing-appender/src/compression.rs
+++ b/tracing-appender/src/compression.rs
@@ -1,13 +1,13 @@
use flate2::Compression;
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, Eq, PartialEq)]
pub(crate) enum GzipCompressionLevelLiteral {
None,
Fast,
Best,
}
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, Eq, PartialEq)]
pub(crate) enum GzipCompressionLevelNumerical {
Level0,
Level1,
@@ -21,7 +21,7 @@ pub(crate) enum GzipCompressionLevelNumerical {
Level9,
}
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, Eq, PartialEq)]
pub(crate) enum GzipCompressionLevel {
Literal(GzipCompressionLevelLiteral),
Numerical(GzipCompressionLevelNumerical),
@@ -52,13 +52,13 @@ impl Into for GzipCompressionLevel {
}
}
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, Eq, PartialEq)]
pub(crate) struct GzipCompression {
pub(crate) level: GzipCompressionLevel,
}
/// Data structure to pass compression parameters
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, Eq, PartialEq)]
#[non_exhaustive]
pub(crate) enum CompressionConfig {
Gzip(GzipCompression),
diff --git a/tracing-appender/src/lib.rs b/tracing-appender/src/lib.rs
index ae7ecb06f9..dbd24ce20e 100644
--- a/tracing-appender/src/lib.rs
+++ b/tracing-appender/src/lib.rs
@@ -163,7 +163,7 @@ pub(crate) mod sync;
mod writer;
-#[cfg(feature = "compression")]
+#[cfg(feature = "compression_gzip")]
mod compression;
pub mod builder;
diff --git a/tracing-appender/src/rolling.rs b/tracing-appender/src/rolling.rs
index a91bbc10a3..6b268afdd5 100644
--- a/tracing-appender/src/rolling.rs
+++ b/tracing-appender/src/rolling.rs
@@ -27,7 +27,7 @@
//! # }
//! ```
use crate::builder::RollingFileAppenderBuilder;
-#[cfg(feature = "compression")]
+#[cfg(feature = "compression_gzip")]
use crate::compression::CompressionConfig;
use crate::sync::{RwLock, RwLockReadGuard};
use crate::writer::WriterChannel;
@@ -107,7 +107,7 @@ pub(crate) struct Inner {
pub(crate) log_filename_prefix: String,
pub(crate) rotation: Rotation,
pub(crate) next_date: AtomicUsize,
- #[cfg(feature = "compression")]
+ #[cfg(feature = "compression_gzip")]
pub(crate) compression: Option,
}
@@ -477,7 +477,7 @@ impl io::Write for RollingWriter<'_> {
// === impl Inner ===
impl Inner {
- #[cfg(feature = "compression")]
+ #[cfg(feature = "compression_gzip")]
fn refresh_writer(&self, now: OffsetDateTime, file: &mut WriterChannel) {
debug_assert!(self.should_rollover(now));
@@ -494,7 +494,7 @@ impl Inner {
Self::refresh_writer_channel(file, writer);
}
- #[cfg(not(feature = "compression"))]
+ #[cfg(not(feature = "compression_gzip"))]
fn refresh_writer(&self, now: OffsetDateTime, file: &mut WriterChannel) {
debug_assert!(self.should_rollover(now));
diff --git a/tracing-appender/src/writer.rs b/tracing-appender/src/writer.rs
index 100741a859..a586f08a98 100644
--- a/tracing-appender/src/writer.rs
+++ b/tracing-appender/src/writer.rs
@@ -2,7 +2,7 @@ use crate::rolling::create_writer_file;
use std::fs::File;
use std::io;
-#[cfg(feature = "compression")]
+#[cfg(feature = "compression_gzip")]
use {
crate::compression::CompressionConfig,
flate2::write::GzEncoder,
@@ -10,7 +10,7 @@ use {
std::sync::{Arc, RwLock},
};
-#[cfg(feature = "compression")]
+#[cfg(feature = "compression_gzip")]
#[derive(Debug)]
pub(crate) struct CompressedGzip {
compression: CompressionConfig,
@@ -20,16 +20,16 @@ pub(crate) struct CompressedGzip {
#[derive(Debug)]
pub(crate) enum WriterChannel {
File(File),
- #[cfg(feature = "compression")]
+ #[cfg(feature = "compression_gzip")]
CompressedFileGzip(CompressedGzip),
}
impl WriterChannel {
- #[cfg(feature = "compression")]
+ #[cfg(feature = "compression_gzip")]
pub(crate) fn new(
directory: &str,
filename: &str,
- #[cfg(feature = "compression")] compression: Option,
+ #[cfg(feature = "compression_gzip")] compression: Option,
) -> io::Result {
if let Some(compression) = compression {
Self::new_with_compression(directory, filename, compression)
@@ -38,7 +38,7 @@ impl WriterChannel {
}
}
- #[cfg(not(feature = "compression"))]
+ #[cfg(not(feature = "compression_gzip"))]
pub(crate) fn new(directory: &str, filename: &str) -> io::Result {
Self::new_without_compression(directory, filename)
}
@@ -48,7 +48,7 @@ impl WriterChannel {
Ok(WriterChannel::File(file))
}
- #[cfg(feature = "compression")]
+ #[cfg(feature = "compression_gzip")]
pub(crate) fn new_with_compression(
directory: &str,
filename: &str,
@@ -70,7 +70,7 @@ impl io::Write for WriterChannel {
fn write(&mut self, buf: &[u8]) -> io::Result {
match self {
WriterChannel::File(f) => f.write(buf),
- #[cfg(feature = "compression")]
+ #[cfg(feature = "compression_gzip")]
WriterChannel::CompressedFileGzip(gz) => {
let mut buffer = gz.buffer.write().unwrap();
buffer.write(buf)
@@ -81,7 +81,7 @@ impl io::Write for WriterChannel {
fn flush(&mut self) -> io::Result<()> {
match self {
WriterChannel::File(f) => f.flush(),
- #[cfg(feature = "compression")]
+ #[cfg(feature = "compression_gzip")]
WriterChannel::CompressedFileGzip(gz) => {
let mut buffer = gz.buffer.write().unwrap();
buffer.flush()
@@ -94,7 +94,7 @@ impl io::Write for &WriterChannel {
fn write(&mut self, buf: &[u8]) -> io::Result {
match self {
WriterChannel::File(f) => (&*f).write(buf),
- #[cfg(feature = "compression")]
+ #[cfg(feature = "compression_gzip")]
WriterChannel::CompressedFileGzip(gz) => {
let mut buffer = gz.buffer.write().unwrap();
buffer.write(buf)
@@ -105,7 +105,7 @@ impl io::Write for &WriterChannel {
fn flush(&mut self) -> io::Result<()> {
match self {
WriterChannel::File(f) => (&*f).flush(),
- #[cfg(feature = "compression")]
+ #[cfg(feature = "compression_gzip")]
WriterChannel::CompressedFileGzip(gz) => {
let mut buffer = gz.buffer.write().unwrap();
buffer.flush()
From 241ea8f7111e54925952c153de1acc1ce47c282c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Tue, 28 Dec 2021 11:41:43 +0100
Subject: [PATCH 13/22] PR changes
---
tracing-appender/src/lib.rs | 5 --
tracing-appender/src/{ => rolling}/builder.rs | 8 +--
.../src/{ => rolling}/compression.rs | 51 ++++++++++---------
.../src/{rolling.rs => rolling/mod.rs} | 42 ++++++---------
tracing-appender/src/writer.rs | 20 ++++----
5 files changed, 57 insertions(+), 69 deletions(-)
rename tracing-appender/src/{ => rolling}/builder.rs (96%)
rename tracing-appender/src/{ => rolling}/compression.rs (83%)
rename tracing-appender/src/{rolling.rs => rolling/mod.rs} (95%)
diff --git a/tracing-appender/src/lib.rs b/tracing-appender/src/lib.rs
index dbd24ce20e..a3ccd5ff29 100644
--- a/tracing-appender/src/lib.rs
+++ b/tracing-appender/src/lib.rs
@@ -163,11 +163,6 @@ pub(crate) mod sync;
mod writer;
-#[cfg(feature = "compression_gzip")]
-mod compression;
-
-pub mod builder;
-
/// Convenience function for creating a non-blocking, off-thread writer.
///
/// See the [`non_blocking` module's docs][mod@non_blocking]'s for more details.
diff --git a/tracing-appender/src/builder.rs b/tracing-appender/src/rolling/builder.rs
similarity index 96%
rename from tracing-appender/src/builder.rs
rename to tracing-appender/src/rolling/builder.rs
index 20ab49e88d..dcf361a5fa 100644
--- a/tracing-appender/src/builder.rs
+++ b/tracing-appender/src/rolling/builder.rs
@@ -9,10 +9,9 @@ use std::sync::atomic::AtomicUsize;
use time::OffsetDateTime;
#[cfg(feature = "compression_gzip")]
-use crate::compression::CompressionConfig;
-
-#[cfg(feature = "compression_gzip")]
-use crate::compression::CompressionOption;
+use {
+ crate::rolling::compression::CompressionConfig, crate::rolling::compression::CompressionOption,
+};
use crate::writer::WriterChannel;
@@ -74,6 +73,7 @@ impl RollingFileAppenderBuilder {
self
}
+ /// Sets compression level
#[cfg(feature = "compression_gzip")]
#[cfg_attr(docsrs, doc(cfg(feature = "compression_gzip")))]
pub fn compression(mut self, compression: CompressionOption) -> Self {
diff --git a/tracing-appender/src/compression.rs b/tracing-appender/src/rolling/compression.rs
similarity index 83%
rename from tracing-appender/src/compression.rs
rename to tracing-appender/src/rolling/compression.rs
index 3d64691623..6289977afb 100644
--- a/tracing-appender/src/compression.rs
+++ b/tracing-appender/src/rolling/compression.rs
@@ -1,3 +1,6 @@
+//! Defines configuration for passing compression options
+//!
+//! Currently only gzip compression is implemented.
use flate2::Compression;
#[derive(Debug, Clone, Eq, PartialEq)]
@@ -8,17 +11,18 @@ pub(crate) enum GzipCompressionLevelLiteral {
}
#[derive(Debug, Clone, Eq, PartialEq)]
+#[repr(u32)]
pub(crate) enum GzipCompressionLevelNumerical {
- Level0,
- Level1,
- Level2,
- Level3,
- Level4,
- Level5,
- Level6,
- Level7,
- Level8,
- Level9,
+ Level0 = 0,
+ Level1 = 1,
+ Level2 = 2,
+ Level3 = 3,
+ Level4 = 4,
+ Level5 = 5,
+ Level6 = 6,
+ Level7 = 7,
+ Level8 = 8,
+ Level9 = 9,
}
#[derive(Debug, Clone, Eq, PartialEq)]
@@ -36,18 +40,7 @@ impl Into for GzipCompressionLevel {
GzipCompressionLevelLiteral::Fast => Compression::fast(),
GzipCompressionLevelLiteral::Best => Compression::best(),
},
- GzipCompressionLevel::Numerical(num) => match num {
- GzipCompressionLevelNumerical::Level0 => Compression::new(0),
- GzipCompressionLevelNumerical::Level1 => Compression::new(1),
- GzipCompressionLevelNumerical::Level2 => Compression::new(2),
- GzipCompressionLevelNumerical::Level3 => Compression::new(3),
- GzipCompressionLevelNumerical::Level4 => Compression::new(4),
- GzipCompressionLevelNumerical::Level5 => Compression::new(5),
- GzipCompressionLevelNumerical::Level6 => Compression::new(6),
- GzipCompressionLevelNumerical::Level7 => Compression::new(7),
- GzipCompressionLevelNumerical::Level8 => Compression::new(8),
- GzipCompressionLevelNumerical::Level9 => Compression::new(9),
- },
+ GzipCompressionLevel::Numerical(num) => Compression::new(num as u32),
}
}
}
@@ -59,7 +52,6 @@ pub(crate) struct GzipCompression {
/// Data structure to pass compression parameters
#[derive(Debug, Clone, Eq, PartialEq)]
-#[non_exhaustive]
pub(crate) enum CompressionConfig {
Gzip(GzipCompression),
}
@@ -92,18 +84,31 @@ impl CompressionConfig {
#[derive(Debug, Clone, Eq, PartialEq)]
#[non_exhaustive]
pub enum CompressionOption {
+ /// No compression (gzip compression level 0)
GzipNone,
+ /// Fast compression (gzip compression level 1)
GzipFast,
+ /// Fast compression (gzip compression level 9)
GzipBest,
+ /// Gzip compression level 0
GzipLevel0,
+ /// Gzip compression level 1
GzipLevel1,
+ /// Gzip compression level 2
GzipLevel2,
+ /// Gzip compression level 3
GzipLevel3,
+ /// Gzip compression level 4
GzipLevel4,
+ /// Gzip compression level 5
GzipLevel5,
+ /// Gzip compression level 6
GzipLevel6,
+ /// Gzip compression level 7
GzipLevel7,
+ /// Gzip compression level 8
GzipLevel8,
+ /// Gzip compression level 9
GzipLevel9,
}
diff --git a/tracing-appender/src/rolling.rs b/tracing-appender/src/rolling/mod.rs
similarity index 95%
rename from tracing-appender/src/rolling.rs
rename to tracing-appender/src/rolling/mod.rs
index 6b268afdd5..3596e0b342 100644
--- a/tracing-appender/src/rolling.rs
+++ b/tracing-appender/src/rolling/mod.rs
@@ -26,9 +26,10 @@
//! let file_appender = RollingFileAppender::new(Rotation::HOURLY, "/some/directory", "prefix.log");
//! # }
//! ```
-use crate::builder::RollingFileAppenderBuilder;
+mod builder;
+pub use crate::rolling::builder::RollingFileAppenderBuilder;
#[cfg(feature = "compression_gzip")]
-use crate::compression::CompressionConfig;
+use crate::rolling::compression::CompressionConfig;
use crate::sync::{RwLock, RwLockReadGuard};
use crate::writer::WriterChannel;
use std::{
@@ -40,6 +41,9 @@ use std::{
};
use time::{format_description, Duration, OffsetDateTime, Time};
+#[cfg(feature = "compression_gzip")]
+pub mod compression;
+
/// A file appender with the ability to rotate log files at a fixed schedule.
///
/// `RollingFileAppender` implements the [`std:io::Write` trait][write] and will
@@ -103,12 +107,12 @@ pub struct RollingWriter<'a>(RwLockReadGuard<'a, WriterChannel>);
#[derive(Debug)]
pub(crate) struct Inner {
- pub(crate) log_directory: String,
- pub(crate) log_filename_prefix: String,
- pub(crate) rotation: Rotation,
- pub(crate) next_date: AtomicUsize,
+ log_directory: String,
+ log_filename_prefix: String,
+ rotation: Rotation,
+ next_date: AtomicUsize,
#[cfg(feature = "compression_gzip")]
- pub(crate) compression: Option,
+ compression: Option,
}
// === impl RollingFileAppender ===
@@ -477,7 +481,6 @@ impl io::Write for RollingWriter<'_> {
// === impl Inner ===
impl Inner {
- #[cfg(feature = "compression_gzip")]
fn refresh_writer(&self, now: OffsetDateTime, file: &mut WriterChannel) {
debug_assert!(self.should_rollover(now));
@@ -485,26 +488,13 @@ impl Inner {
.rotation
.join_date(&self.log_filename_prefix, &now, false);
- let writer = if let Some(compression) = self.compression.clone() {
- WriterChannel::new_with_compression(&self.log_directory, &filename, compression)
- } else {
- WriterChannel::new_without_compression(&self.log_directory, &filename)
- };
+ #[cfg(feature = "compression_gzip")]
+ let writer = WriterChannel::new(&self.log_directory, &filename, self.compression.clone());
- Self::refresh_writer_channel(file, writer);
- }
+ #[cfg(not(feature = "compression_gzip"))]
+ let writer = WriterChannel::new(&self.log_directory, &filename);
- #[cfg(not(feature = "compression_gzip"))]
- fn refresh_writer(&self, now: OffsetDateTime, file: &mut WriterChannel) {
- debug_assert!(self.should_rollover(now));
-
- let filename = self
- .rotation
- .join_date(&self.log_filename_prefix, &now, false);
-
- let writer = WriterChannel::new_without_compression(&self.log_directory, &filename);
-
- Self::refresh_writer_channel(file, writer)
+ Self::refresh_writer_channel(file, writer);
}
fn refresh_writer_channel(file: &mut WriterChannel, writer: io::Result) {
diff --git a/tracing-appender/src/writer.rs b/tracing-appender/src/writer.rs
index a586f08a98..da303b1fb7 100644
--- a/tracing-appender/src/writer.rs
+++ b/tracing-appender/src/writer.rs
@@ -4,17 +4,15 @@ use std::io;
#[cfg(feature = "compression_gzip")]
use {
- crate::compression::CompressionConfig,
- flate2::write::GzEncoder,
- std::io::BufWriter,
- std::sync::{Arc, RwLock},
+ crate::rolling::compression::CompressionConfig, flate2::write::GzEncoder, std::io::BufWriter,
+ std::sync::Mutex,
};
#[cfg(feature = "compression_gzip")]
#[derive(Debug)]
pub(crate) struct CompressedGzip {
compression: CompressionConfig,
- buffer: Arc>>>>,
+ buffer: Mutex>>>,
}
#[derive(Debug)]
@@ -29,7 +27,7 @@ impl WriterChannel {
pub(crate) fn new(
directory: &str,
filename: &str,
- #[cfg(feature = "compression_gzip")] compression: Option,
+ compression: Option,
) -> io::Result {
if let Some(compression) = compression {
Self::new_with_compression(directory, filename, compression)
@@ -60,7 +58,7 @@ impl WriterChannel {
let writer = BufWriter::new(gzfile);
let compressed_gz = CompressedGzip {
compression: compression.clone(),
- buffer: Arc::new(RwLock::new(writer)),
+ buffer: Mutex::new(writer),
};
Ok(WriterChannel::CompressedFileGzip(compressed_gz))
}
@@ -72,7 +70,7 @@ impl io::Write for WriterChannel {
WriterChannel::File(f) => f.write(buf),
#[cfg(feature = "compression_gzip")]
WriterChannel::CompressedFileGzip(gz) => {
- let mut buffer = gz.buffer.write().unwrap();
+ let mut buffer = gz.buffer.lock().unwrap();
buffer.write(buf)
}
}
@@ -83,7 +81,7 @@ impl io::Write for WriterChannel {
WriterChannel::File(f) => f.flush(),
#[cfg(feature = "compression_gzip")]
WriterChannel::CompressedFileGzip(gz) => {
- let mut buffer = gz.buffer.write().unwrap();
+ let mut buffer = gz.buffer.lock().unwrap();
buffer.flush()
}
}
@@ -96,7 +94,7 @@ impl io::Write for &WriterChannel {
WriterChannel::File(f) => (&*f).write(buf),
#[cfg(feature = "compression_gzip")]
WriterChannel::CompressedFileGzip(gz) => {
- let mut buffer = gz.buffer.write().unwrap();
+ let mut buffer = gz.buffer.lock().unwrap();
buffer.write(buf)
}
}
@@ -107,7 +105,7 @@ impl io::Write for &WriterChannel {
WriterChannel::File(f) => (&*f).flush(),
#[cfg(feature = "compression_gzip")]
WriterChannel::CompressedFileGzip(gz) => {
- let mut buffer = gz.buffer.write().unwrap();
+ let mut buffer = gz.buffer.lock().unwrap();
buffer.flush()
}
}
From 5d696b674e4eec6c599b09f5a5b5fbfd00d23e79 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Mon, 3 Jan 2022 10:17:38 +0100
Subject: [PATCH 14/22] Clean up file extension
---
tracing-appender/src/rolling/builder.rs | 47 ++++++++++++++++++---
tracing-appender/src/rolling/compression.rs | 13 ++++++
tracing-appender/src/rolling/mod.rs | 46 ++++++++++----------
tracing-appender/src/writer.rs | 8 ++++
4 files changed, 84 insertions(+), 30 deletions(-)
diff --git a/tracing-appender/src/rolling/builder.rs b/tracing-appender/src/rolling/builder.rs
index dcf361a5fa..270ef80bdd 100644
--- a/tracing-appender/src/rolling/builder.rs
+++ b/tracing-appender/src/rolling/builder.rs
@@ -81,17 +81,42 @@ impl RollingFileAppenderBuilder {
self
}
+ pub(crate) fn get_extension(&self) -> Option {
+ #[cfg(feature = "compression_gzip")]
+ if let Some(compression) = self.compression.clone() {
+ compression.extension().map(|v| v.to_string())
+ } else {
+ None
+ }
+
+ #[cfg(not(feature = "compression_gzip"))]
+ None
+ }
+
/// Builds an instance of `RollingFileAppender` using previously defined attributes.
pub fn build(self) -> RollingFileAppender {
let now = OffsetDateTime::now_utc();
- let rotation = self.rotation.unwrap_or(Rotation::NEVER);
- let filename = rotation.join_date(self.log_filename_prefix.as_str(), &now, false);
+ let rotation = self.rotation.clone().unwrap_or(Rotation::NEVER).clone();
+ let extension = self.get_extension();
+ let filename = rotation.join_date(self.log_filename_prefix.as_str(), &now, extension);
let next_date = rotation.next_date(&now);
- let writer = RwLock::new(WriterChannel::File(
- create_writer_file(self.log_directory.as_str(), &filename)
- .expect("failed to create appender"),
- ));
+ #[cfg(not(feature = "compression_gzip"))]
+ let writer = self.create_file_writer(filename.as_str());
+
+ #[cfg(feature = "compression_gzip")]
+ let writer = if let Some(compression) = self.compression.clone() {
+ RwLock::new(
+ WriterChannel::new_with_compression(
+ self.log_directory.as_str(),
+ &filename,
+ compression,
+ )
+ .unwrap(),
+ )
+ } else {
+ self.create_file_writer(filename.as_str())
+ };
let next_date = AtomicUsize::new(
next_date
@@ -104,11 +129,19 @@ impl RollingFileAppenderBuilder {
log_directory: self.log_directory,
log_filename_prefix: self.log_filename_prefix,
next_date,
- rotation: rotation,
+ rotation: rotation.clone(),
#[cfg(feature = "compression_gzip")]
compression: self.compression,
},
writer,
}
}
+
+ fn create_file_writer(&self, filename: &str) -> RwLock {
+ let a = RwLock::new(WriterChannel::File(
+ create_writer_file(self.log_directory.as_str(), &filename)
+ .expect("failed to create appender"),
+ ));
+ a
+ }
}
diff --git a/tracing-appender/src/rolling/compression.rs b/tracing-appender/src/rolling/compression.rs
index 6289977afb..bffcc8915c 100644
--- a/tracing-appender/src/rolling/compression.rs
+++ b/tracing-appender/src/rolling/compression.rs
@@ -65,6 +65,12 @@ impl CompressionConfig {
}
}
}
+
+ pub(crate) fn extension(&self) -> Option<&str> {
+ match self {
+ CompressionConfig::Gzip(_) => Some("gz"),
+ }
+ }
}
/// Defines a compression level for gzip algorithm.
@@ -157,3 +163,10 @@ impl Into for CompressionOption {
}
}
}
+
+#[cfg(test)]
+mod test {
+
+ #[test]
+ fn test_compression() {}
+}
diff --git a/tracing-appender/src/rolling/mod.rs b/tracing-appender/src/rolling/mod.rs
index 3596e0b342..82cfb02d78 100644
--- a/tracing-appender/src/rolling/mod.rs
+++ b/tracing-appender/src/rolling/mod.rs
@@ -418,7 +418,7 @@ impl Rotation {
&self,
filename: &str,
date: &OffsetDateTime,
- compress: bool,
+ extension: Option,
) -> String {
match *self {
Rotation::MINUTELY => {
@@ -428,7 +428,7 @@ impl Rotation {
let date = date
.format(&format)
.expect("Unable to format OffsetDateTime; this is a bug in tracing-appender");
- Rotation::format_params(filename, compress, date)
+ Rotation::format_params(filename, extension, date)
}
Rotation::HOURLY => {
let format = format_description::parse("[year]-[month]-[day]-[hour]")
@@ -437,7 +437,7 @@ impl Rotation {
let date = date
.format(&format)
.expect("Unable to format OffsetDateTime; this is a bug in tracing-appender");
- Rotation::format_params(filename, compress, date)
+ Rotation::format_params(filename, extension, date)
}
Rotation::DAILY => {
let format = format_description::parse("[year]-[month]-[day]")
@@ -445,11 +445,11 @@ impl Rotation {
let date = date
.format(&format)
.expect("Unable to format OffsetDateTime; this is a bug in tracing-appender");
- Rotation::format_params(filename, compress, date)
+ Rotation::format_params(filename, extension, date)
}
Rotation::NEVER => {
- if compress {
- format!("{}.gz", filename.to_string())
+ if let Some(extension) = extension {
+ format!("{}.{}", filename.to_string(), extension)
} else {
filename.to_string()
}
@@ -457,9 +457,9 @@ impl Rotation {
}
}
- fn format_params(filename: &str, compress: bool, date: String) -> String {
- if compress {
- format!("{}.{}.gz", filename, date)
+ fn format_params(filename: &str, extension: Option, date: String) -> String {
+ if let Some(extension) = extension {
+ format!("{}.{}.{}", filename, date, extension)
} else {
format!("{}.{}", filename, date)
}
@@ -486,7 +486,7 @@ impl Inner {
let filename = self
.rotation
- .join_date(&self.log_filename_prefix, &now, false);
+ .join_date(&self.log_filename_prefix, &now, None);
#[cfg(feature = "compression_gzip")]
let writer = WriterChannel::new(&self.log_directory, &filename, self.compression.clone());
@@ -579,7 +579,7 @@ mod test {
appender.flush().expect("Failed to flush!");
}
- fn test_appender(rotation: Rotation, file_prefix: &str, compress: bool) {
+ fn test_appender(rotation: Rotation, file_prefix: &str) {
let directory = tempfile::tempdir().expect("failed to create tempdir");
let mut appender = RollingFileAppender::new(rotation, directory.path(), file_prefix);
@@ -594,22 +594,22 @@ mod test {
#[test]
fn write_minutely_log() {
- test_appender(Rotation::HOURLY, "minutely.log", false);
+ test_appender(Rotation::HOURLY, "minutely.log");
}
#[test]
fn write_hourly_log() {
- test_appender(Rotation::HOURLY, "hourly.log", false);
+ test_appender(Rotation::HOURLY, "hourly.log");
}
#[test]
fn write_daily_log() {
- test_appender(Rotation::DAILY, "daily.log", false);
+ test_appender(Rotation::DAILY, "daily.log");
}
#[test]
fn write_never_log() {
- test_appender(Rotation::NEVER, "never.log", false);
+ test_appender(Rotation::NEVER, "never.log");
}
#[test]
@@ -655,35 +655,35 @@ mod test {
let now = OffsetDateTime::parse("2020-02-01 10:01:00 +00:00:00", &format).unwrap();
// per-minute
- let path = Rotation::MINUTELY.join_date("app.log", &now, false);
+ let path = Rotation::MINUTELY.join_date("app.log", &now, None);
assert_eq!("app.log.2020-02-01-10-01", path);
// per-hour
- let path = Rotation::HOURLY.join_date("app.log", &now, false);
+ let path = Rotation::HOURLY.join_date("app.log", &now, None);
assert_eq!("app.log.2020-02-01-10", path);
// per-day
- let path = Rotation::DAILY.join_date("app.log", &now, false);
+ let path = Rotation::DAILY.join_date("app.log", &now, None);
assert_eq!("app.log.2020-02-01", path);
// never
- let path = Rotation::NEVER.join_date("app.log", &now, false);
+ let path = Rotation::NEVER.join_date("app.log", &now, None);
assert_eq!("app.log", path);
// per-minute compressed
- let path = Rotation::MINUTELY.join_date("app.log", &now, true);
+ let path = Rotation::MINUTELY.join_date("app.log", &now, Some("gz"));
assert_eq!("app.log.2020-02-01-10-01.gz", path);
// per-hour compressed
- let path = Rotation::HOURLY.join_date("app.log", &now, true);
+ let path = Rotation::HOURLY.join_date("app.log", &now, Some("gz"));
assert_eq!("app.log.2020-02-01-10.gz", path);
// per-day compressed
- let path = Rotation::DAILY.join_date("app.log", &now, true);
+ let path = Rotation::DAILY.join_date("app.log", &now, Some("gz"));
assert_eq!("app.log.2020-02-01.gz", path);
// never compressed
- let path = Rotation::NEVER.join_date("app.log", &now, true);
+ let path = Rotation::NEVER.join_date("app.log", &now, Some("gz"));
assert_eq!("app.log.gz", path)
}
}
diff --git a/tracing-appender/src/writer.rs b/tracing-appender/src/writer.rs
index da303b1fb7..c50c0745ef 100644
--- a/tracing-appender/src/writer.rs
+++ b/tracing-appender/src/writer.rs
@@ -62,6 +62,14 @@ impl WriterChannel {
};
Ok(WriterChannel::CompressedFileGzip(compressed_gz))
}
+
+ pub(crate) fn extension(self) -> Option {
+ match self {
+ WriterChannel::File(_) => None,
+ #[cfg(feature = "compression_gzip")]
+ WriterChannel::CompressedFileGzip(_) => Some("gz".to_string()),
+ }
+ }
}
impl io::Write for WriterChannel {
From 0bc8b537c7d6f54474a04d8d37af7c44def97932 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Mon, 21 Feb 2022 21:34:22 +0100
Subject: [PATCH 15/22] Add tests
---
tracing-appender/src/rolling/builder.rs | 20 +++++-----
tracing-appender/src/rolling/compression.rs | 44 ++++++++++++++++++++-
tracing-appender/src/rolling/mod.rs | 18 ++++-----
tracing-appender/src/writer.rs | 2 +
4 files changed, 65 insertions(+), 19 deletions(-)
diff --git a/tracing-appender/src/rolling/builder.rs b/tracing-appender/src/rolling/builder.rs
index 270ef80bdd..273f5aab21 100644
--- a/tracing-appender/src/rolling/builder.rs
+++ b/tracing-appender/src/rolling/builder.rs
@@ -37,15 +37,17 @@ impl RollingFileAppenderBuilder {
/// Note that `compression` module is enabled by using an optional feature flag
/// `compression_gzip` (for gzip algorithm)
///
- /// # Examples
- /// ```rust
- /// use tracing_appender::builder::RollingFileAppenderBuilder;
- /// use tracing_appender::compression::CompressionOption;
- /// use tracing_appender::rolling::Rotation;
- /// let builder = RollingFileAppenderBuilder::new("/var/tmp", "my-app")
- /// .rotation(Rotation::DAILY)
- /// .compression(CompressionOption::GzipFast);
- /// ```
+ // # Examples
+ // ```rust
+ // # #[cfg(feature = "gzip_compression")] {
+ // use tracing_appender::builder::RollingFileAppenderBuilder;
+ // use tracing_appender::compression::CompressionOption;
+ // use tracing_appender::rolling::Rotation;
+ // let builder = RollingFileAppenderBuilder::new("/var/tmp", "my-app")
+ // .rotation(Rotation::DAILY)
+ // .compression(CompressionOption::GzipFast);
+ // # }
+ // ```
pub fn new(log_directory: impl AsRef, log_filename_prefix: impl AsRef) -> Self {
let log_directory = log_directory
.as_ref()
diff --git a/tracing-appender/src/rolling/compression.rs b/tracing-appender/src/rolling/compression.rs
index bffcc8915c..9097e283f2 100644
--- a/tracing-appender/src/rolling/compression.rs
+++ b/tracing-appender/src/rolling/compression.rs
@@ -66,6 +66,7 @@ impl CompressionConfig {
}
}
+ #[allow(unused)]
pub(crate) fn extension(&self) -> Option<&str> {
match self {
CompressionConfig::Gzip(_) => Some("gz"),
@@ -82,10 +83,12 @@ impl CompressionConfig {
/// - compression level 9 (`CompressionOption::GzipBest` or `CompressionOption::GzipLevel9`)
///
/// ```rust
+/// # #[cfg(feature = "gzip_compression")] {
/// # fn docs() {
/// use tracing_appender::compression::CompressionOption;
/// let compression_level = CompressionOption::GzipBest;
/// # }
+/// # }
/// ```
#[derive(Debug, Clone, Eq, PartialEq)]
#[non_exhaustive]
@@ -166,7 +169,46 @@ impl Into for CompressionOption {
#[cfg(test)]
mod test {
+ use crate::rolling::compression::CompressionOption;
+ use crate::rolling::test::write_to_log;
+ use crate::rolling::{RollingFileAppenderBuilder, Rotation};
+ use flate2::read::GzDecoder;
+ use std::fs;
+ use std::io::Read;
+ use std::path::Path;
+
+ fn find_str_in_compressed_log(dir_path: &Path, expected_value: &str) -> bool {
+ let dir_contents = fs::read_dir(dir_path).expect("Failed to read directory");
+
+ for entry in dir_contents {
+ let path = entry.expect("Expected dir entry").path();
+ let bytes = fs::read(&path).expect("Cannot read bytes from compressed log");
+ let mut decoder = GzDecoder::new(&bytes[..]);
+ let mut s = String::new();
+ let _ = decoder.read_to_string(&mut s);
+ if s.as_str() == expected_value {
+ return true;
+ }
+ }
+
+ false
+ }
#[test]
- fn test_compression() {}
+ fn test_compressed_appender() {
+ let file_prefix = "my-app-compressed-log";
+ let directory = tempfile::tempdir().expect("failed to create tempdir");
+ let mut appender = RollingFileAppenderBuilder::new(directory.path(), file_prefix)
+ .rotation(Rotation::DAILY)
+ .compression(CompressionOption::GzipFast)
+ .build();
+
+ let expected_value = "Hello";
+ write_to_log(&mut appender, expected_value);
+ assert!(find_str_in_compressed_log(directory.path(), expected_value));
+
+ directory
+ .close()
+ .expect("Failed to explicitly close TempDir. TempDir should delete once out of scope.")
+ }
}
diff --git a/tracing-appender/src/rolling/mod.rs b/tracing-appender/src/rolling/mod.rs
index d266681ea7..d3ed747d58 100644
--- a/tracing-appender/src/rolling/mod.rs
+++ b/tracing-appender/src/rolling/mod.rs
@@ -428,7 +428,7 @@ impl Rotation {
let date = date
.format(&format)
.expect("Unable to format OffsetDateTime; this is a bug in tracing-appender");
- Rotation::format_params(filename, extension, date)
+ Rotation::format_params(filename, extension, date.as_str())
}
Rotation::HOURLY => {
let format = format_description::parse("[year]-[month]-[day]-[hour]")
@@ -437,7 +437,7 @@ impl Rotation {
let date = date
.format(&format)
.expect("Unable to format OffsetDateTime; this is a bug in tracing-appender");
- Rotation::format_params(filename, extension, date)
+ Rotation::format_params(filename, extension, date.as_str())
}
Rotation::DAILY => {
let format = format_description::parse("[year]-[month]-[day]")
@@ -445,7 +445,7 @@ impl Rotation {
let date = date
.format(&format)
.expect("Unable to format OffsetDateTime; this is a bug in tracing-appender");
- Rotation::format_params(filename, extension, date)
+ Rotation::format_params(filename, extension, date.as_str())
}
Rotation::NEVER => {
if let Some(extension) = extension {
@@ -457,7 +457,7 @@ impl Rotation {
}
}
- fn format_params(filename: &str, extension: Option, date: String) -> String {
+ fn format_params(filename: &str, extension: Option, date: &str) -> String {
if let Some(extension) = extension {
format!("{}.{}.{}", filename, date, extension)
} else {
@@ -572,7 +572,7 @@ mod test {
false
}
- fn write_to_log(appender: &mut RollingFileAppender, msg: &str) {
+ pub(crate) fn write_to_log(appender: &mut RollingFileAppender, msg: &str) {
appender
.write_all(msg.as_bytes())
.expect("Failed to write to appender");
@@ -671,19 +671,19 @@ mod test {
assert_eq!("app.log", path);
// per-minute compressed
- let path = Rotation::MINUTELY.join_date("app.log", &now, Some("gz"));
+ let path = Rotation::MINUTELY.join_date("app.log", &now, Some("gz".into()));
assert_eq!("app.log.2020-02-01-10-01.gz", path);
// per-hour compressed
- let path = Rotation::HOURLY.join_date("app.log", &now, Some("gz"));
+ let path = Rotation::HOURLY.join_date("app.log", &now, Some("gz".into()));
assert_eq!("app.log.2020-02-01-10.gz", path);
// per-day compressed
- let path = Rotation::DAILY.join_date("app.log", &now, Some("gz"));
+ let path = Rotation::DAILY.join_date("app.log", &now, Some("gz".into()));
assert_eq!("app.log.2020-02-01.gz", path);
// never compressed
- let path = Rotation::NEVER.join_date("app.log", &now, Some("gz"));
+ let path = Rotation::NEVER.join_date("app.log", &now, Some("gz".into()));
assert_eq!("app.log.gz", path)
}
}
diff --git a/tracing-appender/src/writer.rs b/tracing-appender/src/writer.rs
index c50c0745ef..994dd4d55d 100644
--- a/tracing-appender/src/writer.rs
+++ b/tracing-appender/src/writer.rs
@@ -11,6 +11,7 @@ use {
#[cfg(feature = "compression_gzip")]
#[derive(Debug)]
pub(crate) struct CompressedGzip {
+ #[allow(unused)]
compression: CompressionConfig,
buffer: Mutex>>>,
}
@@ -63,6 +64,7 @@ impl WriterChannel {
Ok(WriterChannel::CompressedFileGzip(compressed_gz))
}
+ #[allow(unused)]
pub(crate) fn extension(self) -> Option {
match self {
WriterChannel::File(_) => None,
From eb9803d18a323bcc20313776f1024d0b2d496463 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Wed, 23 Feb 2022 14:11:20 +0100
Subject: [PATCH 16/22] Update tracing-appender/src/rolling/builder.rs
Co-authored-by: Eliza Weisman
---
tracing-appender/src/rolling/builder.rs | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/tracing-appender/src/rolling/builder.rs b/tracing-appender/src/rolling/builder.rs
index 273f5aab21..6b5d424743 100644
--- a/tracing-appender/src/rolling/builder.rs
+++ b/tracing-appender/src/rolling/builder.rs
@@ -15,10 +15,9 @@ use {
use crate::writer::WriterChannel;
-/// Struct for keeping temporary values of `RollingFileAppender`.
+/// A builder for configuring new [`RollingFileAppender`]s.
///
-/// Note that `log_directory` and `log_filename_prefix` are obligatory parameters and should
-/// be passed into the constructor of `RollingFileAppenderBuilder`.
+/// This can be used to configure additional options, such as adding compression.
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct RollingFileAppenderBuilder {
log_directory: String,
From a950404dba6ad1eef4c9bc26fa95d48d7642e386 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Wed, 23 Feb 2022 14:14:42 +0100
Subject: [PATCH 17/22] Update tracing-appender/src/rolling/builder.rs
Co-authored-by: Eliza Weisman
---
tracing-appender/src/rolling/builder.rs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tracing-appender/src/rolling/builder.rs b/tracing-appender/src/rolling/builder.rs
index 6b5d424743..0560bf36b8 100644
--- a/tracing-appender/src/rolling/builder.rs
+++ b/tracing-appender/src/rolling/builder.rs
@@ -51,12 +51,12 @@ impl RollingFileAppenderBuilder {
let log_directory = log_directory
.as_ref()
.to_str()
- .expect("Cannot convert log_directory Path to str")
+ .expect("`log_directory` must not contain invalid UTF-8 characters")
.to_string();
let log_filename_prefix = log_filename_prefix
.as_ref()
.to_str()
- .expect("Cannot convert log_filename_prefix Path to str")
+ .expect("`log_directory` must not contain invalid UTF-8 characters")
.to_string();
RollingFileAppenderBuilder {
log_directory,
From 1748b4ac9b0f80f8b6bc28ab195b1475be486a01 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Wed, 23 Feb 2022 14:15:02 +0100
Subject: [PATCH 18/22] Update tracing-appender/src/rolling/builder.rs
Co-authored-by: Eliza Weisman
---
tracing-appender/src/rolling/builder.rs | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tracing-appender/src/rolling/builder.rs b/tracing-appender/src/rolling/builder.rs
index 0560bf36b8..3957556187 100644
--- a/tracing-appender/src/rolling/builder.rs
+++ b/tracing-appender/src/rolling/builder.rs
@@ -68,7 +68,9 @@ impl RollingFileAppenderBuilder {
}
}
- /// Sets Rotation
+ /// Configures when log files will be rotated.
+ ///
+ /// By default, no rotation will occur.
pub fn rotation(mut self, rotation: Rotation) -> Self {
self.rotation = Some(rotation);
self
From 85dbd742f66e5bb411426d207e4866e58845ac86 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Wed, 23 Feb 2022 14:16:23 +0100
Subject: [PATCH 19/22] Apply suggestions from code review
Co-authored-by: Eliza Weisman
---
tracing-appender/src/rolling/builder.rs | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/tracing-appender/src/rolling/builder.rs b/tracing-appender/src/rolling/builder.rs
index 3957556187..bae7e8cc92 100644
--- a/tracing-appender/src/rolling/builder.rs
+++ b/tracing-appender/src/rolling/builder.rs
@@ -63,7 +63,6 @@ impl RollingFileAppenderBuilder {
log_filename_prefix,
rotation: None,
#[cfg(feature = "compression_gzip")]
- #[cfg_attr(docsrs, doc(cfg(feature = "compression_gzip")))]
compression: None,
}
}
@@ -96,10 +95,10 @@ impl RollingFileAppenderBuilder {
None
}
- /// Builds an instance of `RollingFileAppender` using previously defined attributes.
+ /// Returns a new [`RollingFileAppender`] with the configuration defined by this builder.
pub fn build(self) -> RollingFileAppender {
let now = OffsetDateTime::now_utc();
- let rotation = self.rotation.clone().unwrap_or(Rotation::NEVER).clone();
+ let rotation = self.rotation.cloned().unwrap_or(Rotation::NEVER);
let extension = self.get_extension();
let filename = rotation.join_date(self.log_filename_prefix.as_str(), &now, extension);
let next_date = rotation.next_date(&now);
From 4a1280cf41a17c20386133aec91ccc1f0c1d5e6a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Wed, 23 Feb 2022 14:27:36 +0100
Subject: [PATCH 20/22] Fix tests and apply PR suggestions
---
.vscode/tasks.json | 4 ++++
tracing-appender/src/rolling/builder.rs | 19 +++++++++----------
tracing-appender/src/rolling/compression.rs | 9 ++++++---
tracing-appender/src/rolling/mod.rs | 4 ++--
4 files changed, 21 insertions(+), 15 deletions(-)
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 1ca1d80290..e9867a3446 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -4,6 +4,10 @@
{
"type": "cargo",
"command": "build",
+ "args": [
+ "--features",
+ "compression"
+ ],
"problemMatcher": [
"$rustc"
],
diff --git a/tracing-appender/src/rolling/builder.rs b/tracing-appender/src/rolling/builder.rs
index bae7e8cc92..5551e1ca99 100644
--- a/tracing-appender/src/rolling/builder.rs
+++ b/tracing-appender/src/rolling/builder.rs
@@ -9,17 +9,16 @@ use std::sync::atomic::AtomicUsize;
use time::OffsetDateTime;
#[cfg(feature = "compression_gzip")]
-use {
- crate::rolling::compression::CompressionConfig, crate::rolling::compression::CompressionOption,
-};
+use crate::rolling::compression::{CompressionConfig, CompressionOption};
use crate::writer::WriterChannel;
-/// A builder for configuring new [`RollingFileAppender`]s.
+/// A builder for configuring new [`RollingFileAppender`]s.
///
-/// This can be used to configure additional options, such as adding compression.
-#[derive(Debug, Clone, Eq, PartialEq)]
-pub struct RollingFileAppenderBuilder {
+/// Note that `log_directory` and `log_filename_prefix` are obligatory parameters and should
+/// be passed into the constructor of `RollingFileAppenderBuilder`.
+#[derive(Debug, Clone)]
+pub struct Builder {
log_directory: String,
log_filename_prefix: String,
rotation: Option,
@@ -27,7 +26,7 @@ pub struct RollingFileAppenderBuilder {
compression: Option,
}
-impl RollingFileAppenderBuilder {
+impl Builder {
/// Creates a new `RollingFileAppnderBuilder`
///
/// It was introduced to open up the possibility to use `compression` without
@@ -58,7 +57,7 @@ impl RollingFileAppenderBuilder {
.to_str()
.expect("`log_directory` must not contain invalid UTF-8 characters")
.to_string();
- RollingFileAppenderBuilder {
+ Builder {
log_directory,
log_filename_prefix,
rotation: None,
@@ -98,7 +97,7 @@ impl RollingFileAppenderBuilder {
/// Returns a new [`RollingFileAppender`] with the configuration defined by this builder.
pub fn build(self) -> RollingFileAppender {
let now = OffsetDateTime::now_utc();
- let rotation = self.rotation.cloned().unwrap_or(Rotation::NEVER);
+ let rotation = self.rotation.clone().unwrap_or(Rotation::NEVER);
let extension = self.get_extension();
let filename = rotation.join_date(self.log_filename_prefix.as_str(), &now, extension);
let next_date = rotation.next_date(&now);
diff --git a/tracing-appender/src/rolling/compression.rs b/tracing-appender/src/rolling/compression.rs
index 9097e283f2..0ff288bc24 100644
--- a/tracing-appender/src/rolling/compression.rs
+++ b/tracing-appender/src/rolling/compression.rs
@@ -171,7 +171,7 @@ impl Into for CompressionOption {
mod test {
use crate::rolling::compression::CompressionOption;
use crate::rolling::test::write_to_log;
- use crate::rolling::{RollingFileAppenderBuilder, Rotation};
+ use crate::rolling::{Builder, Rotation};
use flate2::read::GzDecoder;
use std::fs;
use std::io::Read;
@@ -185,7 +185,9 @@ mod test {
let bytes = fs::read(&path).expect("Cannot read bytes from compressed log");
let mut decoder = GzDecoder::new(&bytes[..]);
let mut s = String::new();
- let _ = decoder.read_to_string(&mut s);
+ let r = decoder
+ .read_to_string(&mut s)
+ .expect("Cannot decode compressed log file");
if s.as_str() == expected_value {
return true;
}
@@ -198,13 +200,14 @@ mod test {
fn test_compressed_appender() {
let file_prefix = "my-app-compressed-log";
let directory = tempfile::tempdir().expect("failed to create tempdir");
- let mut appender = RollingFileAppenderBuilder::new(directory.path(), file_prefix)
+ let mut appender = Builder::new(directory.path(), file_prefix)
.rotation(Rotation::DAILY)
.compression(CompressionOption::GzipFast)
.build();
let expected_value = "Hello";
write_to_log(&mut appender, expected_value);
+ drop(appender);
assert!(find_str_in_compressed_log(directory.path(), expected_value));
directory
diff --git a/tracing-appender/src/rolling/mod.rs b/tracing-appender/src/rolling/mod.rs
index d3ed747d58..57c362224a 100644
--- a/tracing-appender/src/rolling/mod.rs
+++ b/tracing-appender/src/rolling/mod.rs
@@ -27,7 +27,7 @@
//! # }
//! ```
mod builder;
-pub use crate::rolling::builder::RollingFileAppenderBuilder;
+pub use crate::rolling::builder::Builder;
#[cfg(feature = "compression_gzip")]
use crate::rolling::compression::CompressionConfig;
use crate::sync::{RwLock, RwLockReadGuard};
@@ -146,7 +146,7 @@ impl RollingFileAppender {
directory: impl AsRef,
file_name_prefix: impl AsRef,
) -> RollingFileAppender {
- RollingFileAppenderBuilder::new(directory, file_name_prefix)
+ Builder::new(directory, file_name_prefix)
.rotation(rotation)
.build()
}
From 5504a9dae374e2c025a55f3662f32ad2f6975d1f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Wed, 23 Feb 2022 14:38:28 +0100
Subject: [PATCH 21/22] Final touches, format, clippy, docs
---
tracing-appender/src/rolling/builder.rs | 56 ++++++++++++++-------
tracing-appender/src/rolling/compression.rs | 2 +-
tracing-appender/src/rolling/mod.rs | 6 +--
3 files changed, 42 insertions(+), 22 deletions(-)
diff --git a/tracing-appender/src/rolling/builder.rs b/tracing-appender/src/rolling/builder.rs
index 5551e1ca99..198e494e81 100644
--- a/tracing-appender/src/rolling/builder.rs
+++ b/tracing-appender/src/rolling/builder.rs
@@ -27,25 +27,45 @@ pub struct Builder {
}
impl Builder {
- /// Creates a new `RollingFileAppnderBuilder`
+ /// Returns a new builder for configuring a [`RollingFileAppender`], with
+ /// the provided log directory and filename prefix.
///
- /// It was introduced to open up the possibility to use `compression` without
- /// breaking the current interface.
+ /// Calling [`build`] on the returned builder will construct a new
+ /// [`RollingFileAppender`] that writes to files in the provided directory.
+ /// By default, log files will never be rotated and compression will not be
+ /// enabled. A rotation policy can be added to the builder using the
+ /// [`rotation`] method. When the "compression" feature flag is enabled,
+ /// compression can be configured using the [`compression`] method.
///
- /// Note that `compression` module is enabled by using an optional feature flag
- /// `compression_gzip` (for gzip algorithm)
+ /// # Panics
///
- // # Examples
- // ```rust
- // # #[cfg(feature = "gzip_compression")] {
- // use tracing_appender::builder::RollingFileAppenderBuilder;
- // use tracing_appender::compression::CompressionOption;
- // use tracing_appender::rolling::Rotation;
- // let builder = RollingFileAppenderBuilder::new("/var/tmp", "my-app")
- // .rotation(Rotation::DAILY)
- // .compression(CompressionOption::GzipFast);
- // # }
- // ```
+ /// This function panics if the provided log directory or log file prefix
+ /// are not valid UTF-8.
+ ///
+ /// # Examples
+ ///
+ /// Building a `RollingFileAppender` with the default configuration:
+ ///
+ /// ```rust
+ /// use tracing_appender::rolling::Builder;
+ /// let appender = Builder::new("/var/tmp", "my-app")
+ /// .build();
+ /// ```
+ ///
+ /// Enabling compression (needs a feature enabled `compression_gzip`):
+ ///
+ /// ```rust
+ /// #[cfg(feature = "compression_gzip")]
+ /// use tracing_appender::{
+ /// rolling::{Builder, Rotation},
+ /// rolling::compression::CompressionOption,
+ /// };
+ /// #[cfg(feature = "compression_gzip")]
+ /// let appender = Builder::new("/var/tmp", "my-app")
+ /// .rotation(Rotation::DAILY)
+ /// .compression(CompressionOption::GzipFast)
+ /// .build();
+ /// ```
pub fn new(log_directory: impl AsRef, log_filename_prefix: impl AsRef) -> Self {
let log_directory = log_directory
.as_ref()
@@ -130,7 +150,7 @@ impl Builder {
log_directory: self.log_directory,
log_filename_prefix: self.log_filename_prefix,
next_date,
- rotation: rotation.clone(),
+ rotation,
#[cfg(feature = "compression_gzip")]
compression: self.compression,
},
@@ -140,7 +160,7 @@ impl Builder {
fn create_file_writer(&self, filename: &str) -> RwLock {
let a = RwLock::new(WriterChannel::File(
- create_writer_file(self.log_directory.as_str(), &filename)
+ create_writer_file(self.log_directory.as_str(), filename)
.expect("failed to create appender"),
));
a
diff --git a/tracing-appender/src/rolling/compression.rs b/tracing-appender/src/rolling/compression.rs
index 0ff288bc24..f85f219e70 100644
--- a/tracing-appender/src/rolling/compression.rs
+++ b/tracing-appender/src/rolling/compression.rs
@@ -185,7 +185,7 @@ mod test {
let bytes = fs::read(&path).expect("Cannot read bytes from compressed log");
let mut decoder = GzDecoder::new(&bytes[..]);
let mut s = String::new();
- let r = decoder
+ decoder
.read_to_string(&mut s)
.expect("Cannot decode compressed log file");
if s.as_str() == expected_value {
diff --git a/tracing-appender/src/rolling/mod.rs b/tracing-appender/src/rolling/mod.rs
index 57c362224a..e247afa438 100644
--- a/tracing-appender/src/rolling/mod.rs
+++ b/tracing-appender/src/rolling/mod.rs
@@ -90,10 +90,10 @@ pub mod compression;
/// [`MakeWriter`]: tracing_subscriber::fmt::writer::MakeWriter
#[derive(Debug)]
pub struct RollingFileAppender {
- pub(crate) state: Inner,
- pub(crate) writer: RwLock,
+ state: Inner,
+ writer: RwLock,
#[cfg(features = "compression")]
- pub(crate) compression: Option,
+ compression: Option,
}
/// A [writer] that writes to a rolling log file.
From 81bfc3267ce992e6334e35459135df98b74521dd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jankiewicz?=
Date: Thu, 12 May 2022 09:42:14 +0200
Subject: [PATCH 22/22] Review fixes
---
tracing-appender/src/rolling/builder.rs | 5 +-
tracing-appender/src/rolling/compression.rs | 91 +++++++++++----------
2 files changed, 49 insertions(+), 47 deletions(-)
diff --git a/tracing-appender/src/rolling/builder.rs b/tracing-appender/src/rolling/builder.rs
index 198e494e81..816a569893 100644
--- a/tracing-appender/src/rolling/builder.rs
+++ b/tracing-appender/src/rolling/builder.rs
@@ -159,10 +159,9 @@ impl Builder {
}
fn create_file_writer(&self, filename: &str) -> RwLock {
- let a = RwLock::new(WriterChannel::File(
+ RwLock::new(WriterChannel::File(
create_writer_file(self.log_directory.as_str(), filename)
.expect("failed to create appender"),
- ));
- a
+ ))
}
}
diff --git a/tracing-appender/src/rolling/compression.rs b/tracing-appender/src/rolling/compression.rs
index f85f219e70..2ba4e09d4b 100644
--- a/tracing-appender/src/rolling/compression.rs
+++ b/tracing-appender/src/rolling/compression.rs
@@ -11,7 +11,7 @@ pub(crate) enum GzipCompressionLevelLiteral {
}
#[derive(Debug, Clone, Eq, PartialEq)]
-#[repr(u32)]
+#[repr(u8)]
pub(crate) enum GzipCompressionLevelNumerical {
Level0 = 0,
Level1 = 1,
@@ -59,10 +59,7 @@ pub(crate) enum CompressionConfig {
impl CompressionConfig {
pub(crate) fn gz_compress_level(&self) -> Compression {
match self {
- CompressionConfig::Gzip(gz) => {
- let level = gz.level.clone().into();
- level
- }
+ CompressionConfig::Gzip(gz) => gz.level.clone().into(),
}
}
@@ -123,46 +120,52 @@ pub enum CompressionOption {
impl Into for CompressionOption {
fn into(self) -> CompressionConfig {
+ let new_gzip_literal = |level| -> CompressionConfig {
+ CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Literal(level),
+ })
+ };
+
+ let new_gzip_numerical = |level| -> CompressionConfig {
+ CompressionConfig::Gzip(GzipCompression {
+ level: GzipCompressionLevel::Numerical(level),
+ })
+ };
+
match self {
- CompressionOption::GzipNone => CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Literal(GzipCompressionLevelLiteral::None),
- }),
- CompressionOption::GzipFast => CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Literal(GzipCompressionLevelLiteral::Fast),
- }),
- CompressionOption::GzipBest => CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Literal(GzipCompressionLevelLiteral::Best),
- }),
- CompressionOption::GzipLevel0 => CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level0),
- }),
- CompressionOption::GzipLevel1 => CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level1),
- }),
- CompressionOption::GzipLevel2 => CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level2),
- }),
- CompressionOption::GzipLevel3 => CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level3),
- }),
- CompressionOption::GzipLevel4 => CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level4),
- }),
- CompressionOption::GzipLevel5 => CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level5),
- }),
- CompressionOption::GzipLevel6 => CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level6),
- }),
- CompressionOption::GzipLevel7 => CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level7),
- }),
- CompressionOption::GzipLevel8 => CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level8),
- }),
- CompressionOption::GzipLevel9 => CompressionConfig::Gzip(GzipCompression {
- level: GzipCompressionLevel::Numerical(GzipCompressionLevelNumerical::Level9),
- }),
+ CompressionOption::GzipNone => new_gzip_literal(GzipCompressionLevelLiteral::None),
+ CompressionOption::GzipFast => new_gzip_literal(GzipCompressionLevelLiteral::Fast),
+ CompressionOption::GzipBest => new_gzip_literal(GzipCompressionLevelLiteral::Best),
+ CompressionOption::GzipLevel0 => {
+ new_gzip_numerical(GzipCompressionLevelNumerical::Level0)
+ }
+ CompressionOption::GzipLevel1 => {
+ new_gzip_numerical(GzipCompressionLevelNumerical::Level1)
+ }
+ CompressionOption::GzipLevel2 => {
+ new_gzip_numerical(GzipCompressionLevelNumerical::Level2)
+ }
+ CompressionOption::GzipLevel3 => {
+ new_gzip_numerical(GzipCompressionLevelNumerical::Level3)
+ }
+ CompressionOption::GzipLevel4 => {
+ new_gzip_numerical(GzipCompressionLevelNumerical::Level4)
+ }
+ CompressionOption::GzipLevel5 => {
+ new_gzip_numerical(GzipCompressionLevelNumerical::Level5)
+ }
+ CompressionOption::GzipLevel6 => {
+ new_gzip_numerical(GzipCompressionLevelNumerical::Level6)
+ }
+ CompressionOption::GzipLevel7 => {
+ new_gzip_numerical(GzipCompressionLevelNumerical::Level7)
+ }
+ CompressionOption::GzipLevel8 => {
+ new_gzip_numerical(GzipCompressionLevelNumerical::Level8)
+ }
+ CompressionOption::GzipLevel9 => {
+ new_gzip_numerical(GzipCompressionLevelNumerical::Level9)
+ }
}
}
}