#events #etw #event-logging #tracing #provider #windows-event #applications

win_etw_tracing

tracing crate提供后端,将事件记录到ETW(Windows事件跟踪)

2个版本

0.1.1 2024年1月12日
0.1.0 2023年4月6日

#102 in 调试

Download history 650/week @ 2024-03-14 31/week @ 2024-03-21 80/week @ 2024-03-28 104/week @ 2024-04-04 119/week @ 2024-04-11 124/week @ 2024-04-18 215/week @ 2024-04-25 140/week @ 2024-05-02 136/week @ 2024-05-09 162/week @ 2024-05-16 149/week @ 2024-05-23 184/week @ 2024-05-30 164/week @ 2024-06-06 142/week @ 2024-06-13 146/week @ 2024-06-20 66/week @ 2024-06-27

543 每月下载量
用于 4 crate

Apache-2.0 OR MIT

96KB
1.5K SLoC

Rust对Windows事件跟踪(ETW)的支持

提供#[trace_logging_provider]宏,允许您定义用于跟踪日志提供程序Windows事件跟踪(ETW)框架。

此宏仅适用于针对Windows的情况。当针对其他平台时,此宏仍然可以工作,但将生成不执行任何操作的代码。

此框架允许应用程序记录结构化事件,而不是文本字符串。ETW分析工具可以可靠地识别事件中的字段,并将它们作为强类型数据处理,而不是文本字符串。

有关如何使用ETW与tracing一起使用的信息,请参阅tracing-etw

如何创建和使用事件提供程序

在ETW中,事件提供程序是生成事件的软件对象。 事件控制器设置事件记录会话,而事件消费者读取和解释事件数据。此crate专注于使应用程序能够创建事件提供程序

添加crate依赖项

将这些依赖项添加到您的Cargo.toml文件中

[dependencies]
win_etw_macros = "0.1.*"
win_etw_provider = "0.1.*"

win_etw_macros包含生成事件代码的过程宏。win_etw_provider包含由win_etw_macros生成的代码调用的库代码。

定义事件提供程序及其事件

将特性定义添加到您的源代码中,并使用 #[trace_logging_provider] 宏进行注释。该 #[trace_logging_provider] 宏消耗特性定义并生成具有相同名称和方法签名的 struct 定义。(特性不能作为普通特性使用。)

#[trace_logging_provider]
pub trait MyAppEvents {}

每个事件提供者 必须 有一个唯一的名称 GUID。 ETW 使用此 GUID 来识别由您的提供者生成的事件。Windows 中包含许多事件提供者,因此能够仅选择由您的应用程序生成的事件非常重要。此 GUID 还被 ETW 内部用于识别事件元数据(字段类型),因此您的 GUID 必须是唯一的。否则,使用相同 GUID 的冲突来源的事件可能会被错误地解释。

指定提供者名称

除非被覆盖,否则 #[trace_logging_provider] 使用您的特性定义的名称作为 ETW 提供者的名称(例如上面示例中的 "MyAppEvents")。要指定不同的名称,使用 #[trace_logging_provider(name = "MyCompany.MyComponent")] 指定名称。

为事件提供者生成 GUID

如果您未指定 guid 参数,#[trace_logging_provider] 宏将生成一个基于名称的 .NET EventSource 兼容的 GUID。生成的 GUID 与以下 PowerShell 代码生成的 GUID 相同:[System.Diagnostics.Tracing.EventSource]::new("MyCompany.MyComponent").Guid。GUID 可通过名为 PROVIDER_GUID 的关联常量从您的 Rust 代码中访问(例如,MyAppEvents::PROVIDER_GUID)。

如果您不希望使用基于名称的 GUID,可以使用类似 uuidgen 的工具(可在 Visual Studio 命令行或 Ubuntu Shell 中获得)生成 GUID,并使用 #[trace_logging_provider(guid = "... your guid here ...")] 指定。

将事件添加到您的提供者

在特性定义中添加方法签名。每个方法签名定义一个 事件类型。每个方法的参数定义事件类型的字段。仅支持有限数量的字段类型(以下列出)。

