freeswitch-log-parser 0.17.1

Parser for FreeSWITCH log files — handles compressed .xz files, multi-line dumps, truncated buffers, and stateful UUID/timestamp tracking
Documentation
//! `fslog tail` — follow the live log, printing each match as it lands.

use std::io::Write;

use freeswitch_log_parser::{LogStream, SessionTracker};

use crate::cli::{build_filter, TailArgs};
use crate::files::{open_tail_reader, resolve_log_path, ReadFailures};
use crate::pager::is_broken_pipe;
use crate::run::RunCtx;

pub fn run(ctx: &RunCtx, args: &TailArgs, out: &mut dyn Write) -> anyhow::Result<()> {
    let filter = build_filter(&args.filter, None, None)?;

    let path = resolve_log_path(&ctx.dir, args.file.as_deref());
    let failures = ReadFailures::default();
    let lines = open_tail_reader(&path, args.lines, ctx.max_line_bytes, &failures)?;

    let printer = args.filter.printer(ctx.color);
    let stream = LogStream::new(lines).unclassified_tracking(args.filter.tracking());
    let mut tracker = SessionTracker::new(stream);

    for enriched in tracker.by_ref() {
        if !filter.matches(&enriched.entry) {
            continue;
        }
        if !args.filter.stats {
            let written = printer
                .print_entry(out, &enriched.entry, enriched.session.as_ref())
                .and_then(|()| out.flush());
            match written {
                Err(e) if is_broken_pipe(&e) => break,
                other => other?,
            }
        }
    }

    // The follower only ends when the file stops being readable, so a run that
    // returns has a reason waiting here.
    failures.check()
}