Bagikan melalui


Fungsi EnableTraceEx2 (evntrace.h)

Pengontrol sesi pelacakan memanggil EnableTraceEx2 untuk mengonfigurasi bagaimana penyedia peristiwa ETW mencatat peristiwa ke sesi pelacakan.

Fungsi ini menggantikan fungsi EnableTrace dan EnableTraceEx .

Sintaks

ULONG WMIAPI EnableTraceEx2(
                 CONTROLTRACE_ID          TraceId,
  [in]           LPCGUID                  ProviderId,
  [in]           ULONG                    ControlCode,
  [in]           UCHAR                    Level,
  [in]           ULONGLONG                MatchAnyKeyword,
  [in]           ULONGLONG                MatchAllKeyword,
  [in]           ULONG                    Timeout,
  [in, optional] PENABLE_TRACE_PARAMETERS EnableParameters
);

Parameter

TraceId

[in] ProviderId

ID penyedia (KONTROL GUID) penyedia peristiwa yang ingin Anda konfigurasi.

[in] ControlCode

Anda dapat menentukan salah satu kode kontrol berikut:

Nilai Makna
EVENT_CONTROL_CODE_DISABLE_PROVIDER Perbarui konfigurasi sesi sehingga sesi tidak menerima peristiwa dari penyedia.
EVENT_CONTROL_CODE_ENABLE_PROVIDER Perbarui konfigurasi sesi sehingga sesi menerima peristiwa yang diminta dari penyedia.
EVENT_CONTROL_CODE_CAPTURE_STATE Meminta penyedia mencatat informasi statusnya.

[in] Level

Nilai yang menunjukkan tingkat maksimum peristiwa yang Anda inginkan untuk ditulis oleh penyedia. Penyedia biasanya menulis peristiwa jika tingkat peristiwa kurang dari atau sama dengan nilai ini, selain memenuhi kriteria MatchAnyKeyword dan MatchAllKeyword .

Microsoft mendefinisikan semantik tingkat 1-5 seperti yang ditunjukkan di bawah ini. Nilai yang lebih rendah menunjukkan peristiwa yang lebih parah. Setiap nilai Level memungkinkan tingkat yang ditentukan dan semua tingkat yang lebih parah. Misalnya, jika Anda menentukan TRACE_LEVEL_WARNING, konsumen Anda akan menerima peringatan, kesalahan, dan peristiwa penting.

Nilai Makna
TRACE_LEVEL_CRITICAL (1) Peristiwa keluar atau penghentian abnormal
TRACE_LEVEL_ERROR (2) Peristiwa kesalahan parah
TRACE_LEVEL_WARNING (3) Peristiwa peringatan seperti kegagalan alokasi
TRACE_LEVEL_INFORMATION (4) Peristiwa informasi non-kesalahan
TRACE_LEVEL_VERBOSE (5) Peristiwa diagnostik terperinci

Konstanta TRACE_LEVEL didefinisikan dalam evntrace.h. Konstanta yang WINMETA_LEVEL setara didefinisikan dalam winmeta.h.

[in] MatchAnyKeyword

Bitmask kata kunci 64-bit yang menentukan kategori peristiwa yang Anda inginkan untuk ditulis oleh penyedia. Penyedia biasanya menulis peristiwa jika bit kata kunci peristiwa cocok dengan salah satu bit yang ditetapkan dalam nilai ini atau jika peristiwa tidak memiliki bit kata kunci yang ditetapkan, selain memenuhi kriteria Level dan MatchAllKeyword .

[in] MatchAllKeyword

Bitmask kata kunci 64-bit yang membatasi peristiwa yang Anda inginkan untuk ditulis oleh penyedia. Penyedia biasanya menulis peristiwa jika bit kata kunci peristiwa cocok dengan semua bit yang ditetapkan dalam nilai ini atau jika peristiwa tidak memiliki bit kata kunci yang ditetapkan, selain memenuhi kriteria Level dan MatchAnyKeyword .

Nilai ini sering diatur ke 0.

[in] Timeout

Jika Timeout adalah 0, fungsi ini akan mulai mengonfigurasi penyedia secara asinkron dan akan segera kembali (yaitu akan kembali tanpa menunggu panggilan balik penyedia selesai).

