Utilice NLog para registrar

Fecha de creación de la página :

medio ambiente

Estudio visual
  • Visual Studio 2019
Núcleo de ASP.NET
  • 5.0 (MVC, página razor)

al principio

NLog le permite generar registros en archivos, correos electrónicos y bases de datos en función de la configuración.

NLog ASP.NET incorporarse al sistema de registro estándar del núcleo. Es posible generar registros de acuerdo con la configuración mientras se utiliza el registrador predeterminado.

Acerca de los niveles de registro

Los registros de Microsoft y los NLog se dividen en seis etapas y los niveles de salida son aproximadamente los mismos:

Nivel MicrosoftNLog
0 rastro rastro
1 depurar depurar
2 información información
3 advertencia advertir
4 error error
5 crítico fatal
(6) (Ninguno) (Desactivado)

Cuanto mayor sea el nivel, más importante será el registro y más probable será que se escriba independientemente de las restricciones de salida de registro.

Instrucciones de registro

Implementación de paquetes NLog

ASP.NET ha creado un proyecto Core, agregue un paquete.

Haga clic con el botón derecho en Dependencias del proyecto y seleccione Administrar paquetes NuGet.

Haga clic en la pestaña Examinar y escriba NLog en el campo de búsqueda para mostrar paquetes relacionados con NLog.

Seleccione NLog y, a continuación, haga clic en el botón instalar con la última versión estable seleccionada.

Haga clic en Aceptar.

Instale también NLog.Web.AspNetCore.

El paquete se ha agregado al proyecto.

Añadir nlog.config

Agregue nlog.config, la definición de salida del registro NLog, al proyecto. El contenido está en formato XML, así que lo creé como un archivo XML. El nombre del archivo debe ser nlog.config (minúsculas).

Cree el archivo de la siguiente manera: La configuración detallada se discutirá más adelante.

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      internalLogLevel="Info"
      throwConfigExceptions="true"
      internalLogFile="${basedir}/internal-nlog-AspNetCore.txt">

  <!-- ログの出力レイアウトを変数 layoutDefine で定義 -->
  <variable name="layoutDefine"
            value="${longdate} [${event-properties:item=EventId_Id:whenEmpty=0}][${level:padding=-5}] ${message} ${exception:format=tostring} (${callsite:includeNamespace=false:fileName=true:includeSourcePath=false})" />

  <!-- 書き込むターゲット -->
  <targets>
    <!-- Visual Studio の出力 (デバッグ) に書き込みます -->
    <target xsi:type="Trace" name="TraceOutput" rawWrite="true" layout="${layoutDefine}" />

    <!-- 基本的な詳細を含むすべてのログメッセージのファイルターゲット -->
    <target xsi:type="File" name="FileOutput" fileName="${aspnet-appbasepath}/Log-${shortdate}.log" layout="${layoutDefine}" />

    <!-- Docker / Visual Studio の起動検出を改善するためにライフタイムメッセージをホストするためのコンソールターゲット  -->
    <target xsi:type="Console" name="LifetimeConsole" layout="${level:truncate=4}\: ${logger}[0]${newline}      ${message}${exception:format=tostring}" />
  </targets>

  <!-- ロガー名からターゲットにマップするルール -->
  <rules>
    <!-- Microsoft からのものを含むすべてのログ -->
    <logger name="*" writeTo="TraceOutput" />

    <!-- 起動の検出を高速化するために、ホスティングライフタイムメッセージをコンソールターゲットに出力します。Microsoft.Hosting.Lifetime はここより下の定義には出力しません -->
    <logger name="Microsoft.Hosting.Lifetime" minlevel="Info" writeTo="LifetimeConsole" final="true" />

    <!-- 重要でない Microsoft ログをスキップして、自分のログのみをログに記録する。システムが出す Warning 以上のログ以外はここより下の定義には出力されません -->
    <logger name="Microsoft.*" maxlevel="Info" final="true" />
    <logger name="System.Net.Http.*" maxlevel="Info" final="true" />

    <!-- 上記で除外したもの以外をファイルに出力 -->
    <logger name="*" writeTo="FileOutput" />
  </rules>
