PEVENT_RECORD_CALLBACK回调函数 (evntrace.h)
使用者实现此回调以接收来自跟踪处理会话的事件。
PEVENT_RECORD_CALLBACK类型定义指向此回调函数的指针。 EventRecordCallback 是应用程序定义的函数名称的占位符。
语法
PEVENT_RECORD_CALLBACK PeventRecordCallback;
void PeventRecordCallback(
[in] PEVENT_RECORD EventRecord
)
{...}
参数
[in] EventRecord
指向包含事件信息的 EVENT_RECORD 结构的指针。
返回值
无
备注
若要指定 ETW 调用以传递事件的函数,请设置传递给 OpenTrace 函数的 EVENT_TRACE_LOGFILE 结构的 EventRecordCallback、Context 和 ProcessTraceMode 成员。
- 将 EventRecordCallback 设置为回调函数的地址。
- 将 Context 设置为一个值,该值应包含在提供给回调的每个EVENT_RECORD的 UserContext 字段中。
- 将 ProcessTraceMode 设置为处理跟踪时要使用的标志。 若要使用 EventRecordCallback,必须在 ProcessTraceMode 值中包含PROCESS_TRACE_MODE_EVENT_RECORD。
注意
如果 EventRecordCallback 函数从 ProcessTrace 接收乱码数据,请双检查提供给 OpenTrace 的结构字段EVENT_TRACE_LOGFILE
中指定的ProcessTraceMode
标志。 EVENT_TRACE_LOGFILE
的 EventCallback 和 EventRecordCallback 字段是联合的重叠成员。 ProcessTraceMode
如果字段包含 PROCESS_TRACE_MODE_EVENT_RECORD
标志,ProcessTrace 将使用 EventRecordCallback 函数签名调用回调。 否则, ProcessTrace 将使用 EventCallback 函数签名调用回调。
使用 OpenTrace 创建跟踪处理会话后,调用 ProcessTrace 函数以开始接收事件。
当 ProcessTrace 开始处理跟踪中的事件时,它可能会使用一个或多个综合事件调用回调,这些事件包含有关跟踪 (元数据) 的数据,而不是来自记录的事件的数据。 这些综合事件将 EventHeader.ProviderId 设置为 EventTraceGuid
, EventHeader.EventDescriptor.Opcode 基于合成事件的内容设置。 例如,每个跟踪文件中的第一个事件将是包含 TRACE_LOGFILE_HEADER 信息的 Opcode 0 的合成事件。
收到的所有其他事件都包含特定于提供程序的事件数据。 使用EVENT_RECORD的 EventHeader.ProviderId 和 EventHeader.EventDescriptor 成员来确定收到的事件类型。
- 如果事件来自已知的提供程序,并且你知道数据的布局,则可以使用自己的系统来解码事件。
- 如果 EventHeader.Flags 字段包含
EVENT_HEADER_FLAG_TRACE_MESSAGE
标志,则事件是 WPP 消息。 如果 TMF 或 PDB 文件) (适当的解码信息可用,则可以使用 TdhGetProperty 或 TdhGetWppProperty 对事件进行解码。 - 否则,事件可能是基于 MOF、基于清单或 TraceLogging 事件。 如果提供了适当的解码信息,则可以使用 TdhGetEventInformation 解码事件。
- 如果事件使用基于 MOF 的解码, TdhGetEventInformation 将在系统的 WMI 数据存储中查找事件解码信息。
- 如果事件使用基于清单的解码, TdhGetEventInformation 将在系统注册的清单或由 TdhLoadManifest 或 TdhLoadManifestFromBinary 加载到每个进程解码上下文的清单或二进制文件中查找事件解码信息。
- 如果事件使用基于 TraceLogging 的解码, TdhGetEventInformation 将使用事件内部的解码信息。
在大多数情况下,事件将按其发生顺序传递到回调, (时间戳顺序) 。 但是,在某些情况下,事件可能不会按原始顺序传递。
- 如果跟踪将系统时间用于会话时间戳 (即跟踪会话启动
properties.Wnode.ClientContext
时设置为 2) 并且系统时钟在会话收集事件时向后调整,则某些事件可能会无序传递。 若要避免这种情况,请将 ClientContext 设置为 0 以获取默认时间戳 (QPC 时间) 。 - 如果使用来自不精确时钟的时间戳收集跟踪,则不同 CPU 中时间戳相同的事件可能会无序传递。
当跟踪将系统时间用于会话时间戳(因为系统时间刻度)时,这种情况最常发生。 此问题可以通过在 LogFileMode 标志中使用 启动会话
EVENT_TRACE_NO_PER_PROCESSOR_BUFFERING
来避免,不过这可能会对跟踪性能产生重大负面影响。 从Windows 10开始:系统时间时钟类型使用 GetSystemTimePreciseAsFileTime 来降低出现此问题的可能性。 - 如果跟踪已损坏,是使用不维护文件中预期时间戳规则的低级别 API 生成的,或者在写入事件时使用时间戳替代选项,则某些事件可能会无序传递。
技术详细信息: 事件存储在缓冲区中。 每个缓冲区都分配给一个缓冲区流,通常为每个 CPU 分配一个流。 ProcessTrace 实现假定缓冲区中的所有事件都按时间戳排序,并且每个缓冲区包含的事件在单个时间跨度内不与该缓冲区流中任何其他缓冲区的跨度重叠。 如果不满足这些假设,ProcessTrace可能会无序传递事件。
当实时跟踪收集会话没有关联的跟踪处理会话时,收集的事件将由系统缓冲,直到缓冲区已满。 当跟踪处理会话连接到实时跟踪收集会话时,跟踪处理会话将接收会话的合成事件,然后接收缓冲事件,然后开始接收新生成的实时事件。 如果第二个实时处理会话连接到同一跟踪收集会话,它将接收综合事件,并且新生成的实时事件 (第二个跟踪处理会话不会接收较旧的事件) 。
重要
处理来自实时会话的事件时,如果处理回调花费了太多时间来处理每个事件,并且事件到达速度过快,则会落后。 系统将缓冲事件以防止数据丢失,但这会增加系统资源使用率, (例如内存和磁盘使用率) 。 通过使用会话筛选器 ((例如,每个提供程序) 级别和关键字 (keyword) 筛选器)来避免此问题,以便在回调中提前筛选不需要完全处理的事件,并优化回调以尽快返回以避免阻塞处理线程。
有关解释事件数据的其他详细信息,请参阅 使用事件 和使用 TDH 检索事件数据。
要求
最低受支持的客户端 | Windows Vista [仅限桌面应用] |
最低受支持的服务器 | Windows Server 2008 [仅限桌面应用] |
目标平台 | Windows |
标头 | evntrace.h |