Utilizați NLog pentru a vă înregistra

Data creării paginii :

Mediu

Studio vizual
  • Studio vizual 2019
ASP.NET Core
  • 5.0 (MVC, pagina razor)

La început

NLog vă permite să afișați jurnalele în fișiere, e-mailuri și baze de date, în funcție de setările dvs.

NLog ASP.NET fi încorporat în sistemul standard de logare al nucleului. Este posibil să scoateți jurnalele în funcție de setări în timp ce utilizați înregistratorul implicit.

Despre nivelurile de jurnal

Jurnalele microsoft și NLogurile sunt împărțite în șase etape, iar nivelurile de ieșire sunt aproximativ aceleași:

Nivel MicrosoftNLog
0 Urmă Urmă
1 Depanare Depanare
2 Informaţii Informaţii
3 Avertizare Avertiza
4 Eroare Eroare
5 Critice Fatal
(6) (Nici unul) (Oprit)

Cu cât este mai mare nivelul, cu atât este mai important jurnalul și cu atât este mai probabil să fie scris indiferent de constrângerile de ieșire a jurnalului.

Instrucțiuni de înregistrare în jurnal

Implementare pachet NLog

ASP.NET ați creat un proiect Nucleu, adăugați un pachet.

Faceți clic cu dreapta pe Dependențe pentru proiect și selectați Gestionare pachete NuGet.

Faceți clic pe fila Răsfoire și tastați NLog în câmpul de căutare pentru a afișa pachete legate de NLog.

Selectați NLog, apoi faceți clic pe butonul de instalare cu cea mai recentă versiune stabilă selectată.

Faceți clic pe OK.

De asemenea, instalați NLog.Web.AspNetCore.

Pachetul a fost adăugat la proiect.

Adaugă nlog.config

Adăugați nlog.config, definiția de ieșire a jurnalului NLog, la proiect. Conținutul este în format XML, așa că l-am creat ca fișier XML. Numele fișierului trebuie să fie nlog.config (minuscule).

Creați fișierul după urmează: Setările detaliate vor fi discutate mai târziu.

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

Asigurați-vă că proprietățile nlog.config sunt setate la Acțiune de compilare: Conținut, Copiere în directorul de ieșire: Copiați dacă este nou.

Editare appsetting.json

În mod implicit, indiferent de modul în care setați nlog.config, Information numai aceste niveluri sunt de ieșire. Acest lucru se datorează faptului că înregistrarea în jurnal se bazează, de asemenea, pe appsetting.json.

Deschideți appsetting.json Logging.LogLevel.Default și modificați valoarea în Trace . Dacă utilizați NLog, puteți ajusta nivelul din partea NLog, astfel încât să puteți afișa practic toate nivelurile Trace prin setarea appsetting.json.

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

De asemenea, în timpul dezvoltării, appsettings. Setările Development.json sunt încărcate, așa că le schimbăm și pe ele.

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

Pregătirea programelor pentru NLog

Adăugați un program astfel încât să vă puteți conecta la mecanismul NLog.

Deschideți fișierul program .cs și remediați-l după urmează:

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

Logare

Pentru proiectele HomeComtroller MVC, pentru paginile Razor, IndexModel ai fi fost transmis ILogger<IndexModel> logger constructorului. De asemenea, este setat _logger în câmpul privat, astfel încât să îl puteți utiliza pentru a vă conecta.

Următorul este un exemplu de ieșire dintr-o pagină razor, dar MVC poate ieșire cu același cod.

// 省略

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

Când depanare, cred că un fișier jurnal se poate face în folderul proiectului.

Puteți verifica jurnalul uitându-vă la conținutul fișierului.

Exemplu de comentariu nlog.config

Îți explic în ordine, dar nu-ți explic părțile mai puțin importante.

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

Există parametri, ar fi setările de ieșire jurnal pentru NLog în sine.

internalLogFile va fi destinația jurnalului. Acest lucru poate fi util, de exemplu, dacă există o eroare în ieșirea jurnalului în sine. ${basedir} se referă la folderul de execuție al programului.

internalLogLevel este nivelul de ieșire al jurnalului NLog. Off dacă este, nu va fi deloc de ieșire.

<!-- ログの出力レイアウトを変数 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})" />

Variabila este setată la ce aspect va fi redat conținutul jurnalului. Aveți posibilitatea să tastați direct în ținte ulterioare, dar dacă specificați mai multe din același aspect, este mai ușor să le gestionați într-o singură variabilă.

Este mai bine să vă referiți la site-ul oficial pentru a vedea ce parametri pot fi specificați în aspect.

Pentru referință, parametrii specificați aici sunt redați în următorul format:

Conținutul de ieșire al
parametrilor
dată lungă Data și ora minute, ar fi 2021-03-17 11:46:36.5034
proprietăți eveniment Afișează ID-ul evenimentului etc. al ieșirii jurnal specificate de program
Nivel Niveluri precum Trasare și eroare
Mesaj Mesaj specificat în înregistrarea în jurnal a programului
Excepţie Ce se întâmplă dacă treci excepție în înregistrarea în jurnal a programului
callsite Locația de înregistrare în jurnal, numele fișierului etc.

Exemplu de ieșire

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>

Specifică ținta de ieșire. Pot fi specificate mai multe.

Primul xsi:type="Trace" specifică , iar jurnalul este imprimat în fereastra de ieșire Visual Studio. Poate fi folosit în principal pentru depanarea execuției.

