"NLog" naudojimas žurnalui

Puslapio sukūrimo data :

Aplinkos

Vizualinė studija
  • Vizualinė studija 2019
ASP.NET branduolys
  • 5.0 (MVC, Skustuvo puslapis)

Iš pradžių

"NLog" leidžia išvesti žurnalus į failus, el. laiškus ir duomenų bazes, atsižvelgiant į jūsų nustatymus.

"NLog" ASP.NET būti įtrauktas į standartinę "Core" registravimo sistemą. Naudojant numatytąjį kaupiklio žurnalą galima išvesti žurnalus pagal parametrus.

Apie žurnalo lygius

"Microsoft" žurnalai ir "NLogs" yra suskirstyti į šešis etapus, o išvesties lygiai yra maždaug tokie patys:

Lygis MicrosoftNLog
0 Sekimo Sekimo
1 Derinimo Derinimo
2 Informacija Informacija
3 Įspėjimas Įspėti
4 Klaida Klaida
5 Kritinių Mirtinas
(6) (Nėra) (Išjungta)

Kuo aukštesnis lygis, tuo svarbesnis yra žurnalas, ir tuo didesnė tikimybė, kad jis bus parašytas nepriklausomai nuo žurnalo išvesties apribojimų.

Registravimo instrukcijos

NLog paketo diegimas

ASP.NET sukūrėte pagrindinį projektą, pridėkite paketą.

Dešiniuoju pelės mygtuku spustelėkite projekto priklausomybės ir pasirinkite Tvarkyti NuGet paketus.

Spustelėkite skirtuką Naršyti ir ieškos lauke įveskite NLog, kad būtų rodomi su NLog susiję paketai.

Pasirinkite NLog, tada spustelėkite diegimo mygtuką su pasirinkta naujausia stabilia versija.

Spustelėkite Gerai.

Taip pat įdiekite NLog.Web.AspNetCore.

Paketas pridėtas prie projekto.

Pridėti nlog.config

Į projektą įtraukite nlog.config, NLog žurnalo išvesties apibrėžimą. Turinys yra XML formato, todėl sukūriau jį kaip XML failą. Failo vardas turi būti nlog.config (mažoji raidė).

Sukurkite failą taip: Išsamūs nustatymai bus aptarti vėliau.

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

Įsitikinkite, kad nlog.config ypatybės nustatytos kaip Kūrimo veiksmas: Turinys, Kopijuoti į išvesties katalogą: Kopijuoti, jei naujas.

Redaguoti appsetting.json

Pagal numatytuosius nustatymus, nesvarbu, kaip jūs nustatote nlog.config, Information tik šie lygiai yra išvesties. Taip yra todėl, kad registravimas taip pat priklauso nuo appsetting.json.

Atidarykite appsetting.json Logging.LogLevel.Default ir pakeiskite reikšmę į Trace . Jei naudojate "NLog", galite reguliuoti lygį "NLog" pusėje, kad galėtumėte išvesti beveik visus Trace lygius nustatydami appsetting.json.

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

Be to, kūrimo metu, appsettings. Development.json nustatymai yra pakrautas, todėl mes juos taip pat.

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

Programų paruošimas NLog

Įtraukite programą, kad galėtumėte prisijungti prie NLog mechanizmo.

Atidarykite .cs programos failą ir pataisykite jį taip:

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

Registravimo

MVC projektams HomeComtroller , Skustuvo puslapiams, IndexModel būtumėte perduoti ILogger<IndexModel> logger konstruktoriui. Jis taip pat nustatytas _logger privačiame lauke, todėl galite jį naudoti žurnalui.

Toliau pateikiamas išvesties iš Skustuvo puslapio pavyzdys, tačiau MVC gali išvesti tą patį 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("ページを表示するタイミングでログを出力します。");
  }
}

Derinant, manau, kad projekto aplanke galima sukurti žurnalo failą.

