Expand description
§TraceLogging-encoded ETW events
The tracelogging
crate provides a simple and efficient way to log
TraceLogging
(manifest-free) events to
ETW
(Event Tracing for Windows). The events can be generated and collected on Windows
Vista or later. The events can be decoded on Windows 10 or later.
This implementation of TraceLogging uses macros to generate event metadata at compile-time, improving runtime performance and minimizing dependencies. To enable compile-time metadata generation, the event schema must be specified at compile-time. For example, event name and field names must be string literals, not variables.
In rare cases, you might not know what events you want to log until runtime. For
example, you might be implementing a middle-layer library providing ETW support to a
dynamic top-layer or a scripting language like JavaScript or Python. In these cases,
you might use the tracelogging_dynamic
crate instead of this crate.
§Overview
-
Use
define_provider!
to create a static symbol for yourProvider
, e.g.define_provider!(MY_PROVIDER, "MyCompany.MyComponent");
-
During component initialization, register the provider, e.g.
unsafe { MY_PROVIDER.register(); }
- Safety:
Provider::register
is unsafe because all providers registered by a DLL must be properly unregistered before the DLL unloads. Since the provider is static, Rust will not automatically drop it. If you are writing an EXE, this is not a safety issue because the process exits before the EXE unloads.
- Safety:
-
As needed, use
write_event!
to send events to ETW. -
During component shutdown, unregister the provider, e.g.
MY_PROVIDER.unregister();
Note that the provider symbol is not pub
so it is not visible outside the module.
If you need to share a provider symbol with multiple modules, define the provider in
the parent module, e.g. in lib.rs
.
§Example
use tracelogging as tlg;
// Define a static variable for the "MyCompany.MyComponent" provider.
tlg::define_provider!(
MY_PROVIDER, // The static symbol to use for this provider.
"MyCompany.MyComponent"); // The provider's name (string literal).
// Register the provider at module initialization. If you don't register (or if
// register fails) then MY_PROVIDER.enabled() will always return false, the
// write_event! macro will be a no-op, and MY_PROVIDER.unregister() will be a no-op.
// Safety: If this is a DLL, you MUST call MY_PROVIDER.unregister() before unload.
unsafe { MY_PROVIDER.register(); }
// As necessary, call write_event! to send events to ETW.
let field1_value = "String Value";
let field2_value = 42u32;
tlg::write_event!(
MY_PROVIDER, // The provider to use for the event.
"MyEventName", // The event's name (string literal).
level(Warning), // Event's severity level.
keyword(0x23), // Event category bits.
str8("Field1", field1_value), // Add a string field to the event.
u32("Field2", &field2_value), // Add an integer field to the event.
);
// Before module unload, unregister the provider.
MY_PROVIDER.unregister();
§Notes
Field value expressions will only be evaluated if the event is enabled, i.e. only if one or more ETW logging sessions are listening to the provider with filters that include the level and keyword of the event.
ETW events are limited in size (event size = headers + metadata + data). Windows will ignore any event that is larger than 64KB and will ignore any event that is larger than the buffer size of the recording session.
Collect the events using Windows SDK tools like
traceview or
tracelog.
Decode the events using Windows SDK tools like
traceview or
tracefmt.
For example, to collect events from a provider that was defined as
define_provider!(MY_PROVIDER, "MyCompany.MyComponent")
:
tracelog -start MyTrace -f MyTraceFile.etl -guid *MyCompany.MyComponent -level 5 -matchanykw 0x23
<run your program>
tracelog -stop MyTrace
tracefmt -o MyTraceData.txt MyTraceFile.etl
Modules§
- changelog
- Release history
Macros§
- define_
provider - Creates a static symbol representing an ETW provider.
- provider_
enabled - Returns true if a
write_event!
macro using the specified PROVIDER_SYMBOL, level, and keyword would be enabled, false if it would be disabled. - win_
filetime_ from_ systemtime - Converts a
std::time::SystemTime
into a WindowsFILETIME
i64
value. (Usually not needed - thesystemtime
field type does this automatically.) - write_
event - Sends an event to ETW via the specified provider.
Structs§
- Channel
- Advanced: Indicates routing and decoding for an event.
- Guid
- GUID (UUID). with host-endian in-memory representation (as expected by the ETW APIs).
- InType
- Advanced: Used to indicate the field’s type for raw metadata operations.
- Level
- Indicates the severity of an event. Use Verbose if unsure.
- Opcode
- Indicates special semantics to be used by the event decoder for grouping and organizing events, e.g. for activities.
- OutType
- Data formatting hint that may be used or ignored by decoders.
- Provider
- A connection to ETW for writing TraceLogging (manifest-free) events.
Enums§
- Native
Implementation - Possible configurations under which this crate can be compiled:
Windows
orOther
.
Constants§
- NATIVE_
IMPLEMENTATION - The configuration under which this crate was compiled:
Windows
,WindowsKernelMode
orOther
.
Type Aliases§
- Provider
Enable Callback - Signature for a custom provider enable callback.