Använda NLog för att logga

Datum för skapande av sida :

Miljö

Visuell studio
  • Visual Studio 2019
ASP.NET kärna
  • 5.0 (MVC, Rakhyvelsida)

Till en början

Med NLog kan du mata ut loggar till filer, e-postmeddelanden och databaser beroende på dina inställningar.

NLog ASP.NET att införlivas i cores standardloggningssystem. Det är möjligt att mata ut loggar enligt inställningarna när du använder standardloggaren.

Om loggnivåer

Microsoft-loggar och NLogs är indelade i sex steg och utdatanivåerna är ungefär desamma:

Nivå MicrosoftNLog
0 Spåra Spåra
1 Debug Debug
2 Information Information om
3 Varning Varna
4 Fel Fel
5 Kritiska Dödlig
(6) - Jag vet inte vad jag ska göra. - Jag har inte tid med det här.

Ju högre nivå, desto viktigare är loggen, och desto mer sannolikt är det att den skrivs oavsett loggutmatningsbegränsningarna.

Loggningsinstruktioner

Distribution av NLog-paket

ASP.NET du har skapat ett Core-projekt lägger du till ett paket.

Högerklicka på Beroenden för projektet och välj Hantera NuGet-paket.

Klicka på fliken Bläddra och skriv NLog i sökfältet om du vill visa NLog-relaterade paket.

Välj NLog och klicka sedan på installationsknappen med den senaste stabila versionen markerad.

Klicka på OK.

Installera även NLog.Web.AspNetCore.

Paketet har lagts till i projektet.

Lägg till nlog.config

Lägg till nlog.config, utdatadefinitionen för NLog-loggen, i projektet. Innehållet är i XML-format, så jag skapade det som en XML-fil. Filnamnet ska vara nlog.config (gemener).

Skapa filen på följande sätt: Detaljerade inställningar kommer att diskuteras senare.

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

Kontrollera att egenskaperna för nlog.config är inställda på Skapa åtgärd: Innehåll, Kopiera till utdatakatalog: Kopiera om det är nytt.

Redigera appsetting.json

Som standard, oavsett hur du anger nlog.config, Information är endast dessa nivåer utdata. Detta beror på att loggning också förlitar sig på appsetting.json.

Öppna appsetting.json Logging.LogLevel.Default och ändra värdet till Trace . Om du använder NLog kan du justera nivån på NLog-sidan, så att du kan mata ut praktiskt taget alla nivåer Trace genom att ställa in appsetting.json.

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

Under utveckling, appsettings. Development.json-inställningarna är laddade, så vi ändrar dem också.

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

Förbereda program för NLog

Lägg till ett program så att du kan logga in på NLog-mekanismen.

Öppna .cs programfil och åtgärda den på följande sätt:

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

Loggning

För MVC-projekt HomeComtroller , för IndexModel Razor-sidor, skulle du ha ILogger<IndexModel> logger vidarebefordrats till konstruktorn. Den är också inställd på _logger i det privata fältet, så att du kan använda den för att logga.

Följande är ett exempel på utdata från en Razor-sida, men MVC kan mata ut med samma kod.

// 省略

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

Vid felsökning tror jag att en loggfil kan göras i projektets mapp.

Du kan kontrollera loggen genom att titta på innehållet i filen.

Exempel på kommentarer från nlog.config

Jag förklarar det i ordning, men jag förklarar inte de mindre viktiga delarna.

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

Det finns parametrar, till exempel loggutmatningsinställningarna för själva NLog.

internalLogFile kommer att vara loggens destination. Detta kan vara till hjälp, till exempel om det finns ett fel i utdata från själva loggen. ${basedir} refererar till programmets körningsmapp.

internalLogLevel är utdatanivån för NLog-loggen. Off Om det är det, kommer det inte att matas ut alls.

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

Variabeln är inställd på vilken layout innehållet i loggen ska matas ut i. Du kan skriva direkt i senare mål, men om du anger flera av samma layout är det enklare att hantera dem i en variabel.

Det är bättre att hänvisa till den officiella webbplatsen för att se vilka parametrar som kan anges i layouten.

Som referens matas de parametrar som anges här ut i följande format:

Innehåll för parameterutmatning
longdate (longdate) Datum- och tidsminuter som "2021-03-17 11:46:36.5034"
händelseegenskaper Visar händelse-ID:t osv. för den loggutmatning som anges av programmet
Nivå Nivåer som Spårning och fel
Meddelande Meddelande som angetts vid programloggning
Undantag Vad händer om du klarar undantag vid programloggning
samtalsplats Loggningsplats, filnamn etc.

Exempel på utdata

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>

Anger målet för utdata. Flera kan anges.

Den första xsi:type="Trace" anger , och loggen skrivs ut i Visual Studio-utdatafönstret. Det kan främst användas för felsökning av körning.

