Compare commits

..

No commits in common. "3ff858cef9dd50a2ac9a6715f5a62c7e64d2b39a" and "d5d7288938c5364cddb311c8920e33523d3f0db2" have entirely different histories.

5 changed files with 62 additions and 90 deletions

View file

@ -1,10 +0,0 @@
language: rust
before_script:
- rustup component add rustfmt-preview
script:
- cargo fmt --all -- --check
- cargo build
- cargo test

View file

@ -1,6 +1,6 @@
[package] [package]
name = "logwatcher" name = "logwatcher"
version = "0.1.1" version = "0.1.0"
authors = ["Aravinda VK <mail@aravindavk.in>"] authors = ["Aravinda VK <mail@aravindavk.in>"]
description = "A lib to watch log files for new Changes, just like tail -f" description = "A lib to watch log files for new Changes, just like tail -f"

View file

@ -1,7 +1,5 @@
# Log Watcher # Log Watcher
[![Build Status](https://travis-ci.org/aravindavk/logwatcher.svg?branch=master)](https://travis-ci.org/aravindavk/logwatcher)
A [Rust](https://www.rust-lang.org/) library to watch the log files. A [Rust](https://www.rust-lang.org/) library to watch the log files.
Note: Tested only in Linux Note: Tested only in Linux
@ -14,25 +12,22 @@ Note: Tested only in Linux
First, add the following to your `Cargo.toml` First, add the following to your `Cargo.toml`
```toml
[dependencies] [dependencies]
logwatcher = "0.1" logwatcher = "0.1"
```
Add to your code, Add to your code,
```rust
extern crate logwatcher; extern crate logwatcher;
use logwatcher::LogWatcher; use logwatcher::LogWatcher;
```
Register the logwatcher, pass a closure and watch it! Create a callback function, which accepts String as input
```rust fn parse_line(line: String) {
let mut log_watcher = LogWatcher::register("/var/log/check.log".to_string()).unwrap();
log_watcher.watch(&mut move |line: String| {
println!("Line {}", line); println!("Line {}", line);
LogWatcherAction::None }
});
``` Register the logwatcher and watch it!
let mut log_watcher = LogWatcher::register("/var/log/check.log".to_string()).unwrap();
log_watcher.watch(parse_line);

View file

@ -1,57 +1,46 @@
use std::fs::File; use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::io::BufReader;
use std::io::ErrorKind;
use std::io::SeekFrom; use std::io::SeekFrom;
use std::os::unix::fs::MetadataExt; use std::io::BufReader;
use std::path::Path; use std::io::prelude::*;
use std::io;
use std::thread::sleep; use std::thread::sleep;
use std::time::Duration; use std::time::Duration;
use std::os::unix::fs::MetadataExt;
pub enum LogWatcherAction { use std::io::ErrorKind;
None,
SeekToEnd,
}
pub struct LogWatcher{ pub struct LogWatcher{
filename: String, filename: String,
inode: u64, inode: u64,
pos: u64, pos: u64,
reader: BufReader<File>, reader: BufReader<File>,
finish: bool, finish: bool
} }
impl LogWatcher { impl LogWatcher {
pub fn register<P: AsRef<Path>>(filename: P) -> Result<LogWatcher, io::Error> { pub fn register(filename: String) -> Result<LogWatcher, io::Error> {
let f = match File::open(&filename) { let f = match File::open(filename.clone()) {
Ok(x) => x, Ok(x) => x,
Err(err) => return Err(err), Err(err) => return Err(err)
}; };
let metadata = match f.metadata() { let metadata = match f.metadata() {
Ok(x) => x, Ok(x) => x,
Err(err) => return Err(err), Err(err) => return Err(err)
}; };
let mut reader = BufReader::new(f); let mut reader = BufReader::new(f);
let pos = metadata.len(); let pos = metadata.len();
reader.seek(SeekFrom::Start(pos)).unwrap(); reader.seek(SeekFrom::Start(pos)).unwrap();
Ok(LogWatcher { Ok(LogWatcher{filename: filename,
filename: filename.as_ref().to_string_lossy().to_string(),
inode: metadata.ino(), inode: metadata.ino(),
pos: pos, pos: pos,
reader: reader, reader: reader,
finish: false, finish: false})
})
} }
fn reopen_if_log_rotated<F: ?Sized>(&mut self, callback: &mut F) fn reopen_if_log_rotated(&mut self, callback: fn (line: String)){
where
F: FnMut(String) -> LogWatcherAction,
{
loop { loop {
match File::open(&self.filename) { match File::open(self.filename.clone()) {
Ok(x) => { Ok(x) => {
let f = x; let f = x;
let metadata = match f.metadata() { let metadata = match f.metadata() {
@ -69,11 +58,12 @@ impl LogWatcher {
self.reader = BufReader::new(f); self.reader = BufReader::new(f);
self.pos = 0; self.pos = 0;
self.inode = metadata.ino(); self.inode = metadata.ino();
} else { }
else{
sleep(Duration::new(1, 0)); sleep(Duration::new(1, 0));
} }
break; break;
} },
Err(err) => { Err(err) => {
if err.kind() == ErrorKind::NotFound{ if err.kind() == ErrorKind::NotFound{
sleep(Duration::new(1, 0)); sleep(Duration::new(1, 0));
@ -84,10 +74,7 @@ impl LogWatcher {
} }
} }
pub fn watch<F: ?Sized>(&mut self, callback: &mut F) pub fn watch(&mut self, callback: fn (line: String)) {
where
F: FnMut(String) -> LogWatcherAction,
{
loop{ loop{
let mut line = String::new(); let mut line = String::new();
let resp = self.reader.read_line(&mut line); let resp = self.reader.read_line(&mut line);
@ -96,23 +83,18 @@ impl LogWatcher {
if len > 0{ if len > 0{
self.pos += len as u64; self.pos += len as u64;
self.reader.seek(SeekFrom::Start(self.pos)).unwrap(); self.reader.seek(SeekFrom::Start(self.pos)).unwrap();
match callback(line.replace("\n", "")) { callback(line.replace("\n", ""));
LogWatcherAction::SeekToEnd => {
println!("SeekToEnd");
self.reader.seek(SeekFrom::End(0)).unwrap();
}
LogWatcherAction::None => {}
}
line.clear(); line.clear();
}else { }else {
if self.finish{ if self.finish{
break; break;
} else { }
else{
self.reopen_if_log_rotated(callback); self.reopen_if_log_rotated(callback);
self.reader.seek(SeekFrom::Start(self.pos)).unwrap(); self.reader.seek(SeekFrom::Start(self.pos)).unwrap();
} }
} }
} },
Err(err) => { Err(err) => {
println!("{}", err); println!("{}", err);
} }
@ -120,3 +102,8 @@ impl LogWatcher {
} }
} }
} }
#[test]
fn it_works() {
}

View file

@ -2,7 +2,12 @@ use std::env::args;
use std::process::exit; use std::process::exit;
extern crate logwatcher; extern crate logwatcher;
use logwatcher::{LogWatcher, LogWatcherAction}; use logwatcher::LogWatcher;
fn parse_line(line: String) {
println!("Line {}", line);
}
fn main(){ fn main(){
let filename = match args().nth(1) { let filename = match args().nth(1) {
@ -12,11 +17,6 @@ fn main() {
exit(1); exit(1);
} }
}; };
let mut log_watcher = LogWatcher::register(filename).unwrap(); let mut log_watcher = LogWatcher::register(filename).unwrap();
log_watcher.watch(parse_line);
log_watcher.watch(&mut move |line: String| {
println!("Line {}", line);
LogWatcherAction::None
});
} }