Jika tidak, fungsi ini akan mulai mengonfigurasi penyedia dan kemudian akan mulai menunggu konfigurasi selesai, termasuk menunggu semua panggilan balik penyedia selesai. Jika konfigurasi selesai sebelum batas waktu yang ditentukan, fungsi ini akan mengembalikan ERROR_SUCCESS. Jika tidak, fungsi ini akan mengembalikan ERROR_TIMEOUT.

Untuk menunggu selamanya, atur ke INFINITE.

[in, optional] EnableParameters

Parameter pelacakan yang digunakan untuk mengaktifkan penyedia. Untuk detailnya, lihat ENABLE_TRACE_PARAMETERS.

Menampilkan nilai

Jika fungsi berhasil, nilai yang dikembalikan adalah ERROR_SUCCESS.

Jika fungsi gagal, nilai yang dikembalikan adalah salah satu kode kesalahan sistem. Berikut ini adalah beberapa kesalahan umum dan penyebabnya.

  • ERROR_INVALID_PARAMETER

    Parameter salah.

    Ini dapat terjadi jika salah satu hal berikut ini benar:

    • ProviderId adalah NULL.
    • TraceHandle adalah 0.
  • ERROR_TIMEOUT

    Nilai batas waktu kedaluwarsa sebelum panggilan balik aktifkan selesai. Untuk detailnya, lihat parameter Waktu Habis .

  • ERROR_INVALID_FUNCTION

    Anda tidak dapat memperbarui tingkat ketika penyedia tidak terdaftar.

  • ERROR_NO_SYSTEM_RESOURCES

    Melebihi jumlah sesi pelacakan yang dapat mengaktifkan penyedia.

  • ERROR_ACCESS_DENIED

    Hanya pengguna dengan hak administratif, pengguna dalam Performance Log Users grup, dan layanan yang berjalan sebagai LocalSystem, LocalService, atau NetworkService dapat mengaktifkan penyedia peristiwa ke sesi lintas proses. Untuk memberi pengguna terbatas kemampuan untuk mengaktifkan penyedia peristiwa, tambahkan mereka ke Performance Log Users grup atau lihat EventAccessControl.

    Windows XP dan Windows 2000: Siapa pun dapat mengaktifkan penyedia peristiwa.

Keterangan

Pengontrol pelacakan peristiwa memanggil fungsi ini untuk mengonfigurasi penyedia peristiwa yang menulis peristiwa ke sesi. Misalnya, pengontrol mungkin memanggil fungsi ini untuk mulai mengumpulkan peristiwa dari penyedia, untuk menyesuaikan tingkat atau kata kunci peristiwa yang dikumpulkan dari penyedia, atau berhenti mengumpulkan peristiwa dari penyedia.

Perilaku pengaktifan untuk penyedia bergantung pada API mana yang digunakan penyedia.

  • Penyedia yang menggunakan RegisterTraceGuids (misalnya penyedia yang menggunakan WPP atau MOF berbasis TMF) menggunakan sistem pengaktifan warisan (terkadang disebut "ETW klasik"). Ketika penyedia warisan diaktifkan atau dikonfigurasi ulang untuk sesi, runtime ETW memberi tahu penyedia dan menyediakan akses ke tingkat , 32 bit rendah masker MatchAnyKeyword, dan ID sesi. Penyedia kemudian menggunakan logikanya sendiri untuk memutuskan peristiwa mana yang harus diaktifkan dan mengirim peristiwa tersebut langsung ke sesi yang ditentukan. Data peristiwa yang dikirim ke ETW saat runtime menyertakan GUID dekode peristiwa dan ID pesan tetapi tidak menyertakan GUID kontrol peristiwa, tingkat atau kata kunci. ETW memverifikasi bahwa penyedia memiliki izin yang diperlukan lalu menambahkan data peristiwa ke sesi yang ditentukan.
    • Karena peristiwa dikirim langsung ke sesi tertentu tanpa GUID kontrol, tingkat atau informasi kata kunci, ETW tidak dapat melakukan pemfilteran atau perutean tambahan untuk penyedia yang menggunakan sistem pengaktifan warisan. Setiap peristiwa dapat dirutekan ke tidak lebih dari satu sesi.
  • Penyedia yang menggunakan EventRegister (misalnya penyedia berbasis manifes atau penyedia TraceLogging) menggunakan sistem pengaktifan modern (terkadang disebut "crimson ETW"). Ketika penyedia modern diaktifkan atau dikonfigurasi ulang untuk sesi, runtime ETW memberi tahu penyedia dengan tingkat , masker MatchAnyKeyword 64-bit, masker MatchAllKeyword 64-bit, dan data pemfilteran sisi penyedia kustom yang ditentukan oleh pengontrol pelacakan. Penyedia kemudian menggunakan logikanya sendiri untuk memutuskan peristiwa mana yang harus diaktifkan, meskipun sebagian besar penyedia hanya menduplikasi logika EventProviderEnabled. Penyedia mengirimkan peristiwa yang diaktifkan ke ETW untuk perutean. Data peristiwa yang dikirim ke ETW mencakup GUID kontrol peristiwa, ID pesan, tingkat, dan kata kunci. ETW kemudian melakukan pemfilteran tambahan yang sesuai, merutekan peristiwa ke sesi yang sesuai.
    • Karena peristiwa dikirim ke ETW dengan informasi deskriptif, ETW dapat melakukan pemfilteran dan perutean tambahan sebelum menambahkan peristiwa ke sesi. Peristiwa dapat dirutekan ke lebih dari satu sesi jika sesuai.

