web-dev-qa-db-fra.com

Ecrire dans EventLog dans .Net Core

J'ai besoin d'un moyen d'écrire dans l'observateur d'événements de Windows dans mon application qui utilise dnx. Mais, la classe EventLog n'est pas disponible dans le System.Diagnostics namespace donc je suis coincé. Existe-t-il un autre moyen d'écrire dans EventViewer?

9
Ameno acids

Ajouter à partir de NuGetMicrosoft.Extensions.Logging.EventLogVersion 2.1.1

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

Inclure l'espace de noms Microsoft.Extensions.Logging.EventLog dans le Program.cs fichier

Cela a résolu mon problème.

7
praveen

il est disponible en 2.0 mais vous devez installer le pack de compatibilité. https://github.com/dotnet/corefx/issues/2544

Ici pour plus d'informations: https://blogs.msdn.Microsoft.com/dotnet/2017/11/16/announcing-the -windows-compatibilité-pack-pour-net-core /

Bonnes nouvelles! EventLog est déjà porté sur corefx et sera disponible dans . NET Core 2.1 .

À l'heure actuelle, vous pouvez télécharger un package d'aperçu System.Diagnostics.EventLog à partir de leur flux MyGet .

1
nyjl

L'écriture dans le journal des événements dans .Net Core nécessite d'abord l'installation d'un package Nuget

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

Notez que la version correcte à installer dépend de la version de .Net Core que vous utilisez. Le package ci-dessus a été testé OK avec .Net Core.

Ensuite, nous devons ajouter EventLog. Dans la classe Programme, nous pouvons le faire comme suit:

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

Et notre fichier appsettings.json comprend la configuration:

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

Nous pouvons injecter l'instance 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();
        }
    }
}

Utilisation plus avancée, ajoutez un gestionnaire d'exceptions global à l'intérieur de la méthode Configure de la classe Startup dans .Net Core:

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

Et enfin un modèle d'aide pour intégrer nos informations d'exception.

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

L'astuce ici est de mettre la main sur un enregistreur dans la classe Startup. Vous pouvez injecter ILoggerFactory pour cela et juste faire:

  _logger = loggerFactory.CreateLogger<Startup>();

Où _logger est utilisé dans le gestionnaire d'erreur global ci-dessus.

Revenons maintenant à la question de savoir comment écrire dans le journal des événements, regardez le code source pour SomeController ci-dessus. Nous injectons ILogger ici. Utilisez simplement cette instance et elle propose différentes méthodes pour écrire dans vos journaux configurés. Puisque nous avons ajouté dans le journal des événements de la classe Program, cela se produit automatiquement.

Avant de tester le code ci-dessus, exécutez le script Powershell suivant en tant qu'administrateur pour obtenir votre source de journal des événements:

New-EventLog -LogName SomeApi -SourceName SomeApi

Ce que j'aime avec cette approche, c'est que si nous faisons tout correctement, les exceptions apparaissent bien dans la source SomeApi et non dans le journal des événements d'application (encombrement à mon humble avis).

0
Tore Aurstad