Brug NLog til at logge

Dato for oprettelse af side :

Miljø

Visual Studio
  • Visual Studio 2019
ASP.NET Kerne
  • 5.0 (MVC, Razor side)

I første omgang

NLog giver dig mulighed for at sende logfiler til filer, e-mails og databaser afhængigt af dine indstillinger.

NLog ASP.NET indarbejdes i kernens standard logføringssystem. Det er muligt at udskrive logfiler i henhold til indstillingerne, mens du bruger standardloggeren.

Om logniveauer

Microsoft-logfiler og NLogs er opdelt i seks faser, og outputniveauerne er stort set de samme:

Niveau MicrosoftNLog
0 Spore Spore
1 Debug Debug
2 Oplysninger Info
3 Advarsel Advare
4 Fejl Fejl
5 Kritiske Fatal
(6) (Ingen) (Fra)

Jo højere niveau, jo vigtigere er loggen, og jo mere sandsynligt er det, at den skrives uanset logoutputbegrænsningerne.

Logføringsinstruktioner

Installation af NLog-pakke

ASP.NET du har oprettet et Kerneprojekt, skal du tilføje en pakke.

Højreklik på Afhængigheder for projektet, og vælg Administrer nugetpakker.

Klik på fanen Gennemse, og skriv NLog i søgefeltet for at få vist NLog-relaterede pakker.

Vælg NLog, og klik derefter på installationsknappen med den nyeste stabile version valgt.

Klik på OK.

Installer også NLog.Web.AspNetCore.

Pakken er føjet til projektet.

Tilføj nlog.config

Føj nlog.config, outputdefinitionen af NLog-logfilen, til projektet. Indholdet er i XML-format, så jeg oprettede det som en XML-fil. Filnavnet skal være nlog.config (små bogstaver).

Opret filen på følgende måde: Detaljerede indstillinger vil blive diskuteret senere.

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

Kontroller, at egenskaberne for nlog.config er angivet til Build Action: Content, Copy to Output Directory: Copy if New.

Rediger appsetting.json

Uanset hvordan du angiver nlog.config, er det som standard Information kun disse niveauer, der udskrives. Dette skyldes, at logføring også er afhængig af appsetting.json.

Åbn appsetting.json Logging.LogLevel.Default , og ret værdien til Trace . Hvis du bruger NLog, kan du justere niveauet på NLog-siden, så du kan udskrive stort set alle niveauer Trace ved at indstille appsetting.json.

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

Også under udvikling, appsettings. Development.json indstillinger er indlæst, så vi ændrer dem så godt.

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

Forberedelse af programmer til NLog

Tilføj et program, så du kan logge ind på NLog-mekanismen.

Åbn .cs programfil, og ret den på følgende måde:

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

Logføring

For MVC-projekter HomeComtroller , for Razor sider, ville du have IndexModel været ILogger<IndexModel> logger videregivet til konstruktøren. Den er også indstillet til _logger i det private felt, så du kan bruge den til at logge.

Følgende er et eksempel på output fra en Razor-side, men MVC kan udskrive med den samme kode.

// 省略

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

Når fejlfinding, tror jeg, at en logfil kan foretages i mappen af projektet.

Du kan kontrollere loggen ved at se på indholdet af filen.

Eksempel på nlog.config-kommentar

Jeg forklarer det i rækkefølge, men jeg forklarer ikke de mindre vigtige dele.

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

Der er parametre, f.eks.

internalLogFile vil være destinationen for loggen. Dette kan f.eks. være nyttigt, hvis der er en fejl i selve loggens output. ${basedir} henviser til programmets kørselsmappe.

internalLogLevel er outputniveauet i NLog-logfilen. Off Hvis det er, vil det slet ikke være output.

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

Variablen er indstillet til, hvilket layout indholdet af loggen vil blive output i. Du kan skrive direkte i senere mål, men hvis du angiver flere af de samme layout, er det lettere at administrere dem i én variabel.

Det er bedre at henvise til den officielle hjemmeside for at se, hvilke parametre der kan specificeres i layoutet.

De parametre, der angives her, er output i følgende format:

Indhold af parameteroutput
langfrist dato Dato- og klokkeslætsminutter som "2021-03-17 11:46:36.5034"
egenskaber for hændelse Viser hændelses-id'et osv.
Niveau Niveauer som Sporing og Fejl
Besked Meddelelse angivet i programlogføring
Undtagelse Hvad hvis du består undtagelsen i programlogføring
opkaldswebsted Logføringsplacering, filnavn osv.

Eksempel på output

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>

Angiver den destination, der skal udskrives. Der kan angives flere.

Den første xsi:type="Trace" angiver , og loggen udskrives i Visual Studio-outputvinduet. Den kan primært bruges til fejlfinding.

