mullvad / windows-service-rs

Windows services in Rust
Apache License 2.0
525 stars 85 forks source link

Couldn't be able to log to file using tracing or env_logger or fern etc #84

Closed 1dveeran closed 2 years ago

1dveeran commented 2 years ago

I am try to add logging to the windows service.

I tried to integrate tracing, env_logger, fern, log4rs to write logs to file. But none of the logger is useful here.

i am using sample codes from all libraries to add in main.rs file and install the services and start it, where i can able run the service successfully but no log are written. But when i run the service executable without installing, logging is happening.

this is an example for fern logging.

fn main() {
    fern::Dispatch::new()
        // Perform allocation-free log formatting
        .format(|out, message, record| {
            out.finish(format_args!(
                "[{}][{}] {}",
                record.target(),
                record.level(),
                message
            ))
        })
        // Add blanket level filter -
        .level(log::LevelFilter::Debug)
        // - and per-module overrides
        .level_for("hyper", log::LevelFilter::Info)
        // Output to stdout, files, and other Dispatch configurations
        .chain(std::io::stdout())
        .chain(fern::log_file("output.log").unwrap())
        // Apply globally
        .apply().unwrap();
    trace!("Hello from Rust!");
    run(); //Start and run my windows service
    //log4rs::init_file("log4rs.yaml", Default::default()).unwrap();
    info!("MyProgram v0.0.1 starting up!");
    debug!("DEBUG output enabled.");
    trace!("TRACE output enabled.");
    info!(target: "overly-verbose-target", "hey, another library here, we're starting.");
}

pub fn run() {
    // Register generated `ffi_service_main` with the system and start the service, blocking
    // this thread until the service is stopped.
    if let Err(e) =
    service_dispatcher::start(SERVICE_NAME, ffi_service_main)
    {
        log::error!("start_service failed: {:?}", e);
    }
}
faern commented 2 years ago

How does your invocation to define_windows_service! look? Do you do any logging in your service_main? Because your line info!("MyProgram v0.0.1 starting up!"); will be logged after service_main returns. service_dispatcher::start blocks until service_main returns.

1dveeran commented 2 years ago

This is my code

pub fn run() {
    if let Err(e) =
    service_dispatcher::start(SERVICE_NAME, ffi_service_main)
    {
        log::error!("start_service failed: {:?}", e);
    }
}

define_windows_service!(ffi_service_main, my_service_main);

pub fn my_service_main(_arguments: Vec<OsString>) {
    log::info!("Running from main service.");
    if let Err(_e) = run_service() {
        log::debug!("Error occurred: {:?}",_e);
    }
}
faern commented 2 years ago

That's strange. I don't immediately see anything wrong. We use this ourselves with the fern logger and it works fine. Maybe you can look at our code and figure out where the error is?

https://github.com/mullvad/mullvadvpn-app/blob/46e8823158b6e857c8f24b1e7cecf51612f48efd/mullvad-daemon/src/main.rs#L26

https://github.com/mullvad/mullvadvpn-app/blob/46e8823158b6e857c8f24b1e7cecf51612f48efd/mullvad-daemon/src/main.rs#L96

pronebird commented 2 years ago

There is no stdout in windows services from what I recall. Your best option is to log to file in this case or system event log.

The following line is also quite questionable:

fern::log_file("output.log")

Where is this output.log located and what's your working directory for windows service?

If I remember it right, the default working directory is system32 when running a service as admin, so you might be trying to write logs into C:\Windows\system32\output.log which is very unlikely to succeed IMO.

So try specifying a writable path. Once the file is there you can use some unix tools like tail -F <file> to follow the program execution and new log messages.

1dveeran commented 2 years ago

found out a way to log in file, hence closing

faern commented 2 years ago

@1dveeran Could you consider describing how? In case someone else is stuck with the same issue as you and find this thread. Currently the thread might not help them much. So maybe you can share what you did to eventually make it work?