NLog gebruiken om te loggen

Aanmaakdatum van pagina :

Milieu

Visuele studio
  • Visuele Studio 2019
ASP.NET Kern
  • 5.0 (MVC, De pagina van het scheermes)

In het begin

Met NLog kunt u logboeken uitvoeren naar bestanden, e-mails en databases, afhankelijk van uw instellingen.

NLog ASP.NET worden opgenomen in het standaard logboeksysteem van Core. Het is mogelijk om logboeken uit te voeren volgens de instellingen tijdens het gebruik van de standaardlogger.

Informatie over logboekniveaus

Microsoft-logboeken en NLogs zijn verdeeld in zes fasen en de uitvoerniveaus zijn ongeveer hetzelfde:

Microsoft NLog op niveau
0 Trace Trace
1 Debug Debug
2 Informatie Info
3 Waarschuwing Waarschuwen
4 Fout Fout
5 Kritische Fatale
(6) (Geen) (Uit)

Hoe hoger het niveau, hoe belangrijker het logboek is en hoe groter de kans dat het wordt geschreven, ongeacht de beperkingen van de logboekuitvoer.

Instructies voor logboekregistratie

NLog-pakketimplementatie

ASP.NET u een Core-project hebt gemaakt, voegt u een pakket toe.

Klik met de rechtermuisknop op Afhankelijkheden voor uw project en selecteer NuGet-pakketten beheren.

Klik op het tabblad Bladeren en typ NLog in het zoekveld om NLog-gerelateerde pakketten weer te geven.

Selecteer NLog en klik vervolgens op de installatieknop met de nieuwste stabiele versie geselecteerd.

Klik op OK.

Installeer ook NLog.Web.AspNetCore.

Het pakket is aan het project toegevoegd.

Nlog.config toevoegen

Voeg nlog.config, de uitvoerdefinitie van het NLog-logboek, toe aan het project. De inhoud is in XML-formaat, dus ik heb het gemaakt als een XML-bestand. De bestandsnaam moet nlog.config (kleine letters) zijn.

Maak het bestand als volgt: Gedetailleerde instellingen worden later besproken.

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

Zorg ervoor dat de eigenschappen van nlog.config zijn ingesteld op Actie bouwen: Inhoud, Kopiëren naar uitvoermap: Kopiëren als nieuw.

Appsetting.json bewerken

Het maakt niet uit hoe u nlog.config instelt, Information alleen deze niveaus worden uitgevoerd. Dit komt omdat logboek registratie ook afhankelijk is van appsetting.json.

Open appsetting.json Logging.LogLevel.Default en wijzig de waarde in Trace . Als u NLog gebruikt, kunt u het niveau aan de NLog-kant aanpassen, zodat u vrijwel alle niveaus kunt uitvoeren Trace door appsetting.json in te stellen.

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

Ook, tijdens de ontwikkeling, appsettings. Development.json-instellingen worden geladen, dus we wijzigen ze ook.

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

Programma's voorbereiden voor NLog

Voeg een programma toe zodat u zich kunt aanmelden bij het NLog-mechanisme.

Open .cs programmabestand en los het als volgt op:

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

Logboekregistratie

Voor MVC-projecten, HomeComtroller voor Razor-pagina's, IndexModel zou je zijn doorgegeven aan de ILogger<IndexModel> logger constructeur. Het is ook ingesteld _logger op in het privéveld, zodat u het kunt gebruiken om te loggen.

Het volgende is een voorbeeld van uitvoer van een Razor-pagina, maar MVC kan met dezelfde code worden uitgevoerd.

// 省略

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

Bij foutopsporing denk ik dat er een logbestand kan worden gemaakt in de map van het project.

U kunt het logboek controleren door naar de inhoud van het bestand te kijken.

Voorbeeld nlog.config commentaar

Ik leg het in volgorde uit, maar ik leg de minder belangrijke delen niet uit.

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

Er zijn parameters, zoals de logboekuitvoerinstellingen voor NLog zelf.

internalLogFile is de bestemming van het logboek. Dit kan bijvoorbeeld handig zijn als er een fout is opgetreden in de uitvoer van het logboek zelf. ${basedir} verwijst naar de uitvoeringsmap van het programma.

internalLogLevel is het uitvoerniveau van het NLog-logboek. Off als dat zo is, zal het helemaal geen uitvoer zijn.

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

De variabele is ingesteld op in welke lay-out de inhoud van het logboek wordt uitgevoerd. U kunt rechtstreeks in latere doelen typen, maar als u meerdere van dezelfde lay-out opgeeft, is het eenvoudiger om ze in één variabele te beheren.

Het is beter om naar de officiële website te verwijzen om te zien welke parameters in de lay-out kunnen worden gespecificeerd.

Ter referentie worden de hier opgegeven parameters uitgevoerd in de volgende indeling:

Inhoud van parameteruitvoer
lange datum Datum en tijd minuten zoals "2021-03-17 11:46:36.5034"
gebeurtenis-eigenschappen Geeft de gebeurtenis-ID, enz. weer van de logboekuitvoer die door het programma is opgegeven
Niveau Niveaus zoals Tracering en Fout
Bericht Bericht opgegeven in programmalogging
Uitzondering Wat als u een uitzondering doorgeeft bij het vastleggen van programma's
callsite Registratielocatie, bestandsnaam, enz.

Voorbeeld van uitvoer

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>

Hiermee geeft u het doel op dat moet worden uitgevoerd. Er kunnen er meerdere worden opgegeven.