Untuk penyedia yang menggunakan sistem pengaktifan modern (yaitu penyedia menggunakan EventRegister), ETW mendukung beberapa fitur yang dapat diminta oleh pengontrol sesi pelacakan melalui EnableTraceEx2EnableParameters. (Lihat EVENT_FILTER_DESCRIPTOR untuk detailnya.)

  • Pemfilteran skema - Ini adalah penyiapan pemfilteran tradisional, juga disebut pemfilteran sisi penyedia. Pengontrol menentukan sekumpulan filter kustom sebagai objek biner yang diteruskan ke penyedia di EnableCallbackFilterData. Ini incumbent pada pengontrol dan penyedia untuk menentukan dan menafsirkan filter ini. Penyedia kemudian dapat menggunakan parameter Filter EventWriteEx untuk menunjukkan sesi tempat peristiwa tidak boleh dikirim karena pemfilteran sisi penyedia. Ini memerlukan coupling dekat pengontrol dan penyedia karena jenis dan format objek biner dari apa yang dapat difilter tidak ditentukan. Fungsi TdhEnumerateProviderFilters dapat digunakan untuk mengambil filter yang ditentukan dalam manifes.
  • Pemfilteran cakupan - Penyedia tertentu diaktifkan atau tidak diaktifkan ke sesi berdasarkan apakah mereka memenuhi kriteria yang ditentukan oleh filter cakupan atau tidak. Ada beberapa jenis filter cakupan yang memungkinkan pemfilteran berdasarkan ID proses (PID), nama file yang dapat dieksekusi, ID aplikasi, dan nama paket aplikasi. Fitur ini didukung pada Windows 8.1, Windows Server 2012 R2, dan yang lebih baru.
  • Pemfilteran Stackwalk - Ini memberi tahu ETW untuk hanya melakukan stack walk untuk sekumpulan ID peristiwa tertentu atau nama peristiwa (untuk peristiwa TraceLogging). Fitur ini didukung pada Windows 8.1, Windows Server 2012 R2, dan yang lebih baru.
  • Pemfilteran atribut - Untuk penyedia manifes, peristiwa dapat difilter berdasarkan atribut peristiwa seperti tingkat, kata kunci, ID peristiwa, atau nama peristiwa.
  • Pemfilteran payload peristiwa - Untuk penyedia manifes, peristiwa dapat difilter dengan cepat berdasarkan apakah mereka memenuhi ekspresi logis berdasarkan satu atau beberapa predikat.

Catatan

Meskipun ETW mendukung pemfilteran payload dan atribut yang kuat, peristiwa terutama harus difilter berdasarkan filter cakupan atau melalui GUID kontrol, tingkat, dan kata kunci. Penyedia biasanya melakukan guid kontrol, tingkat, dan pemfilteran kata kunci langsung dalam kode penyedia sebelum peristiwa dibuat atau dikirim ke ETW. Di sebagian besar penyedia, peristiwa yang dinonaktifkan berdasarkan tingkat atau kata kunci hampir tidak berdampak pada performa sistem. Demikian pula, penyedia yang dinonaktifkan oleh filter cakupan hampir tidak berdampak pada performa sistem. Jenis pemfilteran lainnya (berdasarkan payload atau atribut selain tingkat dan kata kunci) biasanya dilakukan setelah penyedia menghasilkan peristiwa dan mengirimkannya ke runtime ETW, yang berarti peristiwa tersebut berdampak pada performa sistem (waktu CPU yang dihabiskan untuk mempersiapkan peristiwa dan mengirimkannya ke ETW) bahkan jika pemfilteran ETW menentukan bahwa peristiwa tersebut tidak boleh direkam oleh sesi apa pun. Pemfilteran semacam ini hanya efektif dalam mengurangi volume data pelacakan dan tidak seefektif untuk mengurangi overhead CPU pelacakan.

