Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Filtering

Control which log messages are processed and displayed.

Overview

Filtering allows you to:

  • Set minimum log levels
  • Filter by module or function
  • Create custom filters
  • Control output per sink

Level Filtering

Global Level

Set minimum level for all sinks:

#![allow(unused)]
fn main() {
use logly::prelude::*;

let logger = Logger::new();

let mut config = LoggerConfig::default();
config.level = Level::Warning; // Only WARNING and above
logger.configure(config);

logger.add_sink(SinkConfig::default())?;

logger.debug("Not shown".to_string())?;
logger.warning("Shown!".to_string())?;
}

Per-Sink Level

Different levels for different sinks:

#![allow(unused)]
fn main() {
use std::path::PathBuf;

// Console: INFO and above
logger.add_sink(SinkConfig {
    level: Some(Level::Info),
    ..Default::default()
})?;

// File: DEBUG and above
logger.add_sink(SinkConfig {
    path: Some(PathBuf::from("debug.log")),
    level: Some(Level::Debug),
    ..Default::default()
})?;

// Errors only
logger.add_sink(SinkConfig {
    path: Some(PathBuf::from("errors.log")),
    level: Some(Level::Error),
    ..Default::default()
})?;
}

Module Filtering

Filter by module name:

#![allow(unused)]
fn main() {
let mut config = LoggerConfig::default();
config.module_filter = Some(vec![
    "myapp::api".to_string(),
    "myapp::database".to_string(),
]);
logger.configure(config);
}

Function Filtering

Filter by function name:

#![allow(unused)]
fn main() {
let mut config = LoggerConfig::default();
config.function_filter = Some(vec![
    "handle_request".to_string(),
    "process_data".to_string(),
]);
logger.configure(config);
}

Level Priorities

Log levels and their priorities:

LevelPriorityDescription
TRACE5Very detailed debugging
DEBUG10Debugging information
INFO20General information
SUCCESS25Success messages
WARNING30Warning messages
ERROR40Error messages
FAIL45Failure messages
CRITICAL50Critical errors

Examples

Development vs Production

#![allow(unused)]
fn main() {
#[cfg(debug_assertions)]
let level = Level::Debug;

#[cfg(not(debug_assertions))]
let level = Level::Info;

let mut config = LoggerConfig::default();
config.level = level;
logger.configure(config);
}

Separate Error Logs

#![allow(unused)]
fn main() {
use std::path::PathBuf;

let logger = Logger::new();

// All logs to main file
logger.add_sink(SinkConfig {
    path: Some(PathBuf::from("app.log")),
    level: Some(Level::Debug),
    ..Default::default()
})?;

// Errors to separate file
logger.add_sink(SinkConfig {
    path: Some(PathBuf::from("errors.log")),
    level: Some(Level::Error),
    ..Default::default()
})?;

logger.debug("Debug message".to_string())?; // Only in app.log
logger.error("Error message".to_string())?; // In both files
}

Dynamic Level Changes

#![allow(unused)]
fn main() {
// Start with INFO
let mut config = LoggerConfig::default();
config.level = Level::Info;
logger.configure(config);

// ... later, enable debug mode
config.level = Level::Debug;
logger.configure(config);
}

Best Practices

  1. Production: Use INFO or WARNING level
  2. Development: Use DEBUG or TRACE level
  3. Errors: Always log ERROR and above
  4. Performance: Higher levels = better performance
  5. Separate files: Use different sinks for different levels

See Also