.NET Core日志[4]:将日志写入EventLog
面向Windows的程序员应该对Event Log很熟悉,所以很多人一提到日志,首先想到的就是EventLog。 EventLog不仅记录Windows系统自身的各种事件日志,我们的应用程序还可以使用提供的API将日志消息写入EventLog。与EventLog相关的API在System.Diagnostics.EventLog类型中定义。我们不仅可以用它来读取、写入和删除日志,还可以用它来创建和删除事件源。 .NET Core的日志模型使用EventLogLogger来实现与EventLog的集成,但是EventLogLogger使用的是抽象的EventLog。本文已同步至《www.introzo.com Core框架揭秘》]
目录
1。摘要事件日志
2。 EventLogLogger
3。 EventLogLoggerProvider
1。摘要事件日志
EventLogLogger 在 NuGet 包“Microsoft.Extensions.Logging.EventLog”中定义。截至当前版本,NuGet 包托管的程序集仅适用于 .NET Framework 应用程序。换句话说,EventLogLogger仅提供对Windows EventLog的支持。尽管如此,日志模型仍然通过接口抽象了EventLog的相关操作。
ConsoleLogger 使用 IConsole 接口来抽象不同平台的控制台。 EventLogLogger 使用的抽象 EventLog 由 IEventLog 接口表示。如下面的代码片段所示,IEventLog接口只定义了一个唯一的方法WriteEntry来写入日志。提供的参数用于指定日志的消息文本(message)、类型(type)、事件ID(eventID)和类别(category)。 )。为了防止单个日志包含太多内容,IEventLog接口定义了一个只读属性MaxMessageSize来设置日志消息文本允许的最大长度。
2:{
3:void WriteEntry(字符串消息,EventLogEntryType类型,int事件ID,短类别);
4: int MaxMessageSize { 获取; }
5:}
6:
7:公共枚举EventLogEntryType
8:{
9:错误 = 1,
10:警告=2,
11:信息=4,
12:成功审核 = 8
13:失败审核 = 16
14:}
EventLog记录的每条日志都有一个由枚举EventLogEntryType表示的类型,相当于日志级别。对于该枚举中定义的五种类型,Error、Warning、Information 与同名日志级别含义相同,而 SuccessAudit 和 FailureAudit 代表“Audit”事件的日志,分别代表“成功”事件的日志。事件”和“失败事件”回顾。 EventLogLogger在使用EventLog写入日志时,会将指定的日志级别转换为EventLog日志类型。转换规则很简单:Error、Warning、Information的日志级别转换为同名的EventLog日志类型,其他级别转换为Information类型。
具有以下定义的 WindowsEventLog 是 IEventLog 接口的默认实现者。 WindowsEventLog 实际上是 EventLog 对象的封装,由 DiagnosticsEventLog 属性表示。这个封装的EventLog对象是在构造函数中通过指定相应参数的日志名称(logName)、机器名称(machineName)和事件源名称(sourceName)来创建的。在实现的WriteEntry方法中,直接调用这个EventLog的WriteEntry来完成日志的写入。 WindowsEventLog 的 MaxMessageSize 属性返回常量 31839,日志消息文本不能超过此长度。
2:{
3: private const int MaximumMessageSize = 31839;
4:
5:公共int MaxMessageSize
6:{
7:获取{返回MaximumMessageSize; }
8:}
9:
10: 公共System.Diagnostics.EventLog DiagnosticsEventLog { 获取; }
11:
12: public WindowsEventLog(string logName, string machineName, string sourceName)
13:{
14: DiagnosticsEventLog = new System.Diagnostics.EventLog(logName, machineName, sourceName);
15:}
16:
17:public void WriteEntry(字符串消息,EventLogEntryType类型,int事件ID,短类别)
18:{
19:DiagnosticsEventLog.WriteEntry(消息、类型、事件ID、类别);
20:}
21:}
二、EventLogLogger
日志模型利用EventLogger实现了与EventLog的集成。具体来说,一个EventLogger实际上是对EventLog对象的封装,它利用了向EventLog写入日志。EventLogLogger类型具有如下的定义,我们可以看到它具有构造函数,除了提供两个Logger名称之外,其中一个构造函数具有一个类型为EventLogSettings的参数,这个封装的EventLog对象正式创建通过该参数提供的信息出来的。
2:{
3: public EventLogLogger(字符串名称);
4:public EventLogLogger(字符串名称,EventLogSettings设置);
5:
6:public IDisposable BeginScope
7: public bool IsEnabled(LogLevel logLevel);
8:public void Log(LogLevel logLevel, EventId eventId, TState 状态, Exception 异常,
9:Func
10:}
11:
12:公共类EventLogSettings
13:{
14: 公共 IEventLog 事件日志 { 获取;放; }
15:
16: 公共字符串 LogName { get;放; }
17: 公共字符串机器名{ get;放; }
18: 公共字符串 SourceName { get;放; }
19:
20:公共Func
21:}
如上面的代码片段所示,我们可以使用EventLogSettings对象的EventLog属性来向EventLogLogger提供特定的EventLog对象。如果此属性为 Null,EventLogLogger 将使用 EventLogSettings 的其他三个属性(LogName、MatcheName 和 SourceName)创建 WindowsEventLog 对象。除了这四个与创建或提供EventLog对象相关的属性之外,EventLogSettings还有另一个Func 当EventLogLogger使用EventLogSettings创建WindowsEventLog对象时,如果EventLogSettings对象中没有显式设置相关属性(LogName、MatcheName和SourceName),则会采用预定义的默认值。具体来说,这三者对应的默认值分别是“Application”[1]、“.” (代表本地机器)和“应用程序”。如果我们调用第一个构造函数重载,实际上将使用这些默认值在内部创建一个 WindowsEventLog 对象。如果调用构造函数时没有指定名称(name参数),则将使用类型名称(“EventLogLogger”)来命名创建的Logger。 EventLogLogger 和 DebugLogger 一样,不支持日志上下文作用域,所以它的 BeginScope EventLogLogger 由相应的EventLogLoggerProvider 提供。以下代码反映了该类型的完整定义。我们可以调用如下所示的三个扩展方法AddEventLog来创建对应的EventLoggerProvider,并将其注册到指定的LoggerFactory上。我们可以使用此方法来指定EventLogSettings对象以及用于提供或协助创建EventLog的最低日志级别。
2:{
3:私有只读EventLogSettings_settings;
4:公共EventLogLoggerProvider():this(null)
5:{}
6:
7:公共EventLogLoggerProvider(EventLogSettings设置)
8:{
9:_settings=设置;
10:}
11:
12: public ILogger CreateLogger(字符串名称)
13:{
14: return new EventLogLogger(name, _settings ?? new EventLogSettings());
15:}
16:
17: public void Dispose()
18:{}
19:}
20:
21:公共静态类EventLoggerFactoryExtensions
22:{
23: public static ILoggerFactory AddEventLog(这个 ILoggerFactory 工厂);
24:public static ILoggerFactory AddEventLog(此ILoggerFactory工厂,EventLogSettings设置);
25:公共静态ILoggerFactory AddEventLog(此ILoggerFactory工厂,LogLevel minLevel);
26:}
我们还通过简单的控制台应用程序演示了 EventLog 的日志记录。我们的第一选择是创建一个空的控制台应用程序并在 project.json 中添加所需的依赖项。由于 EventLog 的日志记录仅适用于 .NET Framework 应用程序,因此我们仅为该应用程序定义了 .NET Framework 4.6.1 (net461) 的框架。
2:...
3:“依赖项”:{
4:“Microsoft.Extensions.DependencyInjection”:“1.0.0”,
5:“Microsoft.Extensions.Logging”:“1.0.0”,
6:“Microsoft.Extensions.Logging.EventLog”:“1.0.0”
7:},
8:
9:“框架”:{
10:“net461”:{
11:“框架组件”:{
12:“系统.运行时”:{
13:“类型”:“构建”
14:}
15:}
16:}
17:}
18:}
我们编写了以下程序来完成EventLog的记录。如下面的代码片段所示,我们首先为要写入的日志创建一个名为“Demo”的Event Source(一般代表写入日志的应用程序或服务的名称)。接下来,我们使用依赖注入创建了LoggerFactory对象,并调用扩展方法AddEventLog创建了EventLoggerProvider对象并将其注册到LoggerFactory中。我们在调用此 AddEventLog 方法时指定了一个 EventLogSettings 对象,并将其 SourceName 属性设置为“Demo”。我们最终使用这个 LoggerFactory 对象来创建相应的 Logger,并用它来写入带有 Error 级别的日志。
2:{
3: public static void Main(string[] args)
4:{
5: if(!EventLog.SourceExists("演示"))
6:{
7:EventLog.CreateEventSource("演示", "应用程序");
8:}
9:
10:新的ServiceCollection()
11: .AddLogging()
12: .BuildServiceProvider()
13: .GetService
14: .AddEventLog(new EventLogSettings { SourceName = "Demo" })
15: .CreateLogger
16: .LogError("数据库连接失败(数据库:{数据库},用户名:{用户})","TestDb","sa");
17:}
18:}
由于上述程序涉及查看和创建Event Source,因此需要在管理员权限下正常运行。运行程序并查看事件查看器后,我们将看到此日志消息被写入。如图10所示,由于我们调用扩展方法AddEventLog时提供的EventLogSettings没有明确指定EventLog名称,所以我们的日志将默认写入Application EventLog。
[1] Windows 默认提供了三种EventLog,分别是Application、System 和Security。应用程序生成的日志只能写入应用程序日志和系统日志。安全日志是只读的。除了这三种类型的EventLog之外,我们还可以为应用程序创建独立的EventLog。 .NET Core 日志[1]:使用统一方式记录日志 3。 EventLogLoggerProvider
.NET Core 日志[2]:将日志写入控制台
.NET Core 日志[3]:写入日志 Write到调试窗口
.NET Core 日志[4]:使用EventLog 写入日志
.NET Core 日志[5]:使用TraceSource 写入日志 相关文章