#events #trace-logging #etw #provider #event-logging #tracing #guid

win_etw_macros

使应用程序能够向Windows事件跟踪(ETW)报告事件

8个版本

0.1.9 2024年2月6日
0.1.8 2023年5月12日
0.1.7 2023年4月6日
0.1.6 2023年3月30日
0.1.0 2020年5月21日

#555过程宏

Download history 22/week @ 2024-03-13 7/week @ 2024-03-20 10/week @ 2024-03-27 49/week @ 2024-04-03 75/week @ 2024-04-10 53/week @ 2024-04-17 149/week @ 2024-04-24 31/week @ 2024-05-01 29/week @ 2024-05-08 35/week @ 2024-05-15 100/week @ 2024-05-22 156/week @ 2024-05-29 89/week @ 2024-06-05 54/week @ 2024-06-12 58/week @ 2024-06-19 166/week @ 2024-06-26

每月391次下载
用于 5 crates

Apache-2.0 OR MIT

125KB
2K SLoC

为Windows事件跟踪(ETW)提供Rust支持

提供 #[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] 宏进行注释。该宏消费特征定义并生成具有相同名称和相同方法签名的 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 开源行为准则。有关更多信息,请参阅 行为准则常见问题解答 或通过 [email protected] 联系我们,提出任何额外的问题或评论。

依赖关系

~2MB
~42K SLoC