Search code examples
cwinapietw

Cannot find output of Win32 TraceLogging


I tried to replicate the short sample program for TraceLogging that Microsoft provides (see below, with minor changes). I completed the "development" (rather copy) in Visual Studio 2019. All is fine, compiles without issues, runs without issues, but nowhere on my PC I can find an updated *.etl or *.log file, nor do I find an entry somewhere in the Event Viewer.

I carefully read the Microsoft documentation and I searched the Internet for many hours, but no useful findings.

I know that I'm stupid from time to time and I must miss something obvious, but what is it? Any hints, please? Many thanks!

#include <windows.h> // or <wdm.h> for kernel-mode.
#include <winmeta.h>
#include <TraceLoggingProvider.h>
#include <stdio.h>

// Define the GUID to use in TraceLoggingRegister 
// {5B5852D4-DC24-4A0F-87B6-9115AE9D2768}
TRACELOGGING_DEFINE_PROVIDER (      // defines g_hProvider
    g_hProvider,                    // Name of the provider variable
    "Test-Test",                    // Human-readable name of the provider
    (0x5b5852d4, 0xdc24, 0x4a0f, 0x87, 0xb6, 0x91, 0x15, 0xae, 0x9d, 0x27, 0x68) );     // Provider GUID


int main ( int argc, char *argv[] ) // or DriverEntry for kernel-mode.
{
    HRESULT hrRegister;

    hrRegister = TraceLoggingRegister ( g_hProvider );
    if ( !SUCCEEDED ( hrRegister ) ) {
        printf ( "TraceLoggingRegister failed. Stopping." );
        return 1;
    }
    TraceLoggingWrite (
        g_hProvider,
        "MyEvent1",
        // TraceLoggingChannel ( WINEVENT_CHANNEL_CLASSIC_TRACE ),
        // TraceLoggingLevel ( WINEVENT_LEVEL_CRITICAL ),
        TraceLoggingString ( argv[0], "arg0" ),     // field name is "arg0"
        TraceLoggingInt32 ( argc ) );               // field name is implicitly "argc"

    TraceLoggingUnregister ( g_hProvider );
    return 0;
}

Solution

  • First of all, running this C++ code will not generate the .log or .etl file you want, it just sends the TraceLogging event, you need to capture it in other ways to generate the etl file.

    According to the MSDN,You have two steps to capture TraceLogging events:

    1. Capture trace data with WPR
    2. Capture TraceLogging events on Windows Phone

    First create a .WPRP file, I used the same C++ code and WPRP file from MSDN as follow.

    test.cpp

    #include <windows.h> // or <wdm.h> for kernel-mode.
    #include <winmeta.h>
    #include <TraceLoggingProvider.h>
    #include <stdio.h>
    
    
        // Define the GUID to use in TraceLoggingProviderRegister 
        // {3970F9cf-2c0c-4f11-b1cc-e3a1e9958833}
    TRACELOGGING_DEFINE_PROVIDER(
        g_hMyComponentProvider,
        "SimpleTraceLoggingProvider",
        (0x3970f9cf, 0x2c0c, 0x4f11, 0xb1, 0xcc, 0xe3, 0xa1, 0xe9, 0x95, 0x88, 0x33));
    
    
    void main()
    {
    
        char sampleValue[] = "Sample value";
    
        // Register the provider
        TraceLoggingRegister(g_hMyComponentProvider);
        // Log an event
        TraceLoggingWrite(g_hMyComponentProvider, // handle to my provider
            "HelloWorldTestEvent",              // Event Name that should uniquely identify your event.
            TraceLoggingValue(sampleValue, "TestMessage")); // Field for your event in the form of (value, field name).
        // Stop TraceLogging and unregister the provider
        TraceLoggingUnregister(g_hMyComponentProvider);
    }
    

    Sample WPRP file

    <?xml version="1.0" encoding="utf-8"?>
    <!-- TODO: 
    1. Find and replace "SimpleTraceLoggingProvider" with the name of your provider.
    2. See TODO below to update GUID for your event provider
    -->
    <WindowsPerformanceRecorder Version="1.0" Author="Microsoft Corporation" Copyright="Microsoft Corporation" Company="Microsoft Corporation">
      <Profiles>
        <EventCollector Id="EventCollector_SimpleTraceLoggingProvider" Name="SimpleTraceLoggingProvider">
          <BufferSize Value="64" />
          <Buffers Value="4" />
        </EventCollector>
    
        <!-- TODO: 
     1. Update Name attribute in EventProvider xml element with your provider GUID, eg: Name="3970F9cf-2c0c-4f11-b1cc-e3a1e9958833". Or
        if you specify an EventSource C# provider or call TraceLoggingRegister(...) without a GUID, use star (*) before your provider
        name, eg: Name="*MyEventSourceProvider" which will enable your provider appropriately.  
     2. This sample lists one EventProvider xml element and references it in a Profile with EventProviderId xml element. 
        For your component wprp, enable the required number of providers and fix the Profile xml element appropriately
    -->
        <EventProvider Id="EventProvider_SimpleTraceLoggingProvider" Name="*SimpleTraceLoggingProvider" />
    
        <Profile Id="SimpleTraceLoggingProvider.Verbose.File" Name="SimpleTraceLoggingProvider" Description="SimpleTraceLoggingProvider" LoggingMode="File" DetailLevel="Verbose">
          <Collectors>
            <EventCollectorId Value="EventCollector_SimpleTraceLoggingProvider">
              <EventProviders>
                <!-- TODO:
     1. Fix your EventProviderId with Value same as the Id attribute on EventProvider xml element above
    -->
                <EventProviderId Value="EventProvider_SimpleTraceLoggingProvider" />
              </EventProviders>
            </EventCollectorId>
          </Collectors>
        </Profile>
    
        <Profile Id="SimpleTraceLoggingProvider.Light.File" Name="SimpleTraceLoggingProvider" Description="SimpleTraceLoggingProvider" Base="SimpleTraceLoggingProvider.Verbose.File" LoggingMode="File" DetailLevel="Light" />
        <Profile Id="SimpleTraceLoggingProvider.Verbose.Memory" Name="SimpleTraceLoggingProvider" Description="SimpleTraceLoggingProvider" Base="SimpleTraceLoggingProvider.Verbose.File" LoggingMode="Memory" DetailLevel="Verbose" />
        <Profile Id="SimpleTraceLoggingProvider.Light.Memory" Name="SimpleTraceLoggingProvider" Description="SimpleTraceLoggingProvider" Base="SimpleTraceLoggingProvider.Verbose.File" LoggingMode="Memory" DetailLevel="Light" />
    
      </Profiles>
    </WindowsPerformanceRecorder>
    

    Then start the capture using WPR from an elevated (run as Administrator) Command Prompt window.

    wpr.exe -start C:\Users\songz\Desktop\test.wprp

    Next you may run the application that contains your events and stop the trace capture.

    wpr.exe -stop C:\Users\songz\Desktop\test.etl description

    This can generate the etl file you need normally.

    enter image description here

    After completing the above operations, you should capture TraceLogging events. According to the github, you can use the following commands:

    xperf -start MySession -f C:\Users\songz\Desktop\test.etl -on 3970F9cf-2c0c-4f11-b1cc-e3a1e9958833

    xperf -stop MySession

    Note:You should use like xperf -start MySession -f MyFile.etl -on Id

    Finally you can view the corresponding information through WPA.

    enter image description here