web-dev-qa-db-ja.com

.Net CoreのEventLogに書き込む

Dnxを使用しているアプリでWindowsのイベントビューアに書き込む方法が必要です。しかし、EventLogクラスはSystem.Diagnostics名前空間では使用できないため、行き詰まっています。 EventViewerに書き込む他の方法はありますか?

9
Ameno acids

NuGetから追加Microsoft.Extensions.Logging.EventLogVersion 2.1.1

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

名前空間Microsoft.Extensions.Logging.EventLogProgram.csファイルに含める

これで私の問題は解決しました。

7
praveen

2.0で利用可能ですが、互換性パックをインストールする必要があります。 https://github.com/dotnet/corefx/issues/2544

詳細はこちら:https://blogs.msdn.Microsoft.com/dotnet/2017/11/16/announcing-the -windows-compatibility-pack-for-net-core /

朗報です! EventLogはすでに corefxに移植されています であり、 。NET Core 2.1 で使用できるようになります。

現在、プレビューパッケージSystem.Diagnostics.EventLogを MyGet フィードからダウンロードできます。

1
nyjl

.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のスタートアップクラスの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ソース内にうまく表示されることです(IMHOが乱雑になります)。

0
Tore Aurstad