Den andra xsi:type="File" anger och loggar till en fil i den angivna sökvägen. Om du ${shortdate} anger i sökvägen kan du skriva loggen till filen för datumet för loggen vid tidpunkten för loggen. Anger ${aspnet-appbasepath} också rotmappen för webbprojektet. Vid drift är det dock bättre att mata ut loggfiler utanför webbkatalogen för programbyte och säkerhet.

Den tredje anges xsi:type="Console" och kan visas i konsolen i konsolappen. ASP.NET Core i sig inte är en konsol app, men den kan också användas i miljöer som Docker och Azure eftersom tillståndet kan visas i konsolen. Detta är beskrivningen på NLog officiella webbplats.

<!-- ロガー名からターゲットにマップするルール -->
<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>

Här anger du vilken nivå och vilken typ av loggar som ska matas ut till var. Den här beskrivningen tillämpas uppifrån och upp.

Den första är att name="*" mata ut alla loggar till målet eftersom nivån anges när du anger writeTo . Detta target är den angivna i , så den TraceOutput visas i Visual Studio-utdata.

Den andra är Microsoft.Hosting.Lifetime utdata till loggutmatningen i writeTo (コンソール) biblioteket. ConsoleLifetime-associationer kan kontrolleras i konsoler som Azure och Docker. minlevel="Info" eftersom den Trace Debug anger och inte loggas. Efterföljande definitioner matar inte heller ut final="true" Microsoft.Hosting.Lifetime relaterade loggar.

Det tredje name="Microsoft.*" är att sluta logga genom att ange för och name="System.Net.Http.*" final="true" loggar. name *är ett jokertecken, vilket Microsoft System.Net.Http innebär att det refererar till alla relaterade bibliotek. , men stanna här maxlevel="Info" Trace , Debug Information eftersom WArning Error Loggen , , matas också ut i efterföljande Critical definitioner.

Den fjärde matas ut final="true" till en annan fil än loggen som stoppas ovan.

Arkivloggar

Det finns också en metod för att arkivera den gamla loggfilen i en separat mapp för varje datum med endast en huvudloggfil.

Till exempel:

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

Parametrarna som används här betyder:

Beskrivning av parameter
arkiveraNumrering Datum skapar en arkivfil efter datum.
arkivVarje Dagen används för att arkivera dagligen. Det finns också sätt att ange "Månad", "Timme", "Söndag", etc.
arkiveraFileName Sökväg att arkivera till. {#} ändras arkivera för arkiv.
arkiveraDateFormat Datum för datum-format för arkivdatum för filnamnet.
maxArchiveFiler Anger hur många filer som ska arkiveras upp till.

Det finns också sätt att arkivera icke-datummetoder. För mer information, se den officiella webbplatsen.

När den körs ser det ut så här:

Skicka e-post per logg

NLog låter dig också skicka e-postmeddelanden när du loggar. Men om du skickar ett e-postmeddelande som en felsökningslogg blir det för mycket att skicka, Det är en bra idé att endast rikta in sig på begränsade loggnivåer, till exempel Fel och Dödlig. För att undvika risken för fel, till exempel att blockera e-postservern på grund av överföring av overs, Vi rekommenderar att du anger ett e-postkonto endast för loggar.

Följande är ett exempel på en konfiguration. Om du verkligen vill skicka e-post följer du den SMTP-server som du vill använda.

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

Skriva loggar till databasen

NLog kan också skriva loggar till databasen. Följande är ett exempel, så se den officiella webbplatsen för mer information.

I det här avsnittet beskrivs hur du skriver till SQL Server på en annan server.

Skapa först en tabell för loggning i mål-SQL Server. Eftersom du kan välja det värde som ska skrivas definierar du vad du behöver som logg som kolumn.

Följande är ett exempel på tabellskapande 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

Ett databasklientbibliotek System.Data.SqlClient krävs för databasbearbetning. Låt oss installera den från NuGet.

Skriver databasinformation till appsettings.json. nlog.config låter dig läsa in informationen i appsettings.json. Inställningarna är preliminära, så ställ in dem enligt den faktiska databasen. Nyckelnamnet är godtyckligt, men används av nlog.config.

{
  "": "省略",

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

Ange nlog.config enligt följande:

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

Om det inte finns några fel att köra kommer det att skrivas enligt följande:

Observera förresten .cs försök att skriva loggar till databasen i ett tidigt skede, till exempel innan program .cs CreateHostBuilder metoder, misslyckas.

Hämta loggare från RequestServices och logga dem

Det kan vara tråkigt att lägga till konstruktorn varje gång du skapar ILogger en ny styrenhet eller sidmodell. Alternativt kan RequestServices du få från .

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

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

Om det också är besvärligt att ange en egen styrenhet eller sidmodell kan du skapa tilläggsmetoder eller grundläggande klasser.

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

Använda ärenden

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

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