Skip to content

Commit

Permalink
add file rotation
Browse files Browse the repository at this point in the history
  • Loading branch information
AliceLanniste committed May 6, 2020
1 parent c96a6b4 commit 9a0e1c1
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 47 deletions.
83 changes: 40 additions & 43 deletions src/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,12 @@ use std::sync::Mutex;
///
/// See `slog` at https://github.com/slog-rs/slog
/// See `log` at https://github.com/rust-lang/log
///
///

fn create_file<S:Storage>(storage:&S,dp_path:&str,timestamp:i64) -> Result<S::F> {
let new_path = generate_filename(dp_path, FileType::OldInfoLog, timestamp as u64);
storage.rename(dp_path, new_path.as_str())?;
storage.create(dp_path)

fn create_file<S: Storage>(storage: &S, dp_path: &str, timestamp: i64) -> Result<S::F> {
let new_path = generate_filename(dp_path, FileType::OldInfoLog, timestamp as u64);
storage.rename(dp_path, new_path.as_str())?;
storage.create(dp_path)
}

pub struct Logger {
Expand All @@ -45,10 +44,10 @@ impl Logger {
/// If `inner` is `None`
/// - In dev mode, use a std output
/// - In release mode, use a storage specific file with name `LOG`
pub fn new<S:Storage+Clone+'static>(
pub fn new<S: Storage + Clone + 'static>(
inner: Option<slog::Logger>,
level: LevelFilter,
storage:S,
storage: S,
db_path: String,
) -> Self {
let inner = match inner {
Expand All @@ -62,12 +61,13 @@ impl Logger {
} else {
// Use a file `Log` to record all logs
// TODO: add file rotation
let file = create_file(&storage, db_path.as_str(), Local::now().timestamp()).unwrap();
let file_fn = move|path:String| {create_file(&storage,
path.as_str(),Local::now().timestamp())};
let drain =FileBasedDrain::new(file,db_path.clone(),
file_fn)
.add_rotator(RotatedFileBySize::new(0));
let file =
create_file(&storage, db_path.as_str(), Local::now().timestamp()).unwrap();
let file_fn = move |path: String| {
create_file(&storage, path.as_str(), Local::now().timestamp())
};
let drain = FileBasedDrain::new(file, db_path, file_fn)
.add_rotator(RotatedFileBySize::new(0));
let drain = slog_async::Async::new(drain).build().fuse();
slog::Logger::root(drain, o!())
}
Expand Down Expand Up @@ -128,36 +128,37 @@ fn log_to_slog_level(level: log::Level) -> Level {
}
}

struct FileBasedDrain<F: File> {
struct FileBasedDrain<F: File> {
inner: Mutex<F>,
rotators: Vec<Box<dyn Rotator>>,
dp_path:String,
new_file:Box<dyn Send+Fn(String)->Result<F>>
dp_path: String,
new_file: Box<dyn Send + Fn(String) -> Result<F>>,
}

impl<F: File> FileBasedDrain<F> {
fn new<H>(f:F,path:String,new_file: H) -> Self
where H:'static+Send+Fn(String)->Result<F>
{
impl<F: File> FileBasedDrain<F> {
fn new<H>(f: F, path: String, new_file: H) -> Self
where
H: 'static + Send + Fn(String) -> Result<F>,
{
FileBasedDrain {
dp_path: path.clone(),
dp_path: path,
inner: Mutex::new(f),
rotators: vec![],
new_file:Box::new(new_file)
new_file: Box::new(new_file),
}
}

fn add_rotator<R: 'static+Rotator>(mut self, rotator: R) -> Self {
fn add_rotator<R: 'static + Rotator>(mut self, rotator: R) -> Self {
if rotator.is_enabled() {
self.rotators.push(Box::new(rotator));
}
for rotator in (&self).rotators.iter() {
for rotator in self.rotators.iter() {
rotator.prepare(&*self.inner.lock().unwrap()).unwrap();
}
self
}

fn flush(&self) ->Result<()>{
fn flush(&self) -> Result<()> {
self.inner.lock().unwrap().flush()?;
let new_file = (self.new_file)(self.dp_path.clone()).unwrap();

Expand All @@ -166,12 +167,11 @@ impl<F: File> FileBasedDrain<F> {
for rotator in self.rotators.iter() {
rotator.on_rotate()?;
}
return Ok(());

Ok(())
}
}

impl<F:File> Drain for FileBasedDrain<F> {
impl<F: File> Drain for FileBasedDrain<F> {
type Ok = ();
type Err = slog::Never;

Expand All @@ -186,13 +186,13 @@ impl<F:File> Drain for FileBasedDrain<F> {
record.msg(),
values
);
for rotator in self.rotators.iter() {
if rotator.should_rotate() {
self.flush().unwrap();
return Ok(());
}
}
for rotator in self.rotators.iter() {
if rotator.should_rotate() {
self.flush().unwrap();
return Ok(());
}
}

for rotator in self.rotators.iter() {
rotator.on_write(by.as_bytes()).unwrap();
}
Expand All @@ -203,8 +203,6 @@ impl<F:File> Drain for FileBasedDrain<F> {
}
}



trait Rotator: Send {
/// Check if the option is enabled in configuration.
/// Return true if the `rotator` is valid.
Expand Down Expand Up @@ -239,10 +237,9 @@ impl Rotator for RotatedFileBySize {
fn is_enabled(&self) -> bool {
self.rotation_size != 0
}
fn prepare(&self, file: &dyn File) -> Result<()> {
fn prepare(&self, file: &dyn File) -> Result<()> {
*self.file_size.lock().unwrap() = file.len().unwrap();
Ok(())

}

fn should_rotate(&self) -> bool {
Expand All @@ -266,11 +263,11 @@ mod tests {
use crate::storage::mem::MemStorage;

use std::thread;
use std::time::Duration;
use std::time::Duration;

#[test]
fn test_default_logger() {
let s =MemStorage::default();
let s = MemStorage::default();
// let s = &'static s;
let db_path = "test";
let logger = Logger::new(None, LevelFilter::Debug, s, db_path.to_string());
Expand Down
13 changes: 9 additions & 4 deletions src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,10 @@ impl Options {
}

/// Initialize Options by limiting ranges of some flags, applying customized Logger and etc.
pub(crate) fn initialize<O: File + 'static, S:Storage<F = O>+Clone+'static>(
pub(crate) fn initialize<O: File + 'static, S: Storage<F = O> + Clone + 'static>(
&mut self,
db_name: String,
storage: &S,
storage: &S,
) {
self.max_open_files =
Self::clip_range(self.max_open_files, 64 + self.non_table_cache_files, 50000);
Expand All @@ -225,9 +225,14 @@ impl Options {
}

#[allow(unused_must_use)]
fn apply_logger<S: 'static+Storage+Clone>(&mut self, storage: &S, db_path: &str) {
fn apply_logger<S: 'static + Storage + Clone>(&mut self, storage: &S, db_path: &str) {
let user_logger = std::mem::replace(&mut self.logger, None);
let logger = Logger::new(user_logger, self.logger_level, storage.clone(), db_path.to_string());
let logger = Logger::new(
user_logger,
self.logger_level,
storage.clone(),
db_path.to_string(),
);
let static_logger: &'static dyn Log = Box::leak(Box::new(logger));
log::set_logger(static_logger);
log::set_max_level(self.logger_level);
Expand Down

0 comments on commit 9a0e1c1

Please sign in to comment.