</nlog>

Asegúrese de que las propiedades de nlog.config están establecidas en Acción de compilación: Contenido, Copiar en directorio de salida: Copiar si es nuevo.

Editar appsetting.json

De forma predeterminada, no importa cómo establezca nlog.config, Information solo estos niveles son de salida. Esto se debe a que el registro también se basa en appsetting.json.

Abra appsetting.json Logging.LogLevel.Default y cambie el valor a Trace . Si utiliza NLog, puede ajustar el nivel en el lado NLog, por lo que puede generar prácticamente todos los niveles Trace estableciendo appsetting.json.

{
  "Logging": {
    "LogLevel": {
      "Default": "Trace",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Además, durante el desarrollo, appsettings. La configuración de Development.json se carga, por lo que también los estamos cambiando.

{
  "DetailedErrors": true,
  "Logging": {
    "LogLevel": {
      "Default": "Trace",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

Preparación de programas para NLog

Agregue un programa para que pueda iniciar sesión en el mecanismo NLog.

Abra .cs archivo de programa y corrija de la siguiente manera:

using NLog.Web;  // 追加

// 省略

public class Program
{
  public static void Main(string[] args)
  {
    var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
    try
    {
      CreateHostBuilder(args).Build().Run();
    }
    catch (Exception exception)
    {
      // NLog:セットアップエラーをキャッチ
      logger.Error(exception, "例外のためにプログラムを停止しました。");
      throw;
    }
    finally
    {
      // アプリケーションを終了する前に、内部タイマー/スレッドをフラッシュして停止するようにしてください
      // (Linux でのセグメンテーション違反を回避してください)
      NLog.LogManager.Shutdown();
    }
  }

  public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
      .ConfigureWebHostDefaults(webBuilder =>
      {
        webBuilder.UseStartup<Startup>();
      })
      .ConfigureLogging(logging =>
      {
        logging.ClearProviders();                 // NLog 以外で設定された Provider の無効化.
        logging.SetMinimumLevel(LogLevel.Trace);  // 最小ログレベルの設定
      })
      .UseNLog();  // NLog:依存性注入のための NLog のセットアップ
}

Registro

Para proyectos HomeComtroller MVC, para páginas Razor, IndexModel se le habría pasado al ILogger<IndexModel> logger constructor. También se establece _logger en el campo privado, por lo que puede usarlo para registrar.

A continuación se muestra un ejemplo de salida de una página de Razor, pero MVC puede generar con el mismo código.

// 省略

public class IndexModel : PageModel
{
  private readonly ILogger<IndexModel> _logger;
  
  public IndexModel(ILogger<IndexModel> logger)
  {
    _logger = logger;
    
    _logger.LogTrace("Trace で出力します。");
    _logger.LogDebug("Debug で出力します。");
    _logger.LogInformation("Information で出力します。");
    _logger.LogWarning("Warning で出力します。");
    _logger.LogError("Error で出力します。");
    _logger.LogCritical("Critical で出力します。");
    
    _logger.LogInformation(1, "EventID ありで出力します。");
  }
  
  public void OnGet()
  {
    _logger.LogInformation("ページを表示するタイミングでログを出力します。");
  }
}

Al depurar, creo que se puede realizar un archivo de registro en la carpeta del proyecto.

Puede comprobar el registro mirando el contenido del archivo.

Comentario de Sample nlog.config

Lo estoy explicando en orden, pero no estoy explicando las partes menos importantes.

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      internalLogLevel="Info"
      throwConfigExceptions="true"
      internalLogFile="${basedir}/internal-nlog-AspNetCore.txt">

Hay parámetros, como la configuración de salida de registro para NLog sí mismo.

internalLogFile será el destino del registro. Esto puede ser útil, por ejemplo, si hay un error en la salida del propio registro. ${basedir} se refiere a la carpeta de ejecución del programa.

internalLogLevel es el nivel de salida del registro NLog. Off si lo es, no será de salida en absoluto.

<!-- ログの出力レイアウトを変数 layoutDefine で定義 -->
<variable name="layoutDefine"
          value="${longdate} [${event-properties:item=EventId_Id:whenEmpty=0}][${level:padding=-5}] ${message} ${exception:format=tostring} (${callsite:includeNamespace=false:fileName=true:includeSourcePath=false})" />

La variable se establece en el diseño en el que se generará el contenido del registro. Puede escribir directamente en destinos posteriores, pero si especifica varios del mismo diseño, es más fácil administrarlos en una variable.

Es mejor consultar el sitio web oficial para ver qué parámetros se pueden especificar en el diseño.

Como referencia, los parámetros especificados aquí son de salida en el siguiente formato:

salida de
Contenido deparámetros
longdate Minutos de fecha y hora como "2021-03-17 11:46:36.5034"
event-properties Muestra el ID de evento, etc. de la salida de registro especificada por el programa
nivel Niveles como seguimiento y error
Mensaje Mensaje especificado en el registro del programa
excepción ¿Qué pasa si se aprueba la excepción en el registro del programa
callsite Ubicación de registro, nombre de archivo, etc.

Ejemplo de salida

2021-03-17 11:46:37.3537 [0][Info ] ページを表示するタイミングでログを出力します。  (IndexModel.OnGet(Index.cshtml.cs:26))
<!-- 書き込むターゲット -->
<targets>
  <!-- Visual Studio の出力 (デバッグ) に書き込みます -->
  <target xsi:type="Trace" name="TraceOutput" rawWrite="true" layout="${layoutDefine}" />

  <!-- 基本的な詳細を含むすべてのログメッセージのファイルターゲット -->
  <target xsi:type="File" name="FileOutput" fileName="${aspnet-appbasepath}/Log-${shortdate}.log" layout="${layoutDefine}" />

  <!-- Docker / Visual Studio の起動検出を改善するためにライフタイムメッセージをホストするためのコンソールターゲット  -->
  <target xsi:type="Console" name="LifetimeConsole" layout="${level:truncate=4}\: ${logger}[0]${newline}      ${message}${exception:format=tostring}" />
</targets>

Especifica el destino que se debe generar. Se pueden especificar varios.

La primera xsi:type="Trace" especifica y el registro se imprime en la ventana de salida de Visual Studio. Se puede usar principalmente para la ejecución de depuración.

El segundo xsi:type="File" especifica y registra en un archivo de la ruta de acceso especificada. Si ${shortdate} especifica en la ruta de acceso, puede escribir el registro en el archivo de la fecha del registro en el momento del registro. También ${aspnet-appbasepath} especifica la carpeta raíz del proyecto Web. Sin embargo, al operar, es mejor generar archivos de registro fuera del directorio Web para la sustitución y seguridad del programa.

El tercero se xsi:type="Console" especifica y se puede mostrar en la consola de la aplicación de consola. ASP.NET Core en sí no es una aplicación de consola, pero también se puede usar en entornos como Docker y Azure porque el estado se puede mostrar en la consola. Esta es la descripción en el sitio web oficial de NLog.

<!-- ロガー名からターゲットにマップするルール -->
<rules>
  <!-- Microsoft からのものを含むすべてのログ -->
  <logger name="*" writeTo="TraceOutput" />

  <!-- 起動の検出を高速化するために、ホスティングライフタイムメッセージをコンソールターゲットに出力します。Microsoft.Hosting.Lifetime はここより下の定義には出力しません -->
  <logger name="Microsoft.Hosting.Lifetime" minlevel="Info" writeTo="LifetimeConsole" final="true" />

  <!-- 重要でない Microsoft ログをスキップして、自分のログのみをログに記録する。システムが出す Warning 以上のログ以外はここより下の定義には出力されません -->
  <logger name="Microsoft.*" maxlevel="Info" final="true" />
  <logger name="System.Net.Http.*" maxlevel="Info" final="true" />

  <!-- 上記で除外したもの以外をファイルに出力 -->
  <logger name="*" writeTo="FileOutput" />
</rules>

Aquí se especifica qué nivel y qué tipo de registros para generar a dónde. Esta descripción se aplica de arriba a arriba.

La primera es name="*" generar todos los registros en el destino porque se especifica el nivel al especificar writeTo . Este target es el especificado en , por lo que aparece en la salida de Visual TraceOutput Studio.

La segunda es Microsoft.Hosting.Lifetime la salida a la salida de registro de la writeTo (コンソール) biblioteca. Las asociaciones de ConsoleLifetime se pueden proteger en consolas como Azure y Docker. minlevel="Info" porque Trace Debug especifica y no se registra. Además, las definiciones posteriores no generan final="true" Microsoft.Hosting.Lifetime registros relacionados.

La tercera name="Microsoft.*" es detener el registro name="System.Net.Http.*" final="true" especificando y registros. name *es un comodín, lo que significa Microsoft System.Net.Http que se refiere a todas las bibliotecas relacionadas. , pero deténgase maxlevel="Info" Trace aquí, Debug Information porque WArningEl Error registro , también se genera en Critical definiciones posteriores.

El cuarto se genera en final="true" un archivo distinto del registro detenido anteriormente.

Registros de archivos

También hay un método de archivado del archivo de registro antiguo en una carpeta independiente para cada fecha con un solo archivo de registro principal.

por ejemplo:

<target xsi:type="File"
        name="FileOutput"
        fileName="${aspnet-appbasepath}/Log.log"
        archiveNumbering="Date"
        archiveEvery="Day"
        archiveFileName="${aspnet-appbasepath}/Archive/Log_{#}.log"
        archiveDateFormat="yyyy-MM-dd"
        maxArchiveFiles="7"
        layout="${layoutDefine}" />

Los parámetros utilizados aquí significan:

Descripción de los parámetros
archivoNumbering Date crea un archivo de archivado por fecha.
archivoTodo El día se utiliza para archivar a diario. También hay maneras de especificar "Mes", "Hora", "Domingo", etc.
archiveFileName Camino al archivo. {#} cambia archivado por archivo.
archiveDateFormat Formato de fecha por fecha de fecha de archivo del nombre de archivo.
maxArchiveFiles Especifica cuántos archivos archivar hasta.

También hay maneras de archivar métodos que no son actuales. Para obtener más información, consulte el sitio web oficial.

Cuando se ejecuta, se ve así:

Enviar correos electrónicos por registro

NLog también le permite enviar correos electrónicos al iniciar sesión. Sin embargo, si envía un correo electrónico como un registro de depuración, se convertirá en demasiado para enviar, Es una buena idea dirigirse solo a niveles de registro limitados, como Error y Fatal. Además, para evitar el riesgo de fallos, como el bloqueo del servidor de correo debido a la transmisión de overs, Se recomienda especificar una cuenta de correo electrónico de solo registro.

A continuación se muestra un ejemplo de una configuración. Si realmente desea enviar correo, siga el servidor SMTP que desea usar.

<targets>
  <target xsi:type="Mail"
          name="SendMail"
          smtpServer="SMTP Server Name"
          smtpPort="25"
          subject="XXXX システムでエラーが発生しました"
          from="aaaa@example.com"
          to="bbbb@example.com"
          enableSsl="False"
          smtpAuthentication="None"
          smtpUserName=""
          smtpPassword=""
          layout="${layoutDefine}"/>
</targets>

<rules>
  <logger name="*" minlevel="Error" writeTo="SendMail" />
</rules>

Escribir registros en la base de datos

NLog también puede escribir registros en la base de datos. El siguiente es un ejemplo, así que consulte el sitio web oficial para obtener más información.

En esta sección se describen los pasos para escribir en SQL ServerSQL Server en un servidor diferente.

En primer lugar, cree una tabla para iniciar sesión en SQL Serversql Server de destino. Puesto que puede elegir el valor que desea escribir, defina lo que necesita como registro como columna.

A continuación se muestra un ejemplo de creación de tablas SQL.

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Log](
  [Id] [int] IDENTITY(1,1) NOT NULL,
  [Application] [nvarchar](50) NOT NULL,
  [Logged] [datetime] NOT NULL,
  [Level] [nvarchar](50) NOT NULL,
  [User] [nvarchar](250) NOT NULL,
  [Message] [nvarchar](max) NOT NULL,
  [Logger] [nvarchar](250) NULL,
  [Callsite] [nvarchar](max) NULL,
  [Exception] [nvarchar](max) NULL,
  CONSTRAINT [PK_dbo.Log] PRIMARY KEY CLUSTERED 
(
  [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

Se requiere una biblioteca de cliente de base System.Data.SqlClient de datos para el procesamiento de bases de datos. Vamos a instalarlo desde NuGet.

Escribe información de base de datos en appsettings.json. nlog.config le permite cargar la información en appsettings.json. La configuración es provisional, así que por favor ístelos de acuerdo con la base de datos real. El nombre de clave es arbitrario, pero es utilizado por nlog.config.

{
  "": "省略",

  "NlogConnection": {
    "DbHost": "ServerName\\SQLEXPRESS",
    "Database": "TestDatabase",
    "User": "UserName",
    "Password": "********"
  }
}

Establezca nlog.config de la siguiente manera:

<targets>
  <target xsi:type="Database"
          name="DatabaseOutput"
          dbProvider="sqlserver"
          dbHost="${configsetting:name=NlogConnection.DbHost}"
          dbDatabase="${configsetting:name=NlogConnection.Database}"
          dbUserName="${configsetting:name=NlogConnection.User}"
          dbPassword="${configsetting:name=NlogConnection.Password}">
    <commandText>
      insert into dbo.Log (
        Application, Logged, [Level], [User], Message, Logger, CallSite, Exception
      ) values (
        @Application, @Logged, @Level, @User, @Message, @Logger, @Callsite, @Exception
      );
    </commandText>
    <parameter name="@application" layout="XXXX System" />
    <parameter name="@logged" layout="${date}" />
    <parameter name="@level" layout="${level}" />
    <parameter name="@user" layout="${aspnet-user-identity}" />
    <parameter name="@message" layout="${message}" />
    <parameter name="@logger" layout="${logger}" />
    <parameter name="@callSite" layout="${callsite:filename=true}" />
    <parameter name="@exception" layout="${exception:tostring}" />
  </target>
</targets>

<rules>
  <logger name="*" writeTo="DatabaseOutput" />
</rules>

Si no hay errores que ejecutar, se escribirá de la siguiente manera:

Por cierto.cs tenga en cuenta que se puede producir un error al intentar escribir registros en la base de datos en una fase temprana, como antes de los métodos de .cs CreateHostBuilder del programa.

Obtener registradores de RequestServices y registrarlos

Puede ser tedioso agregar al constructor cada vez que ILogger cree un nuevo controlador o modelo de página. Alternativamente, RequestServices puede obtener de .

public void OnGet()
{
  // RequestServices から ILogger を取得する
  var logger = (ILogger<IndexModel>)HttpContext.RequestServices.GetService(typeof(ILogger<IndexModel>));

  logger.LogInformation("ページを表示するタイミングでログを出力します。");
}

Si especificar su propio controlador o modelo de página también es engorroso, puede crear métodos de extensión o clases básicas.

public static class AspNetExtention
{
  /// <summary>
  /// ロガーを取得する拡張メソッドです。
  /// </summary>
  public static ILogger<T> GetLogger<T>(this T self) where T : PageModel
    => (ILogger<T>)self.HttpContext.RequestServices.GetService(typeof(ILogger<T>));

  // MVC の場合
  //public static ILogger<T> GetLogger<T>(this T self) where T : Controller
  //  => (ILogger<T>)self.HttpContext.RequestServices.GetService(typeof(ILogger<T>));
}

Casos de uso

public void OnGet()
{
  // RequestServices から ILogger を取得する (this. は必要)
  var logger = this.GetLogger();

  logger.LogInformation("ページを表示するタイミングでログを出力します。");
}