微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

找不到Win32 TraceLogging的输出

如何解决找不到Win32 TraceLogging的输出

我试图复制Microsoft提供的TraceLogging的简短示例程序(请参见下文,进行一些细微更改)。我在Visual Studio 2019中完成了``开发''(完全复制)。一切都很好,编译没有问题,运行没有问题,但是在我的PC上我找不到更新的* .etl或* .log文件,也找不到事件查看器中某处的条目。

我仔细阅读了Microsoft文档,并在Internet上搜索了多个小时,但没有任何有用的发现。

我知道我有时会很愚蠢,我必须错过一些显而易见的事情,但这是什么?有什么提示吗?非常感谢!

#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;
}

解决方法

首先,运行此C ++代码不会生成您想要的.log或.etl文件,它只会发送TraceLogging事件,您需要以其他方式捕获它以生成etl文件。

根据MSDN,您有两个步骤来捕获TraceLogging事件:

  1. 使用WPR捕获跟踪数据
  2. 在Windows Phone上捕获TraceLogging事件

首先创建一个.WPRP文件,我使用来自MSDN的相同的C ++代码和WPRP文件,如下所示。

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);
}

示例WPRP文件

<?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>

然后从提升的(以管理员身份运行)命令提示符窗口中使用WPR开始捕获。

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

接下来,您可以运行包含事件的应用程序并停止跟踪捕获。

wpr.exe-停止C:\ Users \ songz \ Desktop \ test.etl描述

这可以生成您通常需要的etl文件。

enter image description here

完成上述操作后,应捕获TraceLogging事件。根据{{​​3}},您可以使用以下命令:

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

xperf -stop MySession

注意:您应该使用xperf -start MySession -f MyFile.etl -on Id

最后,您可以通过WPA查看相应的信息。

github

,

朱松,非常感谢您的投入!您的评论使我步入正轨。 好吧,我没有严格遵守您的文字,但是我发现了新的东西要阅读。

我也希望控制器也成为我的应用程序的一部分。因此,我所做的大致如下:

  • 准备EVENT_TRACE_PROPERTIES结构
  • TraceLogRegister
  • StartTrace
  • EnableTraceEx2(启用)
  • TraceLoggingWrite
  • TraceLoggingUnregister
  • EnableTraceEx2(禁用)
  • ControlTrace(停止)

这导致我可以使用tracerpt或WPA查看xxx.etl文件。

再次感谢!我现在很好。

这是详细的代码:

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

#define LOGFILE_NAME TEXT(".\\Test-Test.etl")
#define LOGSESSION_NAME TEXT("Test-Test-Session")


// 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

static const GUID ProviderGUID = { 0x5b5852d4,{0x87,0x68} };


int main ( int argc,char *argv[] ) // or DriverEntry for kernel-mode.
{
    TRACEHANDLE hTrace = 0;
    EVENT_TRACE_PROPERTIES *petProperties;
    HRESULT hrRegister;

    ULONG bufferSize,ret_val;

    bufferSize = sizeof ( EVENT_TRACE_PROPERTIES ) + sizeof ( LOGFILE_NAME ) + sizeof ( LOGSESSION_NAME ) + 512;    // The additional bytes are necessary because the path of thr LOGFILE_NAME is expanded
    petProperties = (EVENT_TRACE_PROPERTIES *) malloc ( bufferSize );
    if ( petProperties == NULL ) {
        printf ( "Unable to allocate %d bytes for properties structure.\n",bufferSize );
        return 1;
    }

    ZeroMemory ( petProperties,bufferSize );
    petProperties->Wnode.BufferSize = bufferSize;
    petProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
    petProperties->Wnode.ClientContext = 1;
    petProperties->Wnode.Guid = ProviderGUID;
    petProperties->LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL | EVENT_TRACE_PRIVATE_LOGGER_MODE | EVENT_TRACE_PRIVATE_IN_PROC;
    petProperties->MaximumFileSize = 100;       // was 1
    petProperties->BufferSize = 512;
    petProperties->MinimumBuffers = 8;
    petProperties->MaximumBuffers = 64;
    petProperties->LoggerNameOffset = sizeof ( EVENT_TRACE_PROPERTIES );
    petProperties->LogFileNameOffset = sizeof ( EVENT_TRACE_PROPERTIES ) + sizeof ( LOGSESSION_NAME );
    StringCbCopy ( (LPWSTR) ((char *) petProperties + petProperties->LogFileNameOffset),sizeof ( LOGFILE_NAME ),LOGFILE_NAME );

    hrRegister = TraceLoggingRegister ( g_hProvider );
    if ( !SUCCEEDED ( hrRegister ) ) {
        printf ( "TraceLoggingRegister failed. Stopping.\n" );
        return 1;
    }

    ret_val = StartTrace ( &hTrace,LOGSESSION_NAME,petProperties );
    if ( ret_val != ERROR_SUCCESS ) {
        printf ( "StartTrace failed with %i\n",ret_val );
        if ( ret_val != ERROR_ALREADY_EXISTS )
            return 1;
    }

    ret_val = EnableTraceEx2 ( hTrace,&ProviderGUID,EVENT_CONTROL_CODE_ENABLE_PROVIDER,TRACE_LEVEL_VERBOSE,NULL );
    if ( ret_val != ERROR_SUCCESS ) {
        printf ( "EnableTraceEx2(enable) failed with %i\n",ret_val );
        ret_val = ControlTrace ( hTrace,petProperties,EVENT_TRACE_CONTROL_STOP );
        if ( ret_val != ERROR_SUCCESS ) {
            printf ( "ControlTrace(stop) failed with %i\n",ret_val );
        }
        return 1;
    }

    if ( TraceLoggingProviderEnabled ( g_hProvider,0 ) )
        printf ( "TraceLoggingProvider enabled\n" );
    else
        printf ( "TraceLoggingProvider NOT enabled\n" );

    TraceLoggingWrite (
        g_hProvider,"MyEvent1",TraceLoggingString ( argv[0],"arg0" ),// field name is "arg0"
        TraceLoggingInt32 ( argc ) );               // field name is implicitly "argc"

    TraceLoggingUnregister ( g_hProvider );

    ret_val = EnableTraceEx2 ( hTrace,EVENT_CONTROL_CODE_DISABLE_PROVIDER,NULL );
    if ( ret_val != ERROR_SUCCESS ) {
        printf ( "EnableTraceEx2(disable) failed with %i\n",ret_val );
    }
    ret_val = ControlTrace ( hTrace,EVENT_TRACE_CONTROL_STOP );
    if ( ret_val != ERROR_SUCCESS ) {
        printf ( "ControlTrace(stop) failed with %i\n",ret_val );
    }

    return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。