PENABLECALLBACK 回呼函式 (evntprov.h)
ETW 事件提供者選擇性地定義 EnableCallback 函式以接收設定變更通知。 PENABLECALLBACK類型會定義這個回呼函式的指標。 EnableCallback 是應用程式定義函數名稱的預留位置。
語法
PENABLECALLBACK Penablecallback;
void Penablecallback(
[in] LPCGUID SourceId,
[in] ULONG IsEnabled,
[in] UCHAR Level,
[in] ULONGLONG MatchAnyKeyword,
ULONGLONG MatchAllKeyword,
[in, optional] PEVENT_FILTER_DESCRIPTOR FilterData,
[in, optional] PVOID CallbackContext
)
{...}
參數
[in] SourceId
啟用或停用提供者之呼叫端所指定的 GUID。
此值來自EnableTraceEx的SourceId參數,或傳遞至EnableTraceEx2之ENABLE_TRACE_PARAMETERS的 SourceId欄位。
注意
SourceId是呼叫 EnableTraceEx 或 EnableTraceEx2 API 中指定的會話值。 它可能與會話的 GUID 不一樣。
在通知沒有來源識別碼的數個案例中,SourceId會設定為GUID_Null。 例如,當追蹤會話在提供者啟動之前、提供者停止或追蹤控制器呼叫 EnableTrace API 而不指定 SourceId時,就會發生這種情況。
[in] IsEnabled
指出對應至此通知的 ControlCode。 這個值可以是下列其中一個值:
值 | 意義 |
---|---|
EVENT_CONTROL_CODE_DISABLE_PROVIDER (0) | 沒有會話已啟用提供者。 |
EVENT_CONTROL_CODE_ENABLE_PROVIDER (1) | 一或多個會話已啟用提供者。 |
EVENT_CONTROL_CODE_CAPTURE_STATE (2) | 會話要求提供者記錄其狀態資訊。 提供者通常會藉由寫入包含提供者狀態的事件來回應。 |
注意
IsEnabled的值可能與傳遞給觸發此事件的EnableTrace API 的ControlCode不相同。 例如,如果兩個會話已啟用此提供者,一個會話會呼叫 EnableTraceEx2(..., EVENT_CONTROL_CODE_DISABLE_PROVIDER, ...)
來停用此提供者,提供者會收到已設定 EVENT_CONTROL_CODE_ENABLE_PROVIDER
為 IsEnabled的通知,因為其他會話仍然啟用提供者。
收到 DISABLE_PROVIDER 通知之後,提供者可以停用所有事件來優化其效能。 收到 ENABLE_PROVIDER 通知之後,提供者應該啟用寫入事件。 它也可以藉由錄製 Level、MatchAnyKeyword 和 MatchAllKeyword 篩選的值來優化其效能,然後只撰寫傳遞篩選 (的事件,如 備註 所述) 所述。 收到 CAPTURE_STATE 通知之後,提供者可能會採取任何適當的動作,通常會撰寫描述元件組態或狀態的事件。
提供者應該忽略 IsEnabled 值無法辨識或支援的通知。
[in] Level
值,指定提供者應該寫入之事件的詳細資訊。 當使用控制項程式碼 EVENT_CONTROL_CODE_ENABLE_PROVIDER叫用時,提供者應該記錄 Level 值,而且後續應該略過事件的詳細資訊層級大於記錄 的 Level的事件,亦即,只有當事件寫入時,才應該寫入事件
eventDescriptor.Level <= recorded.Level
通知中的Level是追蹤控制器在呼叫EnableTrace、EnableTraceEx 或 EnableTraceEx2時,使用此事件提供者的 GUID 所指定的層級上限。 換句話說,如果多個會話在不同的詳細資訊層級記錄來自此事件提供者的事件,EnableCallback通知的Level參數將會設定為層級的最高 (最詳細資訊) 。
[in] MatchAnyKeyword
位元遮罩值,指定提供者應該寫入的事件類別。 當使用控制項程式碼 EVENT_CONTROL_CODE_ENABLE_PROVIDER叫用時,提供者應該記錄 MatchAnyKeyword 值,而且後續應該略過事件之關鍵字為非零的事件,而且沒有記錄 MatchAnyKeyword的任何位,亦即,只有在寫入事件時,才應該寫入事件
eventDescriptor.Keyword == 0 || (eventDescriptor.Keyword & recorded.MatchAnyKeyword) != 0
通知中的MatchAnyKeyword是 match-any-keywords 的聯集 (OR) , (針對此事件提供者的 GUID 呼叫中追蹤控制器所指定的旗標) 啟用旗標。 換句話說,如果有多個會話記錄來自具有不同 match-any 關鍵字篩選之事件提供者的事件,EnableCallback通知的MatchAnyKeyword參數將會設定為會話之 match-any-keyword 篩選的位 OR
。
MatchAllKeyword
位元遮罩值,指定提供者應該寫入的事件類別。 當收到控制項程式碼 EVENT_CONTROL_CODE_ENABLE_PROVIDER通知時,提供者應該記錄 MatchAllKeyword 值,而且後續應該略過事件關鍵字為非零的事件,而且沒有記錄的 MatchAllKeyword中的所有位,亦即,只有在寫入事件時,才應該寫入事件
eventDescriptor.Keyword == 0 || (eventDescriptor.Keyword & recorded.MatchAllKeyword) == recorded.MatchAllKeyword
通知中的MatchAllKeyword是此事件提供者 GUID 呼叫中追蹤控制器所指定之 match-all-keywords 的分離 (AND) 。 換句話說,如果有多個會話記錄來自具有不同 match-all-keyword 篩選之事件提供者的事件,EnableCallback通知的MatchAllKeyword參數將會設定為 AND
會話的 match-all-keyword 篩選。
[in, optional] FilterData
具有事件提供者篩選資料的 EVENT_FILTER_DESCRIPTOR 指標。
每個會話只能指定一個篩選。 回呼通知中的篩選描述元會在啟用提供者時,包含每個會話中指定篩選資料的篩選準則。
篩選資料只在回呼內有效。 如果回呼傳回之後需要資料,提供者應該建立資料的本機複本。
[in, optional] CallbackContext
回呼的內容。 這是呼叫EventRegister之事件提供者時所使用的CallbackCoNtext參數值。
傳回值
無
備註
需要設定變更通知的 ETW 事件提供者在透過EventRegister註冊時,應該提供其 EnableCallback實作的指標。 ETW 會在對涉及提供者的追蹤會話進行變更時叫用提供者的 EnableCallback 函式。 例如,當追蹤會話控制器透過 EnableTraceEx2 設定追蹤或透過 ControlTrace停止追蹤時,ETW 會使用產生的更新組態呼叫提供者的 EnableCallback 函式。
注意
大部分的事件提供者都不會直接實作 EnableCallback 。 相反地,大部分的事件提供者都是使用 ETW 架構來實作,以提供自己的 EnableCallback 實作,並包裝 對 EventRegister、 EventWrite和 EventUnregister的呼叫。 例如,您可以 撰寫事件資訊清單 ,然後使用 訊息編譯 程式為事件產生 C/C++ 程式碼,或者您可以使用 TraceLogging 來避免資訊清單的需求。 ETW 架構通常會實作 EnableCallback 函式,以記錄通知的 Level
、 MatchAnyKeyword
和 MatchAllKeyword
值,而架構會自動使用記錄的值來篩選事件。 如果使用者需要自訂通知處理,ETW 架構通常支援叫用使用者提供的回呼。 例如, TraceLoggingProvider.h 允許透過 TraceLoggingRegisterEx指定通知回呼。
重要
提供者的 EnableCallback 函式應該盡可能簡單。 它應該記錄必要的資訊,並快速傳回。 長時間執行的回呼函式可能會導致 ETW 會話控制 API 的延遲,例如 EnableTraceEx2 或 ControlTrace。 回呼函式不得執行任何需要進程載入器鎖定的任何動作,亦即它不得直接或間接呼叫 LoadLibrary 或 FreeLibrary。 回呼函式不得封鎖鎖定。 如果回呼函式封鎖鎖定或叫用任何 ETW 會話控制項 API,例如 StartTrace、 ControlTrace或 EnableTrace,則回呼函式可能會造成死結。
通知回呼可讓事件提供者更有效率地執行,因為提供者可以自行追蹤層級、關鍵字和其他篩選。 藉由追蹤篩選準則,提供者可以有效率地略過未啟用 (的事件,亦即提供者不需要準備事件資料或針對任何追蹤會話不需要的事件呼叫 EventWrite) 。
請注意,提供者的正確作業不需要篩選追蹤:ETW 提供提供者可以使用的 EventEnabled 和 EventProviderEnabled 函式,而 ETW EventWrite API 會以無訊息方式忽略任何停用的事件。 不過,提供者實作的篩選準則追蹤比 呼叫 EventEnabled 或 EventProviderEnabled更有效率。
通知回呼也允許提供者處理來自追蹤會話的「擷取狀態」要求。 從提供者開始錄製事件時,追蹤會話通常會傳送擷取狀態要求。 如果提供者支援擷取狀態,它可能會記錄狀態資訊來回應擷取狀態要求,例如設定資訊或要求之前元件作業的相關摘要統計資料。
ETW 傳遞至回呼的 Level 值是任何執行中的追蹤會話為這個事件提供者指定的最高 (最詳細資訊) 層級值。 例如,如果會話 A 已啟用此提供者的警告 (層級 3) 事件,然後會話 B 會針對重大 (層級 1) 事件啟用提供者,則回呼的 Level 值會是 3,而不是 1。
同樣地, MatchAnyKeyword 和 MatchAllKeyword 值是從啟用事件提供者的所有會話組態計算的複合值。 MatchAnyKeyword 是會話的 EnableFlags/MatchAnyKeyword 設定的 OR。 MatchAllKeyword 是會話之 MatchAllKeyword 設定的 AND。
如果提供者的 EnableCallback 函式已擷取提供者的 Enabled、Level、MatchAnyKeyword 和 MatchAllKeyword 狀態,提供者就可以判斷是否應該使用如下的函式來寫入事件:
BOOL MyProviderEventEnabled(
_In_ const MY_PROVIDER_STATE* pProvider,
_In_ const EVENT_DESCRIPTOR* pEvent)
{
return
pProvider->Enabled &&
pEvent->Level <= pProvider->Level &&
(pEvent->Keyword == 0 || (
(pEvent->Keyword & pProvider->MatchAnyKeyword) != 0 &&
(pEvent->Keyword & pProvider->MatchAllKeyword) == pProvider->MatchAllKeyword
));
}
需求
最低支援的用戶端 | Windows Vista [僅限傳統型應用程式] |
最低支援的伺服器 | Windows Server 2008 [僅限傳統型應用程式] |
目標平台 | Windows |
標頭 | evntprov.h |