Setiap kali EnableTraceEx2 dipanggil, filter untuk penyedia dalam sesi tersebut digantikan oleh parameter baru yang ditentukan oleh parameter yang diteruskan ke fungsi EnableTraceEx2 . Beberapa filter yang diteruskan dalam satu panggilan EnableTraceEx2 dapat dikombinasikan dengan efek aditif, tetapi filter yang diteruskan dalam panggilan berikutnya akan menggantikan kumpulan filter sebelumnya.

Untuk menonaktifkan pemfilteran dan dengan demikian mengaktifkan semua penyedia/peristiwa dalam sesi pengelogan, panggil EnableTraceEx2 dengan parameter EnableParameters yang menunjuk ke struktur ENABLE_TRACE_PARAMETERS dengan anggota FilterDescCount diatur ke 0.

Setiap filter yang diteruskan ke fungsi EnableTraceEx2 ditentukan oleh anggota Jenis di EVENT_FILTER_DESCRIPTOR. Array struktur EVENT_FILTER_DESCRIPTOR diteruskan dalam struktur ENABLE_TRACE_PARAMETERS yang diteruskan dalam parameter EnableParameters ke fungsi EnableTraceEx2 .

Setiap jenis filter (anggota Jenis tertentu) hanya dapat muncul sekali dalam panggilan ke fungsi EnableTraceEx2 . Beberapa jenis filter memungkinkan beberapa kondisi disertakan dalam satu filter. Jumlah maksimum filter yang dapat disertakan dalam panggilan ke EnableTraceEx2 diatur oleh MAX_EVENT_FILTERS_COUNT (didefinisikan dalam file header Evntprov.h ; nilai dapat berubah dalam versi Windows SDK yang akan datang).

Setiap jenis filter memiliki batas ukuran atau entitasnya sendiri berdasarkan anggota Jenis tertentu dalam struktur EVENT_FILTER_DESCRIPTOR . Daftar di bawah ini menunjukkan batasan ini.

  • EVENT_FILTER_TYPE_SCHEMATIZED

    • Batas ukuran filter: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Jumlah elemen yang diizinkan: Ditentukan oleh penyedia dan pengontrol
  • EVENT_FILTER_TYPE_PID

    • Batas ukuran filter: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Jumlah elemen yang diizinkan: MAX_EVENT_FILTER_PID_COUNT (8)
  • EVENT_FILTER_TYPE_EXECUTABLE_NAME

    • Batas ukuran filter: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Jumlah elemen yang diizinkan: String tunggal yang dapat berisi beberapa nama file yang dapat dieksekusi yang dipisahkan oleh titik koma.
  • EVENT_FILTER_TYPE_PACKAGE_ID

    • Batas ukuran filter: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Jumlah elemen yang diizinkan: String tunggal yang dapat berisi beberapa ID paket yang dipisahkan oleh titik koma.
  • EVENT_FILTER_TYPE_PACKAGE_APP_ID

    • Batas ukuran filter: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Jumlah elemen yang diizinkan: String tunggal yang dapat berisi beberapa ID aplikasi relatif paket (PRAID) yang dipisahkan oleh titik koma.
  • EVENT_FILTER_TYPE_PAYLOAD

    • Batas ukuran filter: MAX_EVENT_FILTER_PAYLOAD_SIZE (4096)
    • Jumlah elemen yang diizinkan: 1
  • EVENT_FILTER_TYPE_EVENT_ID

    • Batas ukuran filter: Tidak ditentukan
    • Jumlah elemen yang diizinkan: MAX_EVENT_FILTER_EVENT_ID_COUNT (64)
  • EVENT_FILTER_TYPE_STACKWALK

    • Batas ukuran filter: Tidak ditentukan
    • Jumlah elemen yang diizinkan: MAX_EVENT_FILTER_EVENT_ID_COUNT (64)

