Utilitza NLog per registrar

Data de creació de la pàgina :

Medi ambient

Estudi Visual
  • Estudi Visual 2019
Nucli ASP.NET
  • 5.0 (MVC, pàgina de la navalla)

Al principi

NLog us permet generar registres a fitxers, correus electrònics i bases de dades en funció de la vostra configuració.

NLog ASP.NET incorporar al sistema de registre estàndard del nucli. És possible generar registres d' acord amb la configuració mentre s' usa el registre per omissió.

Quant als nivells de registre

Els registres de Microsoft i els NLogs es divideixen en sis etapes, i els nivells de sortida són aproximadament els mateixos:

Nivell MicrosoftNLog
0 Traça Traça
1 Depuració Depuració
2 Informació Informació
3 Advertència Advertir
4 Error Error
5 Crítica Fatal
(6) (Cap) (Desactivat)

Com més alt sigui el nivell, més important serà el registre, i més probable serà que s'escrigui independentment de les restriccions de sortida del registre.

Instruccions de registre

Implementació del paquet NLog

ASP.NET hàgiu creat un projecte Core, afegiu un paquet.

Feu clic amb el botó dret del ratolí a Dependències del vostre projecte i seleccioneu Gestiona els paquets NuGet.

Feu clic a la pestanya Navega i escriviu NLog al camp de cerca per visualitzar els paquets relacionats amb NLog.

Seleccioneu NLog i, a continuació, feu clic al botó d'instal·lació amb l'última versió estable seleccionada.

Feu clic a D'acord.

Instal·leu també NLog.Web.AspNetCore.

El paquet s'ha afegit al projecte.

Afegeix nlog.config

Afegiu nlog.config, la definició de sortida del registre NLog, al projecte. El contingut té format XML, de manera que l'he creat com a fitxer XML. El nom del fitxer ha de ser nlog.config (minúscula).

Creeu el fitxer de la manera següent: Els paràmetres detallats es discutiran més endavant.

<?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>

Assegureu-vos que les propietats de nlog.config estan definides com a Acció de construcció: Contingut, Copia-ho al directori de sortida: Copia-ho si és nou.

Edita appsetting.json

De manera predeterminada, independentment de com establiu nlog.config, Information només aquests nivells són de sortida. Això es deu al fet que el registre també es basa en appsetting.json.

Obriu appsetting.json Logging.LogLevel.Default i canvieu el valor a Trace . Si utilitzeu NLog, podeu ajustar el nivell al costat NLog, de manera que pugueu generar pràcticament tots els nivells Trace establint appsetting.json.

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

A més, durant el desenvolupament, appsettings. La configuració de Development.json està carregada, de manera que també les estem canviant.

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

S'estan preparant els programes per al NLog

Afegiu un programa perquè pugueu iniciar sessió al mecanisme NLog.

Obriu .cs fitxer del programa i corregiu-lo de la manera següent:

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 のセットアップ
}

Registre

Per a projectes MVC, HomeComtroller per a pàgines d'afaitar, IndexModel havies passat ILogger<IndexModel> logger al constructor. També està establert _logger al camp privat, de manera que podeu utilitzar-lo per registrar-lo.

A continuació es mostra un exemple de sortida des d'una pàgina d'afaitar, però MVC pot emetre amb el mateix codi.

// 省略

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("ページを表示するタイミングでログを出力します。");
  }
}

En depurar, crec que es pot fer un fitxer de registre a la carpeta del projecte.

Podeu comprovar el registre mirant el contingut del fitxer.

Exemple de comentari nlog.config

Ho explico en ordre, però no explico les parts menys importants.

<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">

Hi ha paràmetres, com ara la configuració de sortida del registre per al propi NLog.

internalLogFile serà la destinació del registre. Això pot ser útil, per exemple, si hi ha un error en la sortida del propi registre. ${basedir} fa referència a la carpeta d'execució del programa.

internalLogLevel és el nivell de sortida del registre NLog. Off si ho és, no serà en absolut sortida.

<!-- ログの出力レイアウトを変数 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 s'estableix a la disposició en què es generarà el contingut del registre. Podeu escriure directament als objectius posteriors, però si especifiqueu diversos de la mateixa disposició, és més fàcil gestionar-los en una variable.

És millor referir-se al lloc web oficial per veure quins paràmetres es poden especificar en el disseny.

Com a referència, els paràmetres especificats aquí es sortida en el següent format:

sortida de
Contingut deparàmetres
data llarga Minuts de data i hora com "2021-03-17 11:46:36.5034"
propietats de l'esdeveniment Mostra l' ID d' esdeveniment, etc. de la sortida del registre especificada pel programa
Nivell Nivells com ara Rastreig i Error
Missatge Missatge especificat en el registre del programa
Excepció Què passa si passeu una excepció en el registre de programes
lloc de trucada Ubicació del registre, nom del fitxer, etc.

Exemple de sortida

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 la destinació a generar. Es poden especificar diversos.

