Skip to content

Commit 97c77e3

Browse files
committed
add test for rotate
1 parent ee2c480 commit 97c77e3

File tree

3 files changed

+92
-57
lines changed

3 files changed

+92
-57
lines changed

src/db/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ impl<S: Storage + Clone> DB for WickDB<S> {
177177
impl<S: Storage + Clone> WickDB<S> {
178178
/// Create a new WickDB
179179
pub fn open_db(mut options: Options, db_name: &'static str, storage: S) -> Result<Self> {
180-
options.initialize(db_name.to_owned(), &storage);
180+
options.initialize(db_name, &storage);
181181
debug!("Open db: '{}'", db_name);
182182
let mut db = DBImpl::new(options, db_name, storage);
183183
let (mut edit, should_save_manifest) = db.recover()?;

src/logger.rs

Lines changed: 87 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,23 @@ use crate::db::filename::{generate_filename, FileType};
1515
use crate::error::Result;
1616
use crate::storage::{File, Storage};
1717

18+
1819
use log::{LevelFilter, Log, Metadata, Record};
1920
use slog::{o, Drain, Level};
2021

2122
use chrono::prelude::*;
2223
use std::sync::Mutex;
24+
2325
/// A `slog` based logger which can be used with `log` crate
2426
///
2527
/// See `slog` at https://github.com/slog-rs/slog
2628
/// See `log` at https://github.com/rust-lang/log
2729
///
2830
29-
fn create_file<S:Storage>(storage:&S,dp_path:&str,timestamp:i64) -> Result<S::F> {
30-
let new_path = generate_filename(dp_path, FileType::OldInfoLog, timestamp as u64);
31-
storage.rename(dp_path, new_path.as_str())?;
32-
storage.create(dp_path)
33-
31+
pub fn create_file<S:Storage>(storage:&S,db_path:&str,timestamp:i64) -> Result<S::F> {
32+
let new_path = generate_filename(db_path, FileType::Log, timestamp as u64);
33+
storage.create(new_path)
34+
3435
}
3536

3637
pub struct Logger {
@@ -49,7 +50,7 @@ impl Logger {
4950
inner: Option<slog::Logger>,
5051
level: LevelFilter,
5152
storage:S,
52-
db_path: String,
53+
db_path: &'static str,
5354
) -> Self {
5455
let inner = match inner {
5556
Some(l) => l,
@@ -62,12 +63,13 @@ impl Logger {
6263
} else {
6364
// Use a file `Log` to record all logs
6465
// TODO: add file rotation
65-
let file = create_file(&storage, db_path.as_str(), Local::now().timestamp()).unwrap();
66-
let file_fn = move|path:String| {create_file(&storage,
66+
//db_path 是generate_filename
67+
let file = create_file(&storage, db_path,Local::now().timestamp()).unwrap();
68+
let file_fn = move |path: String| {create_file(&storage,
6769
path.as_str(),Local::now().timestamp())};
68-
let drain =FileBasedDrain::new(file,db_path.clone(),
70+
let drain =FileBasedDrain::new(file,db_path,
6971
file_fn)
70-
.add_rotator(RotatedFileBySize::new(0));
72+
.add_rotator(RotatedFileBySize::new(1));
7173
let drain = slog_async::Async::new(drain).build().fuse();
7274
slog::Logger::root(drain, o!())
7375
}
@@ -131,46 +133,52 @@ fn log_to_slog_level(level: log::Level) -> Level {
131133
struct FileBasedDrain<F: File> {
132134
inner: Mutex<F>,
133135
rotators: Vec<Box<dyn Rotator>>,
134-
dp_path:String,
136+
db_path:String,
135137
new_file:Box<dyn Send+Fn(String)->Result<F>>
136138
}
137139

138140
impl<F: File> FileBasedDrain<F> {
139-
fn new<H>(f:F,path:String,new_file: H) -> Self
141+
fn new<H>(f:F,path:&str,new_file: H) -> Self
140142
where H:'static+Send+Fn(String)->Result<F>
141143
{
142144
FileBasedDrain {
143-
dp_path: path.clone(),
145+
db_path: path.to_string(),
144146
inner: Mutex::new(f),
145147
rotators: vec![],
146148
new_file:Box::new(new_file)
147149
}
148150
}
149151

152+
150153
fn add_rotator<R: 'static+Rotator>(mut self, rotator: R) -> Self {
151154
if rotator.is_enabled() {
152155
self.rotators.push(Box::new(rotator));
153156
}
154-
for rotator in (&self).rotators.iter() {
157+
for rotator in (&self).rotators.iter() {
155158
rotator.prepare(&*self.inner.lock().unwrap()).unwrap();
156159
}
157160
self
158161
}
159162

160-
fn flush(&self) ->Result<()>{
161-
self.inner.lock().unwrap().flush()?;
162-
let new_file = (self.new_file)(self.dp_path.clone()).unwrap();
163-
164-
let mut old_file = self.inner.lock().unwrap();
165-
std::mem::replace(&mut *old_file, new_file);
163+
fn flush(&self) -> Result<()>{
164+
// use crate::storage::file::FileStorage;
165+
// let storage = FileStorage::default();
166166
for rotator in self.rotators.iter() {
167-
rotator.on_rotate()?;
168-
}
169-
return Ok(());
170-
167+
if rotator.should_rotate() {
168+
// let _ = storage.rename("log/000000.log","log/000000.log");
169+
let new_file = (self.new_file)(self.db_path.clone()).unwrap();
170+
let mut old_file = self.inner.lock().unwrap();
171+
*old_file =new_file;
172+
173+
for rotator in self.rotators.iter() {
174+
rotator.on_rotate();
175+
}
176+
return Ok(());
177+
}
178+
}
179+
self.inner.lock().unwrap().flush()
171180
}
172181
}
173-
174182
impl<F:File> Drain for FileBasedDrain<F> {
175183
type Ok = ();
176184
type Err = slog::Never;
@@ -186,19 +194,17 @@ impl<F:File> Drain for FileBasedDrain<F> {
186194
record.msg(),
187195
values
188196
);
189-
for rotator in self.rotators.iter() {
190-
if rotator.should_rotate() {
191-
self.flush().unwrap();
192-
return Ok(());
193-
}
194-
}
195-
196-
for rotator in self.rotators.iter() {
197-
rotator.on_write(by.as_bytes()).unwrap();
197+
198+
199+
for rotator in self.rotators.iter() {
200+
rotator.on_write(by.as_bytes()).unwrap();
198201
}
199-
// Ignore errors here
200-
let _ = self.inner.lock().unwrap().write(by.as_bytes());
202+
203+
let _f = self.flush().unwrap();
201204

205+
//Ignore errors here
206+
let _ = self.inner.lock().unwrap().write(by.as_bytes());
207+
202208
Ok(())
203209
}
204210
}
@@ -218,7 +224,7 @@ trait Rotator: Send {
218224

219225
fn on_write(&self, buf: &[u8]) -> Result<()>;
220226
// Call by operator, update rotators' state while the operator execute a rotation.
221-
fn on_rotate(&self) -> Result<()>;
227+
fn on_rotate(&self) ;
222228
}
223229

224230
struct RotatedFileBySize {
@@ -253,9 +259,8 @@ impl Rotator for RotatedFileBySize {
253259
Ok(())
254260
}
255261

256-
fn on_rotate(&self) -> Result<()> {
262+
fn on_rotate(&self) {
257263
*self.file_size.lock().unwrap() = 0;
258-
Ok(())
259264
}
260265
}
261266

@@ -264,21 +269,51 @@ mod tests {
264269

265270
use super::*;
266271
use crate::storage::mem::MemStorage;
267-
272+
use crate::storage::file::FileStorage;
273+
use slog::info;
274+
use std::fs;
268275
use std::thread;
269276
use std::time::Duration;
270-
277+
use std::path::Path;
278+
279+
fn file_exists(file: impl AsRef<Path>,storage:FileStorage) -> bool {
280+
storage.exists(file)
281+
}
282+
// #[test]
283+
// fn test_default_logger() {
284+
// let s =MemStorage::default();
285+
// // let s = &'static s;
286+
// let db_path = "test";
287+
// let logger = Logger::new(None, LevelFilter::Debug, s, db_path);
288+
// // Ignore the error if the logger have been set
289+
// let _ = log::set_logger(Box::leak(Box::new(logger)));
290+
// log::set_max_level(LevelFilter::Debug);
291+
// self::info!(,"Hello World");
292+
// // Wait for the async logger print the result
293+
// thread::sleep(Duration::from_millis(100));
294+
// }
295+
271296
#[test]
272-
fn test_default_logger() {
273-
let s =MemStorage::default();
274-
// let s = &'static s;
275-
let db_path = "test";
276-
let logger = Logger::new(None, LevelFilter::Debug, s, db_path.to_string());
277-
// Ignore the error if the logger have been set
278-
let _ = log::set_logger(Box::leak(Box::new(logger)));
279-
log::set_max_level(LevelFilter::Debug);
280-
info!("Hello World");
281-
// Wait for the async logger print the result
282-
thread::sleep(Duration::from_millis(100));
297+
fn test_rotate_by_size() {
298+
let db_path = "log";
299+
300+
let storage = FileStorage::default();
301+
let _= storage.mkdir_all(db_path);
302+
let storage2 = storage.clone();
303+
let file= create_file(&storage,db_path, 0).unwrap();
304+
let new_path = generate_filename(db_path, FileType::Log, 1 );
305+
306+
307+
308+
let file_fn = move |path: String| {create_file(&storage,
309+
path.as_str(), 1)};
310+
311+
let drain =FileBasedDrain::new(file,db_path, file_fn)
312+
.add_rotator(RotatedFileBySize::new(1));
313+
let drain = slog_async::Async::new(drain).build().fuse();
314+
let _log = slog::Logger::root(drain, o!());
315+
self::info!(_log,"Test log file rotated by size");
316+
317+
assert!(file_exists(new_path,FileStorage::default()));
283318
}
284319
}

src/options.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,15 +207,15 @@ impl Options {
207207
/// Initialize Options by limiting ranges of some flags, applying customized Logger and etc.
208208
pub(crate) fn initialize<O: File + 'static, S:Storage<F = O>+Clone+'static>(
209209
&mut self,
210-
db_name: String,
210+
db_name: &'static str,
211211
storage: &S,
212212
) {
213213
self.max_open_files =
214214
Self::clip_range(self.max_open_files, 64 + self.non_table_cache_files, 50000);
215215
self.write_buffer_size = Self::clip_range(self.write_buffer_size, 64 << 10, 1 << 30);
216216
self.max_file_size = Self::clip_range(self.max_file_size, 1 << 20, 1 << 30);
217217
self.block_size = Self::clip_range(self.block_size, 1 << 10, 4 << 20);
218-
self.apply_logger(storage, &db_name);
218+
self.apply_logger(storage, db_name);
219219
if self.block_cache.is_none() {
220220
self.block_cache = Some(Arc::new(LRUCache::new(8 << 20, None)))
221221
}
@@ -225,9 +225,9 @@ impl Options {
225225
}
226226

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

0 commit comments

Comments
 (0)