Crate tracelogging

source ·
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 your Provider, 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.
  • As needed, use write_event! to send events to ETW.

  • During component shutdown, unregister the provider, e.g.

    MY_PROVIDER.unregister();

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

Macros

Structs

  • Advanced: Indicates routing and decoding for an event.
  • GUID (UUID). with host-endian in-memory representation (as expected by the ETW APIs).
  • Advanced: Used to indicate the field’s type for raw metadata operations.
  • Indicates the severity of an event. Use Verbose if unsure.
  • Indicates special semantics to be used by the event decoder for grouping and organizing events, e.g. for activities.
  • Data formatting hint that may be used or ignored by decoders.
  • A connection to ETW for writing TraceLogging (manifest-free) events.

Enums

  • Possible configurations under which this crate can be compiled: Windows or Other.

Constants

Type Definitions