Žurnalą galite patikrinti peržiūrėdami failo turinį.

Nlog.config komentarų pavyzdys

Aš paaiškinti, kad, bet aš ne paaiškinti mažiau svarbių dalių.

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

Yra parametrų, pvz., paties NLog žurnalo išvesties parametrai.

internalLogFile bus žurnalo paskirties vieta. Tai gali būti naudinga, pavyzdžiui, jei paties žurnalo išvestyje yra klaida. ${basedir} nurodo programos vykdymo aplanką.

internalLogLevel yra NLog žurnalo išvesties lygis. Off jei taip, tai nebus produkcija.

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

Kintamasis nustatomas pagal tai, kokiame makete bus išvestis žurnalo turinyje. Galite įvesti tiesiai į vėlesnius tikslinius adresatus, bet jei nurodysite to paties maketo kartotinį, juos lengviau valdyti viename kintamajame.

Geriau kreiptis į oficialią svetainę, kad pamatytumėte, kokius parametrus galima nurodyti išdėstyme.

Nuorodai čia nurodyti parametrai yra išvestis tokiu formatu:

Parametro išvesties turinys
longdate Datos ir laiko minutės, pvz., "2021-03-17 11:46:36.5034"
įvykio ypatybės Rodomas programos nurodytos žurnalo išvesties įvykio ID ir kt.
Lygio Lygiai, pvz., Sekimas ir klaida
Pranešimą Programos registravimui nurodytas pranešimas
Išimtis Ką daryti, jei perduodate išimtį programų registravimui
iškviečia Registravimo vieta, failo vardas ir kt.

Išvesties pavyzdys

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>

Nurodo išvesties tikslą. Galima nurodyti kelis.

Pirmasis xsi:type="Trace" nurodo , o žurnalas spausdinamas Visual Studio išvesties lange. Jis visų pirma gali būti naudojamas derinimo vykdymui.

Antrasis xsi:type="File" nurodo ir registruoja failą nurodytu maršrutu. Jei ${shortdate} nurodote maršrute, žurnalo metu galite įrašyti žurnalą į žurnalo datos failą. Taip pat ${aspnet-appbasepath} nurodo šakninį žiniatinklio projekto aplanką. Tačiau, kai veikia, geriau išvesti žurnalo failus už žiniatinklio katalogo programos pakeitimo ir saugos.

Trečiasis yra xsi:type="Console" nurodytas ir gali būti rodomas konsolėje konsolės programoje. ASP.NET Core pati nėra konsolės programa, tačiau ji taip pat gali būti naudojama tokiose aplinkose kaip "Docker" ir "Azure", nes būsena gali būti rodoma konsolėje. Tai yra "NLog" oficialios svetainės aprašymas.

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

Čia nurodote, kokio lygio ir kokio tipo žurnalus išvesti į kur. Šis aprašas taikomas iš viršaus į viršų.

Pirmasis yra name="*" išvesti visus žurnalus į tikslą, nes lygis writeTo nurodomas nurodant . Tai target nurodyta , todėl ji rodoma Visual Studio TraceOutput išvestyje.

Antrasis yra Microsoft.Hosting.Lifetime išėjimas į žurnalo išvestį writeTo (コンソール) bibliotekoje. ConsoleLifetime asociacijas galima patikrinti konsolėse, tokiose kaip Azure ir Docker. minlevel="Info" nes jis Trace Debug nurodo , ir nėra užregistruotas. Be to, vėlesni apibrėžimai nėra išvesties final="true" Microsoft.Hosting.Lifetime susijusių žurnalų.

Trečiasis name="Microsoft.*" yra name="System.Net.Http.*" sustabdyti registravimą final="true" nurodant ir žurnalus. name *yra pakaitos simbolis, o Microsoft System.Net.Http tai reiškia, kad jis susijęs su visomis susijusiomis bibliotekomis. , bet sustokite čia maxlevel="Info" Trace , Debug Information nes WArning Error , žurnalas taip pat yra išvestis vėlesniuose Critical apibrėžimuose.

