【问题标题】:Write to EventLog in .Net Core在 .Net Core 中写入 EventLog
【发布时间】:2017-01-01 01:20:15
【问题描述】:

我需要一种在使用 dnx 的应用程序中写入 Windows 事件查看器的方法。但是,EventLog 类在 System.Diagnostics 命名空间中不可用,所以我被卡住了。有没有其他方法可以写入 EventViewer?

【问题讨论】:

  • 如果您的应用程序必须以 Core 为目标,那么我不这么认为——事件日志不是一个跨平台的概念。如果您的应用程序可以针对 net461 或其他完整的 .net 平台,那么您可以使用@StingyJack 提到的包
  • @stephen.vakil 如何从我的 project.json 定位 net461 和核心?
  • 通过project.jsonframeworks 部分,请参阅stackoverflow.com/questions/30763115/… 了解一些选项
  • @stephen.vakil 是否可以根据活动的框架有条件地加载命名空间并使用类?我想在 dnx461 处于活动状态时运行EventLog,否则执行其他操作。

标签: c# logging .net-core dnx


【解决方案1】:

NuGetMicrosoft.Extensions.Logging.EventLogVersion 2.1.1添加

CM> Install-Package Microsoft.Extensions.Logging.EventLog -Version 2.1.1

Program.cs 文件中包含命名空间Microsoft.Extensions.Logging.EventLog

这解决了我的问题。

【讨论】:

  • 嗨,欢迎来到 StackOverflow。请您编辑您的答案以澄清这如何回答 OP 的问题。
【解决方案2】:

在 .Net Core 中写入事件日志需要首​​先安装 Nuget 包

Install-Package Microsoft.Extensions.Logging.EventLog -Version 3.1.2

请注意,要安装的正确版本取决于您正在运行的 .Net Core 版本。上面的包已通过 .Net Core 测试正常。

然后我们需要添加EventLog。在 Program 类中,我们可以这样做:

    using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.EventLog;

namespace SomeAcme.SomeApi
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureLogging((hostingContext, logging) =>
                {
                    logging.ClearProviders();
                    logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                    logging.AddEventLog(new EventLogSettings()
                    {
                        **SourceName = "SomeApi",
                        LogName = "SomeApi",**
                        Filter = (x, y) => y >= LogLevel.Warning
                    });
                    logging.AddConsole();
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

我们的 appsettings.json 文件包括设置:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=.\\SQLEXPRESS;Database=SomeApi;Trusted_Connection=True;MultipleActiveResultSets=true"
  },
  **"Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },**
  "AllowedHosts": "*"
}

我们可以注入 ILogger 实例

using SomeAcme.SomeApi.SomeModels;
using SomeAcme.SomeApi.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;

namespace SomeAcme.SomeApi.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class SomeController : ControllerBase
    {
        private readonly ISomeService _healthUnitService;
        private readonly ILogger<SomeController> _logger;

        public SomeController(ISomeService someService, ILogger<SomeController> logger)
        {
            _someService= someService;
            _logger = logger;
        }
        // GET: api/Some
        [HttpGet]
        public IEnumerable<SomeModel> GetAll()
        {
            return _someService.GetAll();
        }
    }
}

更高级的使用,在.Net Core的Startup类的Configure方法里面添加一个全局异常处理函数:

  //Set up a global error handler for handling Unhandled exceptions in the API by logging it and giving a HTTP 500 Error with diagnostic information in Development and Staging
        app.UseExceptionHandler(errorApp =>
        {
            errorApp.Run(async context =>
            {
                context.Response.StatusCode = 500; // or another Status accordingly to Exception Type
                context.Response.ContentType = "application/json";

                var status = context.Features.Get<IStatusCodeReExecuteFeature>();

                var error = context.Features.Get<IExceptionHandlerFeature>();
                if (error != null)
                {
                    var ex = error.Error;
                    string exTitle = "Http 500 Internal Server Error in SomeAcme.SomeApi occured. The unhandled error is: ";
                    string exceptionString = !env.IsProduction() ? (new ExceptionModel
                    {
                        Message = exTitle + ex.Message,
                        InnerException = ex?.InnerException?.Message,
                        StackTrace = ex?.StackTrace,
                        OccuredAt = DateTime.Now,
                        QueryStringOfException = status?.OriginalQueryString,
                        RouteOfException = status?.OriginalPath
                    }).ToString() : new ExceptionModel()
                    {
                        Message = exTitle + ex.Message,
                        OccuredAt = DateTime.Now
                    }.ToString();
                    try
                    {
                        _logger.LogError(exceptionString);
                    }
                    catch (Exception err)
                    {
                        Console.WriteLine(err);
                    }
                    await context.Response.WriteAsync(exceptionString, Encoding.UTF8);
                }
            });
        });

最后是一个辅助模型,用于将我们的异常信息打包到其中。

using System;
using Newtonsoft.Json;

namespace SomeAcme.SomeApi.Models
{
    /// <summary>
    /// Exception model for generic useful information to be returned to client caller
    /// </summary>
    public class ExceptionModel
    {
        public string Message { get; set; }
        public string InnerException { get; set; }
        public DateTime OccuredAt { get; set; }
        public string StackTrace { get; set; }
        public string RouteOfException { get; set; }
        public string QueryStringOfException { get; set; }

        public override string ToString()
        {
            return JsonConvert.SerializeObject(this);
        }
    }
}

这里的棘手之处是在 Startup 类中获取一个记录器。 您可以为此注入 ILoggerFactory 并执行以下操作:

  _logger = loggerFactory.CreateLogger<Startup>();

上面的全局错误处理程序中使用了_logger。

现在再次回到如何写入事件日志的问题,请看上面SomeController的源代码。我们在这里注入 ILogger。 只需使用该实例,它就会提供不同的方法来写入您配置的日志。由于我们在 Program 类事件日志中添加,这会自动发生。

在测试上述代码之前,请以管理员身份运行以下 Powershell 脚本以获取事件日志源:

New-EventLog -LogName SomeApi -SourceName SomeApi

我喜欢这种方法的一点是,如果我们做的一切都正确,异常会很好地在 SomeApi 源中弹出,而不是在应用程序事件日志中(恕我直言混乱)。

【讨论】:

  • 创建事件日志的 PowerShell 语法是 New-EventLog -LogName SomeApi -Source SomeApi
  • 是的,如果 -LogName 和 -Source 具有相同的值,则日志也将在事件查看器中作为 eventvwr 左侧日志列表中的单个节点可见,而不是与其他节点混合日志,通常是应用程序日志。
【解决方案3】:

好消息! EventLog 已经是ported to corefx,将在.NET Core 2.1 中提供。

现在您可以从他们的MyGet 提要下载预览包 System.Diagnostics.EventLog。

【讨论】:

    【解决方案4】:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-06
      • 1970-01-01
      • 2021-07-03
      • 1970-01-01
      • 2017-06-12
      • 1970-01-01
      相关资源
      最近更新 更多