# winlog [![Build status](https://img.shields.io/gitlab/pipeline/arbitrix/winlog.svg)](https://gitlab.com/arbitrix/winlog/pipelines) [![Latest version](https://img.shields.io/crates/v/winlog.svg)](https://crates.io/crates/winlog) [![Documentation](https://docs.rs/winlog/badge.svg)](https://docs.rs/winlog) [![License](https://img.shields.io/crates/l/winlog.svg)](https://gitlab.com/arbitrix/winlog/blob/master/LICENSE) A simple [Rust log](https://docs.rs/log/latest/log/) backend to send messages to the [Windows event log](https://docs.microsoft.com/en-us/windows/desktop/eventlog/event-logging). ## Features * Writes Rust log messages to the Windows event log using the [RegisterEventSourceW](https://docs.microsoft.com/en-us/windows/desktop/api/Winbase/nf-winbase-registereventsourcew) and [ReportEventW](https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-reporteventw) APIs. * Supports `env_logger` filtering, initialized from RUST_LOG environment variable. (optional) * Provides utility functions to register/unregister your [event source](https://docs.microsoft.com/en-us/windows/desktop/eventlog/event-sources) in the Windows registry. * Embeds a small (120-byte) message resource library containing the necessary log message templates in your executable. * Does not panic. The five Rust log levels are mapped to Windows [event types](https://docs.microsoft.com/en-us/windows/desktop/eventlog/event-types) as follows: | Rust Log Level | Windows Event Type | Windows Event Id | | -------------- | ------------------ | ---------------- | | Error | Error | 1 | | Warn | Warning | 2 | | Info | Informational | 3 | | Debug | Informational | 4 | | Trace | Informational | 5 | ## Requirements * Rust 1.29+ * Windows or MinGW * [Windows, optional] [mc.exe](https://docs.microsoft.com/en-us/windows/desktop/wes/message-compiler--mc-exe-) and [rc.exe](https://docs.microsoft.com/en-us/windows/desktop/menurc/resource-compiler) (only required when `eventmsgs.mc` is changed) * [Windows, optional] PowerShell (used for the end-to-end test) ## Usage ### Cargo.toml Plain winlog: ``` [dependencies] winlog = "*" ``` Or to enable env_logger filtering support: ``` [dependencies] winlog = { version = "0.2.5", features = ["env_logger"] } ``` ### Register log source with Windows Register the log source in the Windows registry: ``` winlog::register("Example Log"); // silently ignores errors // or winlog::try_register("Example Log").unwrap(); ``` This usually requires `Administrator` permission so this is usually done during installation time. If your MSI installer (or similar) registers your event sources you should not call this. ### Log events Without env_logger filtering: ``` winlog::init("Example Log").unwrap(); info!("Hello, Event Log"); trace!("This will be logged too"); ``` Use the winlog backend with env_logger filter enabled: ``` // # export RUST_LOG="info" winlog::init("Example Log").unwrap(); info!("Hello, Event Log"); trace!("This will be filtered out"); ``` ### Deregister log source Deregister the log source: ``` winlog::deregister("Example Log"); // silently ignores errors // or winlog::try_deregister("Example Log").unwrap(); ``` This is usually done during program uninstall. If your MSI installer (or similar) deregisters your event sources you should not call this. ## What's New ### 0.2.6 * Disable unneeded regex features to speed up the build. * Improve error reporting/handling in `build.rs`. ### 0.2.5 * Gitlab CI builds on Windows 10 and Debian/MinGW. * Optional support for env_logger event (enable feature `env_logger`). * Always run `windrc/windrc` on MinGW. * Include linker configuration in `.cargo/config`. ## Building ### Windows ```sh cargo build --release ``` ### MinGW Install MinGW (Ubuntu): ```sh sudo apt install mingw-w64 ``` Install Rust: ```sh rustup target install x86_64-pc-windows-gnu ``` Currently the install from rustup doesn't use the correct linker so you have to add the following to `.cargo/config`: [target.x86_64-pc-windows-gnu] linker = "/usr/bin/x86_64-w64-mingw32-gcc" Build: ```sh cargo build --release ``` ### Internals Artifacts `eventmsgs.lib` and `eventmsgs.rs` are under source control so users don't need to have `mc.exe` and `rc.exe` installed for a standard build. 1. If `build.rs` determines that `eventmsgs.mc` was changed then `build.rs`: * invokes `mc.exe` (which creates `eventmsgs.h`) * invokes `rc.exe` (which creates `eventmsgs.lib`) * creates `eventmsgs.rs` from `eventmsgs.h`. 2. `build.rs` emits linker flags so `eventmsgs.lib` can found. 3. Standard `cargo build` follows. ## Testing The end-to-end test requires 'Full Control' permissions on the `HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Application` registry key. ```cargo test``` Process: 1. Create a unique temporary event source name (`winlog-test-###########`). 2. Register our compiled test executable as ```EventMessageFile``` for the event source in the Windows registry. You can see a new key at `HKLM\SYSTEM\CurrentControlSet\Services\EventLog\Application\winlog-test-###########`. 2. Write some log messages to the event source. 3. Use PowerShell to retrieve the logged messages. 4. Deregister our event source. This removes the `winlog-test-###########` registry key. 5. Assert that the retrieved log messages are correct. ## License Licensed under either of * Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0) * MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT) at your option. ## Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.