Ketvirtasis yra final="true" išvestis į failą, išskyrus žurnalą, kuris buvo sustabdytas aukščiau.

Archyvuoti žurnalus

Taip pat yra būdas archyvuoti seną žurnalo failą atskirame aplanke kiekvienai datai su tik vienu pagrindiniu žurnalo failu.

Pavyzdžiui:

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

Čia naudojami parametrai reiškia:

Parametro aprašas
archyvasNumeravimas Data sukuria archyvo failą pagal datą.
archyvasEvery Diena naudojama archyvuoti kasdien. Taip pat yra būdų, kaip nurodyti "Mėnuo", "Valanda", "Sekmadienis" ir kt.
archyvasFileName Kelias į archyvą. {#} pasikeičia archyvo pagrindu.
archyvasDateFormatas Failo vardo archyvavimo pagal datą datos formatas.
maxArchiveFiles Nurodo, kiek failų archyvuoti iki.

Taip pat yra būdų archyvuoti ne datos metodus. Daugiau informacijos rasite oficialioje svetainėje.

Kai vykdoma, atrodo taip:

Siųsti el. laiškus į žurnalą

NLog taip pat leidžia jums siųsti laiškus, kai registruojatės. Tačiau, jei siunčiate el. laišką, pvz., derinimo žurnalą, jis taps per daug siunčiamas, Tai gera idėja nukreipti tik ribotą žurnalo lygį, pavyzdžiui, klaidų ir fatal. Be to, siekiant išvengti gedimo rizikos, pvz., blokuoti pašto serverį dėl perpildyto perdavimo, Rekomenduojame nurodyti tik žurnalo el. pašto paskyrą.

Toliau pateikiamas konfigūracijos pavyzdys. Jei norite iš tikrųjų siųsti laiškus, sekite SMTP serverį, kurį norite naudoti.

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

Žurnalų rašymas į duomenų bazę

NLog taip pat gali rašyti žurnalus į duomenų bazę. Toliau pateikiamas pavyzdys, todėl išsamesnės informacijos ieškokite oficialioje svetainėje.

Šiame skyriuje aprašomi veiksmai, kaip rašyti į SQL serverį kitame serveryje.

Pirmiausia sukurkite lentelę, skirtą prisijungti paskirties SQL serveryje. Kadangi galite pasirinkti vertę, kurią norite rašyti, nurodykite, ko jums reikia kaip žurnalą kaip stulpelį.

Toliau pateikiamas lentelės kūrimo SQL pavyzdys.

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

Duomenų bazei apdoroti reikalinga duomenų bazės kliento System.Data.SqlClient biblioteka. Įdiekime jį iš NuGet.

Įrašo duomenų bazės informaciją appsettings.json. nlog.config leidžia įkelti informaciją appsettings.json. Parametrai yra preliminarūs, todėl nustatykite juos pagal faktinę duomenų bazę. Rakto pavadinimas yra savavališkas, bet jį naudoja nlog.config.

{
  "": "省略",

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

Nustatykite nlog.config taip:

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

Jei nėra klaidų paleisti, jis bus parašytas taip:

Beje.cs pažymi, kad bandymas rašyti žurnalus į duomenų bazę ankstyvame etape, pvz., prieš programos .cs CreateHostBuilder metodus, gali nepavykti.

Gaukite loggers iš RequestServices ir užregistruokite juos

Gali būti nuobodu pridėti prie konstruktoriaus kiekvieną kartą, kai ILogger kuriate naują valdiklį ar puslapio modelį. Arba RequestServices galite gauti iš .

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

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

Jei nurodyti savo valdiklį arba puslapio modelį taip pat sudėtinga, galite sukurti plėtinio metodus arba pagrindines klases.

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

Naudoti atvejus

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

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