WNODE_HEADER 结构

WNODE_HEADER 结构是 EVENT_TRACE_PROPERTIES 结构的成员。

语法

typedef struct _WNODE_HEADER {
  ULONG BufferSize;
  ULONG ProviderId;
  union {
    ULONG64 HistoricalContext;
    struct {
      ULONG Version;
      ULONG Linkage;
    };
  };
  union {
    HANDLE        KernelHandle;
    LARGE_INTEGER TimeStamp;
  };
  GUID  Guid;
  ULONG ClientContext;
  ULONG Flags;
} WNODE_HEADER, *PWNODE_HEADER;

成员

BufferSize

为事件跟踪会话属性分配的总内存大小(以字节为单位)。 内存大小必须包括 EVENT_TRACE_PROPERTIES 结构的空间,以及内存中结构后面的会话名称字符串和日志文件名称字符串。

ProviderId

保留以供内部使用。

HistoricalContext

输出时,是事件跟踪会话的句柄。

版本

保留以供内部使用。

链接

保留以供内部使用。

KernelHandle

保留以供内部使用。

时间 戳

自 1601 年 1 月 1 日午夜以来,以 100 纳秒的间隔更新此结构中的信息的时间。

Guid

为会话定义的 GUID。

对于 NT 内核记录器会话,将此成员设置为 SystemTraceControlGuid

如果此成员设置为 SystemTraceControlGuidGlobalLoggerGuid,则记录器将是系统记录器。

对于专用记录器会话,请将此成员设置为要为会话启用的提供程序的 GUID。

如果启动的会话不是内核记录器或专用记录器会话,则无需指定会话 GUID。 如果未指定 GUID,ETW 会为你创建一个 GUID。 仅当想要更改与特定会话关联的默认权限时,才需要指定会话 GUID。 有关详细信息,请参阅 EventAccessControl 函数。

不能使用相同的会话 GUID 启动多个会话。

在 Windows Vista 之前: 可以使用同一会话 GUID 启动多个会话。

ClientContext

