Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: aravindavk/logwatcher
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: MrCasCode/logwatcher
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Able to merge. These branches can be automatically merged.
  • 4 commits
  • 2 files changed
  • 3 contributors

Commits on Sep 7, 2021

  1. feat: choose where to start, at the beginning/offset/end of the file;…

    … and return the current position of the reader
    dizda committed Sep 7, 2021
    Copy the full SHA
    d872f52 View commit details

Commits on Sep 8, 2021

  1. chore: comments

    dizda committed Sep 8, 2021
    Copy the full SHA
    dcf24a5 View commit details

Commits on Nov 28, 2021

  1. Add refresh time

    MrCasCode committed Nov 28, 2021
    Copy the full SHA
    be7dcc3 View commit details
  2. Merge pull request #1 from MrCasCode/feat-pos

    Feat pos
    MrCasCode authored Nov 28, 2021
    Copy the full SHA
    890d531 View commit details
Showing with 55 additions and 17 deletions.
  1. +49 −11 src/lib.rs
  2. +6 −6 src/main.rs
60 changes: 49 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -6,24 +6,53 @@ use std::io::ErrorKind;
use std::io::SeekFrom;
use std::os::unix::fs::MetadataExt;
use std::path::Path;
use std::str::FromStr;
use std::thread::sleep;
use std::time::Duration;

/// Where shall it starts to print from
#[derive(Clone)]
pub enum StartFrom {
/// The beginning of the file
Beginning,
/// Specify the cursor position offset
Offset(u64),
/// The end of the file, which is the last known position
End,
}

impl FromStr for StartFrom {
type Err = ();

fn from_str(input: &str) -> Result<StartFrom, Self::Err> {
match input {
"start" => Ok(StartFrom::Beginning),
"end" => Ok(StartFrom::End),
_ => Ok(StartFrom::End),
}
}
}

pub enum LogWatcherAction {
None,
SeekToEnd,
}

pub struct LogWatcher {
filename: String,
refresh_preiod: u32,
inode: u64,
pos: u64,
reader: BufReader<File>,
finish: bool,
}

impl LogWatcher {
pub fn register<P: AsRef<Path>>(filename: P) -> Result<LogWatcher, io::Error> {
pub fn register<P: AsRef<Path>>(
filename: P,
starts_from: StartFrom,
refresh_period: u32
) -> Result<LogWatcher, io::Error> {
let f = match File::open(&filename) {
Ok(x) => x,
Err(err) => return Err(err),
@@ -35,20 +64,28 @@ impl LogWatcher {
};

let mut reader = BufReader::new(f);
let pos = metadata.len();
reader.seek(SeekFrom::Start(pos)).unwrap();

let starts_from = match starts_from {
StartFrom::Beginning => 0u64,
StartFrom::Offset(pos) => pos,
StartFrom::End => metadata.len(),
};

reader.seek(SeekFrom::Start(starts_from)).unwrap();

Ok(LogWatcher {
filename: filename.as_ref().to_string_lossy().to_string(),
refresh_preiod: refresh_period,
inode: metadata.ino(),
pos: pos,
reader: reader,
pos: starts_from,
reader,
finish: false,
})
}

fn reopen_if_log_rotated<F: ?Sized>(&mut self, callback: &mut F)
where
F: FnMut(String) -> LogWatcherAction,
F: FnMut(u64, usize, String) -> LogWatcherAction,
{
loop {
match File::open(&self.filename) {
@@ -57,7 +94,7 @@ impl LogWatcher {
let metadata = match f.metadata() {
Ok(m) => m,
Err(_) => {
sleep(Duration::new(1, 0));
sleep(Duration::new(0, self.refresh_preiod * 1000));
continue;
}
};
@@ -70,13 +107,13 @@ impl LogWatcher {
self.pos = 0;
self.inode = metadata.ino();
} else {
sleep(Duration::new(1, 0));
sleep(Duration::new(0, self.refresh_preiod * 1000));
}
break;
}
Err(err) => {
if err.kind() == ErrorKind::NotFound {
sleep(Duration::new(1, 0));
sleep(Duration::new(0, self.refresh_preiod * 1000));
continue;
}
}
@@ -86,17 +123,18 @@ impl LogWatcher {

pub fn watch<F: ?Sized>(&mut self, callback: &mut F)
where
F: FnMut(String) -> LogWatcherAction,
F: FnMut(u64, usize, String) -> LogWatcherAction,
{
loop {
let mut line = String::new();
let resp = self.reader.read_line(&mut line);
match resp {
Ok(len) => {
if len > 0 {
let old_pos = self.pos;
self.pos += len as u64;
self.reader.seek(SeekFrom::Start(self.pos)).unwrap();
match callback(line.replace("\n", "")) {
match callback(old_pos, len, line.replace("\n", "")) {
LogWatcherAction::SeekToEnd => {
println!("SeekToEnd");
self.reader.seek(SeekFrom::End(0)).unwrap();
12 changes: 6 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
extern crate logwatcher;

use logwatcher::{LogWatcher, LogWatcherAction, StartFrom};
use std::env::args;
use std::process::exit;

extern crate logwatcher;
use logwatcher::{LogWatcher, LogWatcherAction};

fn main() {
let filename = match args().nth(1) {
Some(x) => x,
@@ -13,10 +13,10 @@ fn main() {
}
};

let mut log_watcher = LogWatcher::register(filename).unwrap();
let mut log_watcher = LogWatcher::register(filename, StartFrom::End, 50).unwrap();

log_watcher.watch(&mut move |line: String| {
println!("Line {}", line);
log_watcher.watch(&mut move |pos: u64, len: usize, line: String| {
println!("Pos #{}, len {} char, Line: `{}`", pos, len, line);
LogWatcherAction::None
});
}