EventSource不会在Windows事件查看器中写入日志

时间:2018-12-15 09:17:34

标签: c# event-log eventsource

我正在尝试在Windows事件查看器中编写日志。我创建了用于捕获异常的类和方法。这是我的代码:

[EventSource(Name = "Samples-EventSourceDemos-EventLog")]
public sealed class MinimalEventSource : EventSource
{
    public static MinimalEventSource Log = new MinimalEventSource();
    [NonEvent]
    public void WriteLog(Exception exception)
    {
        UnhandledException(exception.Message);
    }

    [Event(601, Message = "Unhandled exception occurred. Details: {0}", Keywords = EventKeywords.None, Level = EventLevel.Critical)]
    private void UnhandledException(string exceptionMsg)
    {
        this.WriteEvent(601, exceptionMsg);
    }
}

static void Main(string[] args)
{
    AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
    throw new Exception("TestException");
}

private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    MinimalEventSource.Log.WriteLog(e.ExceptionObject as Exception);
    Process.GetCurrentProcess().Kill();
}

在Windows事件查看器中,我找不到此日志

Windows event viewer

我从nuget安装了Microsoft.Diagnostics.Tracing.EventSource。重建后创建清单。这是调试文件夹 Debug folder

我决定通过代码注册它:

string commandOfRegistringEventSource = "";
using (Process process = new Process())
{
    ProcessStartInfo startInfo = new ProcessStartInfo
    {
        WindowStyle = ProcessWindowStyle.Hidden,
        FileName = "cmd.exe",
        Arguments = commandOfRegistringEventSource
    };
    process.StartInfo = startInfo;
    process.Start();
}

我尝试使用wevtutil.exe im <EtwManifestManFile> /rf:"<EtwManifestDllFile>" /mf:"<EtwManifestDllFile>"执行,但是它显示诸如The system cannot find the file specified.之类的错误,...请帮助我编写registring EventSource的cmd命令。这是清单

 C:\Users\dilshodk\source\repos\ETW loggiing\ETW loggiing\bin\Debug\ETW loggiing.Samples-EventSourceDemos-EventLog.etwManifest.dll
C:\Users\dilshodk\source\repos\ETW loggiing\ETW loggiing\bin\Debug\ETW loggiing.Samples-EventSourceDemos-EventLog.etwManifest.man

2 个答案:

答案 0 :(得分:1)

您还需要一些其他步骤才能使其正常运行。首先,您需要像这样设置Channel属性的Event属性:

[EventSource(Name = "Samples-EventSourceDemos-EventLog")]
public sealed class MinimalEventSource : EventSource
{
    public static MinimalEventSource Log = new MinimalEventSource();
    [NonEvent]
    public void WriteLog(Exception exception)
    {
        UnhandledException(exception.Message);
    }

    [Event(601, Channel = EventChannel.Admin,  Message = "Unhandled exception occurred. Details: {0}", Keywords = EventKeywords.None, Level = EventLevel.Critical)]
    private void UnhandledException(string exceptionMsg)
    {
        this.IsEnabled().Dump();
        this.WriteEvent(601, exceptionMsg);
    }
}

第二,您的EventSource需要注册。步骤概述了here

  

通道支持引入的一项要求是需要静态注册ETW提供程序清单。 NuGet软件包支持生成静态注册所需的文件,作为构建的一部分。构建完成后,将运行一个新步骤,该步骤为项目中定义的每种事件源类型生成一对文件:   ..etwManifest.man和   ..etwManifest.dll

     

第一个文件包含ETW清单,而第二个文件包含ETW清单的二进制形式以及任何所需的本机资源(特别是本地化字符串表)。

     

生成上面两个文件的工具是“ eventRegister.exe”,它执行两个功能:   它确保为需要静态注册的所有事件源类型生成注册文件,并且   它对输出程序集中定义的所有事件源类型执行许多验证检查。   部署组件将需要包括这些文件,并在安装时执行一个注册步骤,并在卸载时执行一个注销步骤。

     

注册:

     

wevtutil.exe im <EtwManifestManFile> /rf:"<EtwManifestDllFullPathName>" /mf:"<EtwManifestDllFullPathName>"

     

取消注册:

     

wevtutil.exe um <EtwManifestManFile>

     

对于静态注册,eventRegister.exe生成包含所有本地化信息的清单。之所以需要这样做,是因为清单是在构建时生成的,当时没有关于最终应用程序将运行的区域性的信息。

     

请注意,您将看到在生成的.etwManfest.man文件中,该文件中包含资源文件和清单文件的路径名。它们是在构建时存在的路径。如果使用/ rf和/ mf选项,则不会使用这些路径。因此,您应该始终指定/ rf:和/ mf选项(除非您手动修改.etwManifest.man文件以指定DLL的部署时文件路径)。   最后,对/ mf:和/ rf:选项使用完全限定名称很重要。您可以使用所有过程都可用的环境变量(例如,%SystemRoot%或%ProgramFiles%),但是您不应该使用相对路径(尚不清楚它们与之相对,可能是System32,但不要指望它)。   通常的建议是将您的etwManifest.dll和.etwManifest.man复制到%ProgramFiles%下的目录,然后使用wevtutil在该位置注册它们。

创建上述文件的最简单方法是添加this NuGet软件包,因为它将在构建项目时创建这些文件。 the docs带有.docx格式。

答案 1 :(得分:0)

我过去已这样做,将其写入事件日志Application

using (EventLog eventLog = new EventLog("Application")) 
{
    eventLog.Source = "Application"; 
    eventLog.WriteEntry("Log message test", EventLogEntryType.Information, 101, 1); 
}