Kata kunci menentukan kategori peristiwa. Misalnya, jika penyedia menentukan InitializationKeyword = 0x1 (kata kunci bit 0), FileOperationKeyword = 0x2 (kata kunci bit 1), dan CalculationKeyword = 0x4 (kata kunci bit 2), Anda dapat mengatur MatchAnyKeyword ke (InitializationKeyword | CalculationKeyword) = 5 untuk menerima inisialisasi dan peristiwa penghitungan tetapi bukan peristiwa file.

Ketika digunakan dengan penyedia modern (berbasis manifes atau TraceLogging), nilai 0MatchAnyKeyword diperlakukan sama dengan nilai 0xFFFFFFFFFFFFFFFFMatchAnyKeyword, yaitu memungkinkan semua kata kunci peristiwa. Namun, perilaku ini tidak berlaku untuk penyedia warisan (MOF atau WPP berbasis TMF). Untuk mengaktifkan semua kata kunci peristiwa dari penyedia warisan, atur MatchAnyKeyword ke 0xFFFFFFFF. Untuk mengaktifkan semua kata kunci peristiwa dari penyedia warisan dan modern, atur MatchAnyKeyword ke 0xFFFFFFFFFFFFFFFF.

Jika kata kunci peristiwa adalah nol, penyedia akan menulis peristiwa ke sesi terlepas dari masker MatchAnyKeyword dan MatchAllKeyword . (Perilaku ini dapat dinonaktifkan dengan menggunakan bendera EVENT_ENABLE_PROPERTY_IGNORE_KEYWORD_0 .)

Untuk menunjukkan bahwa Anda ingin mengaktifkan Grup Penyedia, gunakan EVENT_ENABLE_PROPERTY_PROVIDER_GROUP bendera pada anggota EnableProperty dari EnableParameters.

Ketika Anda memanggil EnableTraceEx2, penyedia mungkin atau mungkin belum terdaftar. Jika penyedia sudah terdaftar, ETW memanggil fungsi panggilan balik penyedia (jika ada), dan sesi mulai menerima peristiwa. Jika penyedia belum terdaftar, ETW akan memanggil fungsi panggilan balik penyedia (jika ada) segera setelah penyedia mendaftar dan sesi kemudian akan mulai menerima peristiwa. Jika penyedia belum terdaftar, fungsi panggilan balik penyedia tidak akan menerima ID sumber.

Jika penyedia terdaftar dan sudah diaktifkan ke sesi Anda, Anda dapat memanggil EnableTraceEx2 lagi untuk memperbarui parameter Level, MatchAnyKeyword, MatchAllKeyword dan anggota EnableProperty dan EnableFilterDesc dari EnableParameters.

Pada Windows 8.1, Windows Server 2012 R2, dan yang lebih baru, payload peristiwa, cakupan, dan filter stack walk dapat digunakan oleh fungsi EnableTraceEx2 dan struktur ENABLE_TRACE_PARAMETERS dan EVENT_FILTER_DESCRIPTOR untuk memfilter kondisi tertentu dalam sesi pencatat. Untuk informasi selengkapnya tentang filter payload peristiwa, lihat fungsi TdhCreatePayloadFilter, dan TdhAggregatePayloadFilters dan struktur ENABLE_TRACE_PARAMETERS, EVENT_FILTER_DESCRIPTOR, dan PAYLOAD_FILTER_PREDICATE .

Peristiwa penyedia pelacakan sistem khusus tidak dapat diaktifkan atau dinonaktifkan oleh EnableTraceEx2. Mereka hanya dapat diaktifkan melalui bidang EnableFlagsEVENT_TRACE_PROPERTIES ketika jejak pertama kali dimulai oleh StartTrace.

Dimulai dengan Windows 11, peristiwa penyedia pelacakan sistem dapat diaktifkan menggunakan EnableTraceEx2.