记录每个事件的时间戳时要使用的时钟解析。 默认值为 QPC) (查询性能计数器。

在 Windows Vista 之前: 默认值为系统时间。

在 Windows 10 版本 1703 之前:任何系统记录器都可以同时使用超过 2 个不同的时钟类型。

从 Windows 10 版本 1703 开始:已删除时钟类型限制。 系统记录器现在可以同时使用这三种时钟类型。

可以指定以下值之一。

含义
1
查询性能计数器 (QPC) 。 QPC 计数器提供不受系统时钟调整影响的高分辨率时间戳。 存储在 事件中的时间戳等效于从 QueryPerformanceCounter API 返回的值。 有关此时间戳的特征的详细信息,请参阅 获取高分辨率时间戳
如果事件速率较高,或者使用者合并来自不同缓冲区的事件,则应使用此分辨率。 在这些情况下,QPC 时间戳的精度和稳定性可以更好地对来自不同缓冲区的事件进行排序。 但是,QPC 时间戳不会反映对系统时钟的更新,例如,如果在跟踪正在进行时由于与 NTP 服务器同步而向前调整系统时钟,则跟踪中的 QPC 时间戳将继续反映时间,就像未发生任何更新一样。
若要确定解决方法,请在使用 事件时使用 TRACE_LOGFILE_HEADERPerfFreq 成员。
若要将事件的时间戳转换为 100-ns 单位,请使用以下转换公式:
scaledTimestamp = eventRecord.EventHeader.TimeStamp.QuadPart * 10000000.0 / logfileHeader.PerfFreq.QuadPart
请注意,在较旧的计算机上,时间戳可能不准确,因为计数器有时会由于硬件错误而向前跳过。
2
系统时间。 系统时间提供一个时间戳,用于跟踪系统时钟的更改,例如,如果在跟踪过程中由于与 NTP 服务器同步而向前调整系统时钟,则跟踪中的系统时间戳也将向前跳转以匹配系统时钟的新设置。
  • 在Windows 10之前的系统上,存储在 事件中的时间戳等效于从 GetSystemTimeAsFileTime API 返回的值。
  • 在 Windows 10 或更高版本上,存储在 事件中的时间戳等效于从 GetSystemTimePreciseAsFileTime API 返回的值。
在Windows 10之前,此时间戳的分辨率是系统时钟计时周期的分辨率,如 TRACE_LOGFILE_HEADER 的 TimerResolution 成员所示。 从 Windows 10 开始,此时间戳的分辨率为性能计数器分辨率,如 TRACE_LOGFILE_HEADER 的 PerfFreq 成员所示。
若要将事件的时间戳转换为 100-ns 单位,请使用以下转换公式:
scaledTimestamp = eventRecord.EventHeader.TimeStamp.QuadPart
请注意,在Windows 10之前在运行 OS 的系统上捕获事件时,如果事件量很大,则系统时间的解析可能不够精细,无法确定事件序列。 在这种情况下,一组事件将具有相同的时间戳,但 ETW 传递事件的顺序可能不正确。 从 Windows 10 开始,时间戳的捕获精度更高,但在捕获跟踪时调整了系统时钟的情况下,仍可能出现一些不稳定的情况。
3
CPU 周期计数器。 CPU 计数器提供最高分辨率的时间戳,并且要检索的资源消耗最少。 但 CPU 计数器不太可靠,不应在生产中使用。 例如,在某些计算机上,除了在某些状态下停止之外,计时器还会由于热和电源的变化而更改频率。
若要确定分辨率,请在使用 事件时使用 TRACE_LOGFILE_HEADERCpuSpeedInMHz 成员。
如果你的硬件不支持此时钟类型,则 ETW 将使用系统时间。
Windows Server 2003、带 SP1 和 Windows XP 的 Windows XP: 不支持此值,它是在 Windows Server 2003 SP1 和 Windows XP SP2 中引入的。

 

Windows 2000:不支持 ClientContext 成员。

标志

必须包含 WNODE_FLAG_TRACED_GUID ,以指示结构包含事件跟踪信息。

备注

在设置任何成员之前,请务必将此结构的内存初始化为零。

若要将 ETW 时间戳转换为 FILETIME,请使用以下过程:

1. 对于 (处理的每个会话或日志文件(即每个 EVENT\_TRACE\_LOGFILE) ),检查 logFile.ProcessTraceMode 字段,以确定是否设置了 PROCESS\_TRACE\_MODE\_RAW\_TIMESTAMP 标志。 默认情况下,不设置此标志。 如果未设置此标志,ETW 运行时会自动将每个 EVENT\_RECORD的时间戳转换为 FILETIME,然后再将 EVENT\_RECORD发送到 EventRecordCallback 函数,因此无需进行其他处理。 仅当使用设置了 PROCESS\_TRACE\_MODE\_RAW\_TIMESTAMP 标志处理跟踪时,才应使用以下步骤。 2. 对于 (处理的每个会话或日志文件,即对于每个 EVENT\_TRACE\_LOGFILE) ,检查 logFile.LogfileHeader.ReservedFlags 字段来确定日志文件的时间戳刻度。 根据 ReservedFlags 的值,执行以下步骤之一来确定剩余步骤中要用于 timeStampScale 的值:
a. 如果 ReservedFlags == 1 (QPC) :DOUBLE timeStampScale = 10000000.0 / logFile.LogfileHeader.PerfFreq.QuadPart;B。 如果 ReservedFlags == 2 (系统时间) :DOUBLE timeStampScale = 1.0;请注意,对于使用系统时间的事件,不需要执行剩余的步骤,因为这些事件已以 FILETIME 单位提供其时间戳。 其余步骤将起作用,但没有必要,并且将引入一个小的舍入错误。 c. 如果 ReservedFlags == 3 (CPU 周期计数器) :DOUBLE timeStampScale = 10.0 / logFile.LogfileHeader.CpuSpeedInMHz;
3. 在对特定日志文件的 EventRecordCallback 函数进行首次调用时, 使用 logFile (EVENT\_TRACE\_LOGFILE) 和 eventRecord (EVENT\_RECORD) 中的数据来计算将用于日志文件中剩余事件的 timeStampBase:INT6 4 timeStampBase = logFile.LogfileHeader.StartTime.QuadPart - (INT64) (timeStampScale \* eventRecord.EventHeader.TimeStamp.QuadPart) ;4. 对于每个 eventRecord (EVENT\_RECORD) , 使用在步骤 2 和 3 中计算的 timeStampScale 和 timeStampBase 值将事件的时间戳转换为 FILETIME:INT64 timeStampInFileTime = timeStampBase + (INT64) (timeStampScale \* eventRecord.EventHeader.TimeStamp.QuadPart) ;

要求

要求
最低受支持的客户端
Windows 2000 专业版 [桌面应用 |UWP 应用]
最低受支持的服务器
Windows 2000 Server [桌面应用 |UWP 应用]
标头
Wmistr.h

另请参阅

ControlCallback

EVENT_TRACE_PROPERTIES

GetTraceLoggerHandle

LARGE_INTEGER