Al doilea xsi:type="File" specifică și se conectează la un fișier din calea specificată. Dacă ${shortdate} specificați în cale, aveți posibilitatea să scrieți jurnalul în fișierul datei jurnalului în momentul jurnalului. De ${aspnet-appbasepath} asemenea, specifică folderul rădăcină pentru proiectul Web. Cu toate acestea, atunci când operează, este mai bine să se afișeze fișiere jurnal în afara directorului Web pentru înlocuirea programului și securitate.

Al treilea este xsi:type="Console" specificat și poate fi afișat în consolă în aplicația consolei. ASP.NET Core în sine nu este o aplicație de consolă, dar poate fi utilizată și în medii precum Docker și Azure, deoarece starea poate fi afișată în consolă. Aceasta este descrierea de pe site-ul oficial 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>

Aici specificați ce nivel și ce tip de jurnale să se afișeze unde. Această descriere se aplică de sus în sus.

Primul este să name="*" afișați toate jurnalele la țintă, deoarece nivelul este writeTo specificat în timp ce specificați . Aceasta target este specificația în , deci TraceOutput apare în ieșirea Visual Studio.

Al doilea este Microsoft.Hosting.Lifetime ieșirea la ieșirea jurnalului din writeTo (コンソール) bibliotecă. Asociațiile ConsoleLifetime pot fi verificate în console precum Azure și Docker. minlevel="Info" deoarece Trace Debug specifică și nu este înregistrat în jurnal. De asemenea, definițiile ulterioare nu final="true" Microsoft.Hosting.Lifetime afișează jurnalele asociate.

Al treilea name="Microsoft.*" este să name="System.Net.Http.*" opriți înregistrarea în jurnal final="true" specificând și jurnalele. name *este un metacaracter, ceea ce înseamnă Microsoft System.Net.Http că se referă la toate bibliotecile asociate. , dar opri aici maxlevel="Info" Trace , pentru Debug InformationWArning Error , , jurnal este, de asemenea, de ieșire în Critical definițiile ulterioare.

Al patrulea este ieșirea final="true" într-un alt fișier decât jurnalul oprit mai sus.

Jurnale de arhivă

Există, de asemenea, o metodă de arhivare a fișierului jurnal vechi într-un folder separat pentru fiecare dată cu un singur fișier jurnal principal.

De exemplu:

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

Parametrii utilizați aici înseamnă:

Descrierea
parametrilor
arhivăNumărare Data creează un fișier arhivă după dată.
arhivaTot Ziua este folosit pentru a arhiva pe o bază de zi cu zi. Există, de asemenea, modalități de a specifica "Lună", "Oră", "Duminică" etc.
arhivăFileName Cale de arhivare. {#} se modifică în funcție de arhivă.
arhivăDateFormat Formatul datei de arhivare a numelui fișierului.
maxArchiveFiles Specifică câte fișiere să arhiveze până la.

Există, de asemenea, modalități de a arhiva metodele care nu sunt date. Pentru mai multe informații, consultați site-ul oficial.

Când este executat, se pare ca aceasta:

Trimiterea e-mailurilor per jurnal

NLog vă permite, de asemenea, să trimiteți e-mailuri atunci când vă conectați. Cu toate acestea, dacă trimiteți un e-mail, ar fi un jurnal de depanare, acesta va deveni prea mult pentru a trimite, Este o idee bună să vizați doar niveluri limitate de jurnal, ar fi Eroare și Fatal. În plus, pentru a evita riscul de defectare, ar fi blocarea serverului de e-mail din cauza transmiterii over-urilor, Vă recomandăm să specificați un cont de e-mail doar pentru jurnal.

Următorul este un exemplu de configurație. Dacă doriți să trimiteți efectiv e-mailuri, urmați serverul SMTP pe care doriți să îl utilizați.

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

Scrierea jurnalelor în baza de date

NLog poate scrie, de asemenea, jurnale în baza de date. Următorul este un exemplu, așa că vă rugăm să consultați site-ul oficial pentru detalii.

Această secțiune descrie pașii pentru a scrie la SQL Server pe un alt server.

Mai întâi, creați un tabel pentru conectarea la serverul SQL țintă. Deoarece aveți posibilitatea să alegeți valoarea de scris, definiți ceea ce aveți nevoie ca jurnal ca coloană.

Următorul este un exemplu de tabel de creare 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

Este necesară o bibliotecă client a bazei de date System.Data.SqlClient pentru procesarea bazei de date. Să-l instalăm din NuGet.

Scrie informații despre baza de date pentru appsettings.json. nlog.config vă permite să încărcați informațiile în appsettings.json. Setările sunt tentative, așa că vă rugăm să le setați în funcție de baza de date reală. Numele cheie este arbitrar, dar este folosit de nlog.config.

{
  "": "省略",

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

Setați nlog.config după urmează:

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

Dacă nu există erori de executat, aceasta va fi scrisă după urmează:

Apropo.cs rețineți că încercarea de a scrie jurnale în baza de date într-un stadiu incipient, ar fi înainte de programul .cs CreateHostBuilder metode, poate să nu reușească.

Obțineți înregistratoare de la RequestServices și înregistrați-le

Poate fi plictisitor să adăugați la constructor de fiecare dată când ILogger creați un controler nou sau un model de pagină. Alternativ, RequestServices puteți obține de la .

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

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

Dacă specificarea propriului controler sau a propriului model de pagină este, de asemenea, greoaie, puteți crea metode de extensie sau clase de bază.

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

Utilizarea carcaselor

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

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