Hingga delapan sesi pelacakan dapat mengaktifkan dan menerima peristiwa dari penyedia modern (berbasis manifes atau TraceLogging) yang sama. Namun, hanya satu sesi pelacakan yang dapat mengaktifkan penyedia warisan (MOF, WPP berbasis TMF). Jika lebih dari satu sesi mencoba mengaktifkan penyedia warisan, sesi pertama akan berhenti menerima peristiwa ketika sesi kedua mengaktifkan penyedia yang sama. Misalnya, jika Sesi A mengaktifkan penyedia warisan lalu Sesi B mengaktifkan penyedia yang sama, hanya Sesi B yang akan menerima peristiwa dari penyedia tersebut.

Penyedia tetap diaktifkan untuk sesi hingga sesi menonaktifkan penyedia. Jika aplikasi yang memulai sesi berakhir tanpa menonaktifkan penyedia, penyedia tetap diaktifkan.

Untuk menentukan tingkat dan kata kunci yang digunakan untuk mengaktifkan penyedia berbasis manifes, gunakan salah satu perintah berikut:

  • nama penyedia kueri logman
  • wevtutil gp provider-name

Untuk penyedia klasik, terserah penyedia untuk mendanai dan menyediakan untuk pengontrol potensial tingkat keparahan atau mengaktifkan bendera yang didukungnya. Jika penyedia ingin diaktifkan oleh pengontrol apa pun, penyedia harus menerima 0 untuk tingkat keparahan dan mengaktifkan bendera dan menginterpretasikan 0 sebagai permintaan untuk melakukan pengelogan default (apa pun yang mungkin terjadi).

Jika Anda menggunakan EnableTraceEx2 untuk mengaktifkan penyedia klasik, terjemahan berikut terjadi:

  • Parameter Level sama dengan mengatur parameter EnableLevel di EnableTrace.
  • MatchAnyKeyword sama dengan mengatur parameter EnableFlag di EnableTrace kecuali bahwa nilai kata kunci dipotong dari nilai 64-bit ke nilai 32-bit.
  • Dalam panggilan balik ControlCallback , penyedia dapat memanggil GetTraceEnableLevel untuk mendapatkan tingkat dan GetTraceEnableFlags untuk mendapatkan bendera aktifkan.
  • Parameter lainnya tidak digunakan.

Contoh

Contoh berikut menunjukkan penggunaan EnableTraceEx2 dengan filter payload menggunakan fungsi TdhCreatePayloadFilter dan TdhAggregatePayloadFilters untuk memfilter kondisi tertentu dalam sesi pencatat.

#define INITGUID
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <strsafe.h>
#include <evntrace.h>
#include <tdh.h>

#define MAXIMUM_SESSION_NAME 1024

#define PATH_TO_MANIFEST_FILE L"c:\\ExampleManifest.man"

//
// The following definitions would be found in the include file generated by
// message compiler from the manifest file.
//

// Provider Example-Provider Event Count 2
EXTERN_C __declspec(selectany) const GUID EXAMPLE_PROVIDER = {0x37a59b93, 0xbb25, 0x4cee, {0x97, 0xaa, 0x8b, 0x6a, 0xcd, 0xc, 0x4d, 0xf8}};

//
// Event Descriptors
//
EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR Example_Event_1 = { 0x1, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0 };
#define Example_Event_1_value 0x1
EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR Example_Event_2 = { 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0 };
#define Example_Event_2_value 0x2

//
// (End of snippet from include file)
//

// Allocate an EVENT_TRACE_PROPERTIES structure and set the needed logging session properties
PEVENT_TRACE_PROPERTIES AllocateTraceProperties(
    _In_opt_ PCWSTR LoggerName,
    _In_opt_ PCWSTR LogFileName
)
{
    PEVENT_TRACE_PROPERTIES TraceProperties = NULL;
    ULONG BufferSize;

    BufferSize = sizeof(EVENT_TRACE_PROPERTIES) +
        (MAXIMUM_SESSION_NAME + MAX_PATH) * sizeof(WCHAR);

    TraceProperties = (PEVENT_TRACE_PROPERTIES)malloc(BufferSize);
    if (TraceProperties == NULL) {
        printf("Unable to allocate %d bytes for properties structure.\n", BufferSize);
        goto Exit;
    }

    //
    // Set the session properties.
    //
    ZeroMemory(TraceProperties, BufferSize);
    TraceProperties->Wnode.BufferSize = BufferSize;
    TraceProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
    TraceProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
    TraceProperties->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES) +
        (MAXIMUM_SESSION_NAME * sizeof(WCHAR));

    if (LoggerName != NULL) {
        StringCchCopyW((LPWSTR)((PCHAR)TraceProperties + TraceProperties->LoggerNameOffset),
            MAXIMUM_SESSION_NAME,
            LoggerName);
    }

    if (LogFileName != NULL) {
        StringCchCopyW((LPWSTR)((PCHAR)TraceProperties + TraceProperties->LogFileNameOffset),
            MAX_PATH,
            LogFileName);
    }