use win_etw_macros::trace_logging_provider;
#[trace_logging_provider(name = "MyCompany.MyComponent")]
pub trait MyAppEvents {
    fn http_request(client_address: &SockAddr, is_https: bool, status_code: u32, status: &str);
    fn database_connection_created(connection_id: u64, server: &str);
    fn database_connection_closed(connection_id: u64);
    // ...
}

创建事件提供者的实例

在初始化时(在你的 fn main() 等等中),创建事件提供者的一个实例

let my_app_events = MyAppEvents::new();

你的应用程序应只为每个进程创建每个事件提供者的一个实例。也就是说,你应该创建你的事件提供者的一个实例,并在你的进程中共享它。通常,实例存储在静态变量中,使用懒加载/原子赋值。有许多crate和类型支持这种使用模式。

调用事件方法来报告事件

要报告事件,请调用事件提供者上定义的方法之一。该方法将调用ETW来报告事件,但没有保证事件会被存储或转发;如果事件缓冲区资源稀缺,事件可能会丢失。

my_app_events.client_connected(None, &"192.168.0.42:6667".parse(), false, 100, "OK");

请注意,所有生成的事件方法都有一个添加的第一个参数,options: Option<&EventOptions>。此参数允许你覆盖每个事件参数,例如事件级别和事件相关性ID。在大多数情况下,你应该传递 None

支持的字段类型

仅支持有限数量的字段类型。

  • 64位以内的整数原语:i8i16i32i64u8u16u32u64
  • 浮点数原语:f32f64
  • 与架构相关的尺寸:usizeisize
  • 布尔值:bool
  • 所有支持的原语切片:&[u8]&[u16] 等。
  • 支持 Windows FILETIME。类型必须恰好声明为 FILETIME;类型别名或完全限定的路径(例如 winapi::shared::minwindef::FILETIME不会工作。生成代码中的参数类型将是 win_etw_provider::FILETIME,它是一个基于 u64 的新类型。
  • std::time::SystemTime 受支持,但必须恰好声明为 SystemTime;类型别名或完全限定的路径(例如 std::time::SystemTime不会工作
  • SockAddrSockAddrV4SockAddrV6 受支持。它们必须恰好声明,不得使用完全限定的名称或类型别名。

如何捕获和查看事件

有各种工具可以用来捕获和查看ETW事件。最简单的工具是来自Windows SDK的TraceView工具。通常它安装在以下路径:C:\Program Files (x86)\Windows Kits\10\bin\10.0.<xxxxx>.0\x64\traceview.exe,其中<xxxxx>是Windows SDK的版本号。

运行TraceView,然后选择“文件”,然后“创建新的日志会话”。选择“手动输入GUID或哈希名称”并输入您分配给事件提供者的GUID。点击确定。下一个对话框将提示您选择WPP格式信息源;选择自动并点击确定。

此时,TraceView应该正在捕获事件(针对您的分配的GUID)并在实时显示它们,不管哪些进程报告了这些事件。

这些工具也可以用来捕获ETW事件

  • Windows性能记录器 此工具旨在捕获系统级的事件流。对于捕获特定事件提供者的事件来说并不有用。
  • logman 是一个用于管理事件的命令行工具。
  • Tracelog

还有其他工具,例如Windows性能记录器,可以捕获ETW事件。

改进建议

  • 比使用Option<&EventOptions>更好地处理每个事件的覆盖。

参考

贡献

此项目欢迎贡献和建议。大多数贡献需要您同意一份贡献者许可协议(CLA),声明您有权并且实际上确实授予我们使用您贡献的权利。有关详细信息,请访问https://cla.opensource.microsoft.com

当您提交拉取请求时,CLA机器人将自动确定您是否需要提供CLA,并适当装饰PR(例如,状态检查,注释)。只需遵循机器人提供的说明即可。您只需要在整个使用我们CLA的仓库中这样做一次。

此项目已采用Microsoft开源行为准则。有关更多信息,请参阅行为准则FAQ或通过[email protected]联系以获取任何其他问题或评论。

依赖项

~2.9–4MB
~62K SLoC