emabee / flexi_logger

A flexible logger for rust programs that can write to stderr, stdout, and/or to log files
Apache License 2.0
315 stars 55 forks source link

There is no line number in the log? #141

Closed 107295472 closed 1 year ago

107295472 commented 1 year ago
const TS_USCORE_DASHES_USCORE_DASHES: &str = "_%Y-%m-%d";
let f = DeferredNow::new().format(TS_USCORE_DASHES_USCORE_DASHES).to_string();
let s = FileSpec::default().basename(format!("log{}", f)).directory("logs").use_timestamp(false);
// println!("{}", s);
let _ = Logger::try_with_str("info,error")
    .unwrap()
    .log_to_file(s)
    // .rotate(Criterion::Age(Age::Day), Naming::Numbers, Cleanup::KeepLogFiles(365))
    .append()
    .write_mode(WriteMode::BufferAndFlush)
    .start();
107295472 commented 1 year ago

image

emabee commented 1 year ago

Sorry, not sure what you would want to have. Should every line optionally start with a line number?

The below example realizes a counter of the printed log-call within your own formatting function; this is not really a line number, because the printed log entries can contain line breaks themselves, and file rotation is not considered. On the other hand, doing a real line count would be expensive and quite redundant, since most text editors anyhow show the line number, at least optionally.

use flexi_logger::{DeferredNow, FlexiLoggerError, Logger};
use log::*;
use std::sync::atomic::{AtomicU32, Ordering};

// Produces
//      1 INFO [entry_numbers] first
//      2 WARN [entry_numbers] second
//      3 ERROR [entry_numbers] third
fn main() -> Result<(), FlexiLoggerError> {
    Logger::try_with_str("info")?.format(my_format).start()?;

    info!("first");
    warn!("second");
    error!("third");
    Ok(())
}

pub fn my_format(
    w: &mut dyn std::io::Write,
    _now: &mut DeferredNow,
    record: &Record,
) -> Result<(), std::io::Error> {
    static LINE: AtomicU32 = AtomicU32::new(1);
    write!(
        w,
        "{:>6} {} [{}] {}",
        LINE.fetch_add(1, Ordering::Relaxed),
        record.level(),
        record.module_path().unwrap_or("<unnamed>"),
        record.args()
    )
}