Exit:
    return TraceProperties;
}

// Free the EVENT_TRACE_PROPERTIES structure previously allocated
VOID FreeTraceProperties(
    _In_ PEVENT_TRACE_PROPERTIES TraceProperties
)
{
    free(TraceProperties);
    return;
}

// Set the values needed in a PAYLOAD_FILTER_PREDICATE for a single payload filter
FORCEINLINE VOID PayloadPredicateCreate(
    _Out_ PAYLOAD_FILTER_PREDICATE* Predicate,
    _In_ PCWSTR FieldName,
    USHORT CompareOp,
    PCWSTR Value
)
{
    Predicate->FieldName = (PWSTR)FieldName;
    Predicate->CompareOp = CompareOp;
    Predicate->Value = (PWSTR)Value;
    return;
}

int __cdecl wmain()
{
    UINT i;
    PVOID EventFilters[2];
    EVENT_FILTER_DESCRIPTOR FilterDescriptor;
    UINT PredicateCount;
    PAYLOAD_FILTER_PREDICATE Predicates[3];
    ULONG FilterCount;
    ULONG Status = ERROR_SUCCESS;
    TRACEHANDLE SessionHandle = 0;
    PEVENT_TRACE_PROPERTIES TraceProperties;
    BOOLEAN TraceStarted = FALSE;
    PCWSTR LoggerName = L"MyTrace";
    ENABLE_TRACE_PARAMETERS EnableParameters;

    ZeroMemory(EventFilters, sizeof(EventFilters));
    ZeroMemory(Predicates, sizeof(Predicates));
    TraceProperties = NULL;
    FilterCount = 0;

    //
    // Load the manifest for the provider
    //
    Status = TdhLoadManifest((PWSTR)PATH_TO_MANIFEST_FILE);
    if (Status != ERROR_SUCCESS) {
        printf("TdhCreatePayloadFilter() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Create predicates that match the following high-level expression:
    //
    // INCLUDE Example_Event_1 IF
    //     Example_Event_1.Initiator == "User" AND
    //     7 <= Example_Event_1.Level <= 16
    //
    PredicateCount = 0;

    PayloadPredicateCreate(
        &Predicates[PredicateCount++],
        (PWSTR)L"Initiator",
        PAYLOADFIELD_IS,
        (PWSTR)L"User");

    PayloadPredicateCreate(
        &Predicates[PredicateCount++],
        L"Level",
        PAYLOADFIELD_BETWEEN,
        L"7,16");

    Status = TdhCreatePayloadFilter(
        &EXAMPLE_PROVIDER,
        &Example_Event_1,
        FALSE,      // Match all predicates (AND)
        PredicateCount,
        Predicates,
        &EventFilters[FilterCount++]);
    if (Status != ERROR_SUCCESS) {
        printf("TdhCreatePayloadFilter() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Create predicates that match the following high-level expression:
    // INCLUDE Example_Event_2 IF
    //      Example_Event_2.Title CONTAINS "UNI" OR
    //      Example_Event_2.InstanceId == {0E95CFBC-58D4-44BA-BE40-E63A853536DF} OR
    //      Example_Event_2.ErrorCode != 0      //
    PredicateCount = 0;

    PayloadPredicateCreate(
        &Predicates[PredicateCount++],
        L"Title",
        PAYLOADFIELD_CONTAINS,
        L"UNI");

    PayloadPredicateCreate(
        &Predicates[PredicateCount++],
        L"InstanceId",
        PAYLOADFIELD_IS,
        L" {0E95CFBC-58D4-44BA-BE40-E63A853536DF}");

    PayloadPredicateCreate(
        &Predicates[PredicateCount++],
        L"ErrorCode",
        PAYLOADFIELD_NE,
        L"0");

    Status = TdhCreatePayloadFilter(
        &EXAMPLE_PROVIDER,
        &Example_Event_2,
        FALSE,      // Match any predicates (OR)
        PredicateCount,
        Predicates,
        &EventFilters[FilterCount++]);
    if (Status != ERROR_SUCCESS) {
        printf("TdhCreatePayloadFilter() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Combine the interim filters into a final filter descriptor.
    //
    Status = TdhAggregatePayloadFilters(
        FilterCount,
        EventFilters,
        NULL,
        &FilterDescriptor);
    if (Status != ERROR_SUCCESS) {
        printf("TdhAggregatePayloadFilters() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Clean up the interim filters
    //
    for (i = 0; i < FilterCount; i++) {

        Status = TdhDeletePayloadFilter(&EventFilters[i]);
        if (Status != ERROR_SUCCESS) {
            printf("TdhDeletePayloadFilter() failed with %lu\n", Status);
            goto Exit;
        }
    }

    //
    // Create a new trace session
    //
    //
    // Allocate EVENT_TRACE_PROPERTIES structure and perform some
    // basic initialization.
    //
    // N.B. LoggerName will be populated during StartTrace call.
    //
    TraceProperties = AllocateTraceProperties(NULL, L"SystemTrace.etl");
    if (TraceProperties == NULL) {
        Status = ERROR_OUTOFMEMORY;
        goto Exit;
    }

    TraceProperties->LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL | EVENT_TRACE_SYSTEM_LOGGER_MODE;
    TraceProperties->MaximumFileSize = 100; // Limit file size to 100MB max
    TraceProperties->BufferSize = 512; // Use 512KB trace buffers
    TraceProperties->MinimumBuffers = 8;
    TraceProperties->MaximumBuffers = 64;

    Status = StartTraceW(&SessionHandle, LoggerName, TraceProperties);
    if (Status != ERROR_SUCCESS) {
        printf("StartTrace() failed with %lu\n", Status);
        goto Exit;
    }

    TraceStarted = TRUE;

    //
    // Enable the provider to a trace session with filtering enabled on the
    // provider
    //
    ZeroMemory(&EnableParameters, sizeof(EnableParameters));
    EnableParameters.Version = ENABLE_TRACE_PARAMETERS_VERSION_2;
    EnableParameters.EnableFilterDesc = &FilterDescriptor;
    EnableParameters.FilterDescCount = 1;

    Status = EnableTraceEx2(
        SessionHandle,
        &EXAMPLE_PROVIDER,
        EVENT_CONTROL_CODE_ENABLE_PROVIDER,
        TRACE_LEVEL_VERBOSE,
        0,
        0,
        0,
        &EnableParameters);
    if (Status != ERROR_SUCCESS) {
        printf("EnableTraceEx2() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Clean up the payload descriptor
    //
    Status = TdhCleanupPayloadEventFilterDescriptor(&FilterDescriptor);
    if (Status != ERROR_SUCCESS) {
        printf("TdhCleanupPayloadEventFilterDescriptor() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Collect trace for 30 seconds
    //
    Sleep(30 * 1000);

Exit:

    //
    // Stop tracing.
    //
    if (TraceStarted != FALSE) {
        Status = ControlTraceW(SessionHandle, NULL, TraceProperties, EVENT_TRACE_CONTROL_STOP);
        if (Status != ERROR_SUCCESS) {
            printf("StopTrace() failed with %lu\n", Status);
        }
    }

    if (TraceProperties != NULL) {
        FreeTraceProperties(TraceProperties);
    }

    TdhUnloadManifest((PWSTR)PATH_TO_MANIFEST_FILE);

    return Status;
}

Persyaratan

Persyaratan Nilai
Klien minimum yang didukung Windows 7 [aplikasi desktop | Aplikasi UWP]
Server minimum yang didukung Windows Server 2008 R2 [aplikasi desktop | Aplikasi UWP]
Target Platform Windows
Header evntrace.h
Pustaka Sechost.lib pada Windows 8.1 dan Windows Server 2012 R2; Advapi32.lib pada Windows 8, Windows Server 2012, Windows 7 dan Windows Server 2008 R2
DLL Sechost.dll pada Windows 8.1 dan Windows Server 2012 R2; Advapi32.dll pada Windows 8, Windows Server 2012, Windows 7, dan Windows Server 2008 R2

Lihat juga

StartTrace

ControlTrace

EnableCallback

ENABLE_TRACE_PARAMETERS

EVENT_FILTER_DESCRIPTOR