Den anden xsi:type="File" angiver og logger på en fil i den angivne sti. Hvis du ${shortdate} angiver i stien, kan du skrive logfilen til filen for datoen for loggen på tidspunktet for loggen. Angiver også ${aspnet-appbasepath} rodmappen til webprojektet. Men når du kører, er det bedre at udskrive logfiler uden for webmappen til programudskiftning og sikkerhed.

Den tredje er xsi:type="Console" angivet og kan vises i konsollen i konsolappen. ASP.NET Core i sig selv ikke er en konsolapp, men den kan også bruges i miljøer som Docker og Azure, fordi tilstanden kan vises i konsollen. Dette er beskrivelsen på NLog officielle hjemmeside.

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

Her kan du angive, hvilket niveau og hvilken type logfiler der skal udskrives til hvor. Denne beskrivelse anvendes fra top til top.

Den første er at name="*" sende alle logfiler til destinationen, fordi niveauet er writeTo angivet under angivelse af . Dette target er angivet i , så det TraceOutput vises i Visual Studio-outputtet.

Den anden er Microsoft.Hosting.Lifetime output til logoutputtet i writeTo (コンソール) biblioteket. ConsoleLifetime-tilknytninger kan tjekkes ind i konsoller som Azure og Docker. minlevel="Info" fordi den Trace Debug angiver og ikke logføres. De efterfølgende definitioner udskriver heller ikke final="true" Microsoft.Hosting.Lifetime relaterede logfiler.

Den tredje name="Microsoft.*" er at name="System.Net.Http.*" stoppe final="true" logføringen ved at angive for og logfiler. name *er et jokertegn, hvilket Microsoft System.Net.Http betyder, at det refererer til alle relaterede biblioteker. , men stop maxlevel="Info" Trace her, Debug Information fordi WArning Error , er log også output i efterfølgende Critical definitioner.

Den fjerde er output til final="true" en anden fil end den logfil, der er stoppet ovenfor.

Arkivere logfiler

Der findes også en metode til arkivering af den gamle logfil i en separat mappe for hver dato med kun én hovedlogfil.

F.eks.:

<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 parametre, der bruges her, betyder:

Beskrivelse af parameter
arkivNummerering Dato opretter en arkivfil efter dato.
arkivEvery Dag bruges til at arkivere på daglig basis. Der er også måder at angive "Måned", "Time", "søndag" osv.
archiveFileName Sti at arkivere til. {#} ændringer på arkiv-for-arkiv-basis.
arkivDateFormat Dato for dato arkiv datoformat for filnavnet.
maxArchiveFiles Angiver, hvor mange filer der skal arkiveres op til.

Der er også måder at arkivere ikke-dato metoder. For mere information, se den officielle hjemmeside.

Når det udføres, ser det sådan ud:

Send e-mails pr. log

NLog giver dig også mulighed for at sende e-mails, når du logger. Men hvis du sender en e-mail som en fejlfindingslog, bliver det for meget at sende, Det er en god ide kun at målrette mod begrænsede logniveauer, f.eks. For at undgå risikoen for fejl, f.eks. Vi anbefaler, at du angiver en e-mail-konto, der kun er logget på.

Følgende er et eksempel på en konfiguration. Hvis du rent faktisk vil sende e-mail, skal du følge den SMTP-server, du vil bruge.

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

Skrive logfiler til databasen

NLog kan også skrive logfiler til databasen. Følgende er et eksempel, så se den officielle hjemmeside for detaljer.

I dette afsnit beskrives trinnene til at skrive til SQL Server på en anden server.

Opret først en tabel til logføring i SQL Server-destinationen. Da du kan vælge den værdi, der skal skrives, skal du definere, hvad du har brug for som en log som en kolonne.

Følgende er et eksempel på tabeloprettelse 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

Der kræves et databaseklientbibliotek System.Data.SqlClient til databasebehandling. Lad os installere det fra NuGet.

Skriver databaseoplysninger til appsettings.json. nlog.config giver dig mulighed for at indlæse oplysningerne i appsettings.json. Indstillingerne er foreløbige, så angiv dem i henhold til den faktiske database. Nøglenavnet er vilkårligt, men bruges af nlog.config.

{
  "": "省略",

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

Angiv nlog.config på følgende måde:

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

Hvis der ikke er nogen fejl at køre, vil det blive skrevet som følger:

Af den måde.cs bemærke, at forsøge at skrive logfiler til databasen på et tidligt tidspunkt, såsom før programmet .cs CreateHostBuilder metoder, kan mislykkes.

Hent logføringer fra RequestServices, og logfør dem

Det kan være kedeligt at føje til konstruktøren, hver gang du ILogger opretter en ny controller eller sidemodel. Alternativt RequestServices kan du få fra .

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

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

Hvis det også er besværligt at angive din egen controller eller sidemodel, kan du oprette udvidelsesmetoder eller grundlæggende 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>));
}

Brug sager

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

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