De eerste xsi:type="Trace" geeft aan en het logboek wordt afgedrukt in het uitvoervenster van Visual Studio. Het kan voornamelijk worden gebruikt voor het opsporen van foutopsporing.

De tweede xsi:type="File" geeft een bestand in het opgegeven pad op en meldt zich aan. Als u ${shortdate} in het pad opgeeft, kunt u het logboek schrijven naar het bestand van de datum van het logboek op het moment van het logboek. ${aspnet-appbasepath} Hiermee geeft u ook de hoofdmap voor het webproject op. Tijdens het werken is het echter beter om logboekbestanden buiten de webmap uit te voeren voor programmavervanging en beveiliging.

De derde is xsi:type="Console" opgegeven en kan worden weergegeven in de console in de console-app. ASP.NET Core zelf is geen console-app, maar kan ook worden gebruikt in omgevingen zoals Docker en Azure omdat de status kan worden weergegeven in de console. Dit is de beschrijving op de officiële website van 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>

Hier geeft u op welk niveau en welk type logboeken naar waar moet worden uitgevoerd. Deze beschrijving wordt van boven naar boven toegepast.

De eerste is om name="*" alle logboeken naar het doel uit te voeren omdat het niveau is writeTo opgegeven tijdens het opgeven van . Dit target is de opgegeven in , zodat deze TraceOutput wordt weergegeven in de Visual Studio-uitvoer.

De tweede is Microsoft.Hosting.Lifetime uitvoer naar de logboekuitvoer in de writeTo (コンソール) bibliotheek. ConsoleLifetime-koppelingen kunnen worden ingecheckt in consoles zoals Azure en Docker. minlevel="Info" omdat het Trace Debug opgeeft en niet wordt geregistreerd. Latere definities voeren ook geen final="true" Microsoft.Hosting.Lifetime gerelateerde logboeken uit.

De derde name="Microsoft.*" is het stoppen van name="System.Net.Http.*" logboekregistratie door voor en final="true" logboeken op te geven. name *is een jokerteken, wat betekent Microsoft System.Net.Http dat het verwijst naar alle gerelateerde bibliotheken. , maar stop maxlevel="Info" Trace hier, Debug Information want WArningHet Error logboek , wordt ook uitgevoerd in volgende Critical definities.

De vierde is uitvoer naar final="true" een ander bestand dan het logboek dat hierboven is gestopt.

Logboeken archiveren

Er is ook een methode om het oude logboekbestand voor elke datum in een aparte map te archiveren met slechts één hoofdlogboekbestand.

Bijvoorbeeld:

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

De parameters die hier worden gebruikt, betekenen:

Parameterbeschrijving
archiefNummering Date maakt een archiefbestand op datum.
archiefIedereen Day wordt dagelijks gebruikt om te archiveren. Er zijn ook manieren om "Maand", "Uur", "Zondag", enz. op te geven.
archiefFileName Pad naar archief naar. {#} verandert per archief.
archiefDateFormat Datum-voor-datum archiefdatumnotatie van de bestandsnaam.
maxArchiveBestanden Hiermee geeft u op tot hoeveel bestanden moet worden gearchiveerd.

Er zijn ook manieren om niet-datummethoden te archiveren. Zie voor meer informatie de officiële website.

Wanneer uitgevoerd, ziet het er als volgt uit:

E-mails verzenden per logboek

Met NLog kunt u ook e-mails verzenden bij het loggen. Als u echter een e-mail verzendt, zoals een foutopsporingslogboek, wordt deze te veel om te verzenden, Het is een goed idee om slechts beperkte logboekniveaus te targeten, zoals Error en Fatal. Om het risico op storingen te voorkomen, zoals het blokkeren van de e-mailserver als gevolg van overstransmissie, We raden u aan een e-mailaccount met alleen logboeken op te geven.

Hier volgt een voorbeeld van een configuratie. Als u daadwerkelijk e-mail wilt verzenden, volgt u de SMTP-server die u wilt gebruiken.

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

Logboeken naar de database schrijven

NLog kan ook logboeken naar de database schrijven. Het volgende is een voorbeeld, dus raadpleeg de officiële website voor meer informatie.

In deze sectie worden de stappen beschreven die u op een andere server naar SQL Server wilt schrijven.

Maak eerst een tabel voor het aanmelden bij de doel-SQL Server. Aangezien u de waarde kunt kiezen om te schrijven, definieert u wat u nodig hebt als logboek als kolom.

Hier volgt een voor beeld van SQL voor het maken van tabellen.

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

Een databaseclientbibliotheek System.Data.SqlClient is vereist voor databaseverwerking. Laten we het installeren vanaf NuGet.

Schrijft database informatie naar appsettings.json. Met nlog.config kunt u de informatie laden in appsettings.json. De instellingen zijn voorlopig, dus stel ze in op basis van de werkelijke database. De sleutelnaam is willekeurig, maar wordt gebruikt door nlog.config.

{
  "": "省略",

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

Stel nlog.config als volgt in:

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

Als er geen fouten zijn om uit te voeren, wordt het als volgt geschreven:

Trouwens.cs merk op dat het proberen om logboeken naar de database te schrijven in een vroeg stadium, zoals vóór programma .cs CreateHostBuilder methoden, kan mislukken.

Loggers loggen bij RequestServices en deze registreren

Het kan vervelend zijn om elke keer dat u ILogger een nieuwe controller of paginamodel maakt, aan de constructor toe te voegen. Als alternatief RequestServices kunt u krijgen van .

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

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

Als het opgeven van uw eigen controller of paginamodel ook omslachtig is, kunt u extensiemethoden of basisklassen maken.

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

Gebruikscases

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

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