El primer xsi:type="Trace" especifica i el registre s'imprimeix a la finestra de sortida del Visual Studio. Es pot utilitzar principalment per a l'execució de depuració.

El segon xsi:type="File" especifica i es registra en un fitxer del camí especificat. Si ${shortdate} especifiqueu en el camí, podeu escriure el registre al fitxer de la data del registre en el moment del registre. També ${aspnet-appbasepath} especifica la carpeta arrel del projecte web. No obstant això, quan s'opera, és millor generar fitxers de registre fora del directori web per a la substitució de programes i la seguretat.

El tercer xsi:type="Console" s'especifica i es pot mostrar a la consola a l'aplicació consola. ASP.NET Core en si no és una aplicació de consola, però també es pot utilitzar en entorns com Docker i Azure perquè l'estat es pot mostrar a la consola. Aquesta és la descripció al lloc 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í especifiqueu quin nivell i quin tipus de registres s' han de generar a on. Aquesta descripció s'aplica de dalt a baix.

El primer és name="*" generar tots els registres a la destinació perquè el nivell s'especifica writeTo mentre s'especifica . Aquest target és l'especificat al , de manera que TraceOutput apareix a la sortida del Visual Studio.

La segona és Microsoft.Hosting.Lifetime la sortida al registre de la writeTo (コンソール) biblioteca. Les associacions ConsoleLifetime es poden protegir en consoles com Azure i Docker. minlevel="Info" perquè Trace Debug especifica , i no està registrat. A més, les definicions subsegüents no surten final="true" Microsoft.Hosting.Lifetime registres relacionats.

La tercera name="Microsoft.*" és name="System.Net.Http.*" deixar de final="true" registrar-se especificant i registrant. name *és un comodí, el que significa Microsoft System.Net.Http que es refereix a totes les biblioteques relacionades. , però atureu-vos maxlevel="Info" Trace aquí, Debug Information perquè WArningEl Error registre , també s'emet en Critical definicions posteriors.

El quart és la sortida a final="true" un fitxer que no sigui el registre aturat més amunt.

Registres d'arxivament

També hi ha un mètode per arxivar el fitxer de registre antic en una carpeta separada per a cada data amb només un fitxer de registre principal.

Per exemple:

<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}" />

Els paràmetres utilitzats aquí signifiquen:

Descripció del paràmetre
arxiuNumbering Date crea un fitxer d'arxiu per data.
arxiuEvery El dia s'utilitza per arxivar diàriament. També hi ha maneres d'especificar "Mes", "Hora", "Diumenge", etc.
fitxer archiveFileName Camí a arxivar a. {#} canvia d'arxiu per arxivament.
arxiuDateFormat Format de data d'arxivament per data del nom del fitxer.
Fitxers maxArchive Especifica quants fitxers s'han d'arxivar.

També hi ha maneres d'arxivar mètodes no datades. Per a més informació, consulteu el lloc web oficial.

Quan s'executa, sembla que:

Enviar correus electrònics per registre

NLog també us permet enviar correus electrònics en registrar-vos. No obstant això, si envieu un correu electrònic, com ara un registre de depuració, esdevindrà massa per enviar, És una bona idea orientar només els nivells de registre limitats, com ara Error i Fatal. A més, per evitar el risc d'avaria, com ara bloquejar el servidor de correu a causa de la transmissió excessiva, Us recomanem que especifiqueu un compte de correu electrònic només de registre.

A continuació es troba un exemple d'una configuració. Si voleu enviar correu, seguiu el servidor SMTP que voleu utilitzar.

<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>

Escriu registres a la base de dades

NLog també pot escriure registres a la base de dades. El següent és un exemple, així que consulteu el lloc web oficial per obtenir més informació.

Aquesta secció descriu els passos per escriure a l'SQL Server en un servidor diferent.

Primer, creeu una taula per iniciar la sessió a l'SQL Server de destinació. Com que podeu triar el valor a escriure, definiu el que necessiteu com a registre com a columna.

A continuació es troba un exemple de creació de taules 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

Cal una biblioteca client de base de dades System.Data.SqlClient per al processament de la base de dades. Instal·lem-lo des de NuGet.

Escriu informació de la base de dades a appsettings.json. nlog.config us permet carregar la informació a appsettings.json. Els paràmetres són provisionals, de manera que si us plau, establiu- los d' acord amb la base de dades real. El nom de la clau és arbitrari, però és utilitzat per nlog.config.

{
  "": "省略",

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

Establiu nlog.config de la manera següent:

<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 hi ha errors per executar, s'escriurà de la següent manera:

Per cert.cs tingueu en compte que intentar escriure registres a la base de dades en una fase primerenca, com abans que el programa .cs CreateHostBuilder mètodes, pot fallar.

Obteniu registres de RequestServices i registreu-los

Pot ser tediós afegir al constructor cada vegada que ILogger creeu un nou controlador o model de pàgina. Alternativament, RequestServices podeu obtenir de .

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

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

Si especificar el vostre propi controlador o model de pàgina també és molest, podeu crear mètodes d'extensió o classes bàsiques.

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 d'ús

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

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