Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
etw-wrapper
Strongly-typed Event Tracing for Windows (ETW) logger generator for Rust.
Point the gen_etw_wrapper! macro at an ETW manifest file to emit a struct with a method for each event.
use ;
gen_etw_wrapper!;
[!NOTE] This crate is Windows-only. Use cfg gates if you need to use this alongside code for other platforms.
Getting started
Add the crate to your Cargo.toml:
[]
= "0.1.0"
The gen_etw_wrapper! macro is available by default through the macro feature. If you only want the runtime pieces, disable default features:
[]
= { = "0.1.0", = false }
See the Manual API section for how to use the helpers directly.
Usage
Generating a provider
Invoke the macro at module scope with the path to your manifest. Paths are resolved relative to the crate's CARGO_MANIFEST_DIR (i.e. the directory containing your Cargo.toml).
This will generate a struct using the default naming convention of [PascalCaseProvideSymbol]Logger. For example the symbol PROVIDER_WIDGETSERVICE becomes ProviderWidgetserviceLogger.
gen_etw_wrapper!;
To pick your own struct name, map the provider's manifest symbol to it with ->:
gen_etw_wrapper!;
If the provider symbol is not a valid Rust identifier, quote it:
gen_etw_wrapper!;
Emitting events
Given this manifest template and event:
the macro generates:
[!IMPORTANT] The macro emits events but does not build or register the provider's message and metadata resource tables. Consumers will need the manifest registered seperately. This can be handled via a combination of
mc.exeandwevtutil.exe.For a simple way of compiling and embedding the resources, use a build-time helper such as
embed-resource.
Type mapping
The macro maps manifest inType values to Rust parameter types as follows:
Manifest inType |
Rust type | Notes |
|---|---|---|
win:Int8 |
i8 |
|
win:UInt8 |
u8 |
|
win:Int16 |
i16 |
|
win:UInt16 |
u16 |
|
win:Int32 |
i32 |
|
win:UInt32, win:HexInt32 |
u32 |
|
win:Int64 |
i64 |
|
win:UInt64, win:HexInt64 |
u64 |
|
win:Float |
f32 |
|
win:Double |
f64 |
|
win:Boolean |
bool |
Encoded as a 32-bit Windows BOOL |
win:Pointer |
usize |
|
win:GUID |
GUID |
|
win:FILETIME |
FILETIME |
|
win:SYSTEMTIME |
SYSTEMTIME |
|
win:UnicodeString |
&str |
Interior NULs become spaces, length="N" produces exactly N units including NUL |
win:AnsiString |
&[u8] |
Caller supplies provider-code-page bytes and the final NUL |
win:AnsiString with outType="win:Utf8/win:Json/win:Xml" |
&str |
Encoded as UTF-8, interior NULs become spaces |
win:Binary |
&[u8] |
length="N" becomes &[u8; N], length="Field" derives that field (see below) |
win:SID |
&field::Sid |
Build from a PSID via unsafe Sid::from_psid, or borrow an owned SidBuf |
Variable-Length Fields
Binary
When a win:Binary field uses length="OtherField", the raw event structure expects to receive the length in that field. The generated method does not expose this field. It is derived internally from the slice's length.
As an example:
generates the method
Strings
For win:UnicodeString length="N", the generated method emits exactly N UTF-16 code units as required by ETW: at most N-1 content units, space padding when needed, and a terminating NUL.
A default win:AnsiString uses the provider's ANSI code page, so its generated parameter remains raw bytes. A fixed-length default ANSI field becomes &[u8; N]; the array must already contain the required padding and final NUL. If the manifest explicitly selects outType="win:Utf8", win:Json, or win:Xml, the generated method accepts &str, performs UTF-8 encoding, and handles fixed-length padding and truncation.
Manual API
If you prefer not to use the macro, you can use the runtime directly. The EtwLogger automatically handles the internal callbacks and ensures that deregistration happens when the logger is dropped. It can be moved and stored freely.
The field module provides converters for passing fields to the write function safely: scalar for any Copy value; str16/to_u16cstring and to_u16cstring_fixed_len for UTF-16 strings; str8/to_cstring and to_cstring_fixed_len for ANSI strings; bytes for binary blobs; and sid for a Sid.
Before logging you can call enabled() to check that your event write won't be a no-op.
use ;
let ctx = register?;
let descriptor = EVENT_DESCRIPTOR ;
if ctx.enabled
License
Licensed under the ISC License.