shadowsocks/shadowsocks-rust · error

logging

Error message

logging

What it means

Panic while building the log4rs Config object in init_with_config: the builder chain .build(...) returned Err (e.g. duplicate logger names or an invalid appender/logger setup) and expect('logging') panics. This is the first of the two expect calls, on config construction rather than initialization.

Source

Thrown at src/logging/log4rs.rs:67

    let (l1, l2) = match debug_level {
        0 => (LevelFilter::Info, LevelFilter::Off),
        1 => (LevelFilter::Debug, LevelFilter::Off),
        2 => (LevelFilter::Trace, LevelFilter::Off),
        3 => (LevelFilter::Trace, LevelFilter::Debug),
        _ => (LevelFilter::Off, LevelFilter::Trace),
    };

    let config = match debug_level {
        0..=3 => logging_builder
            .logger(Logger::builder().build(bin_name, l1))
            .logger(Logger::builder().build("shadowsocks_rust", l1))
            .logger(Logger::builder().build("shadowsocks", l1))
            .logger(Logger::builder().build("shadowsocks_service", l1)),
        _ => logging_builder,
    }
    .build(Root::builder().appender("console").build(l2))
    .expect("logging");

    log4rs::init_config(config).expect("logging");
}

View on GitHub (pinned to 8eb0f0a65b)

Solutions

  1. Ensure the programmatically built Config has unique logger and appender names
  2. Print/log the generated config on failure instead of a bare expect
  3. Validate the LogConfig inputs (level, format) before building the log4rs config
  4. Check shadowsocks-rust updates for changes in init_with_config's builder logic

Example fix

// before
.build(Root::builder().appender("console").build(l2))
.expect("logging");
// after
.build(Root::builder().appender("console").build(l2))
.unwrap_or_else(|e| {
    eprintln!("invalid logging config: {}", e);
    std::process::exit(1);
})
Defensive patterns

Strategy: fallback

Validate before calling

// ensure logger/appender names passed into the builder are unique before building
assert_unique(&["shadowsocks_rust", "shadowsocks", "shadowsocks_service"]);

Try / catch

// build() returns Result and init_with_config expects it; wrap init in a fallible helper
let config = builder.build(root).map_err(|e| LoggingInitError(e))?;

Prevention

When it happens

Trigger: init_with_config constructs a Config with appenders/loggers whose names collide or are invalid, causing ConfigBuilder::build to error before log4rs::init_config is reached.

Common situations: Bin-name-derived logger names duplicating the root/other loggers; programmatic LogConfig values producing zero or conflicting appenders; refactors changing logger name strings (shadowsocks_rust, shadowsocks, shadowsocks_service) into collisions.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of shadowsocks/shadowsocks-rust@8eb0f0a65b (2026-09-09). Data as JSON: /api/errors/c8658e63f19951d2. Report an issue: GitHub.