Uporaba NLoga za prijavo

Datum ustvarjanja strani :

Okolje

Vizualni studio
  • Vizualni studio 2019
ASP.NET Core
  • 5.0 (MVC, stran z britvicami)

Sprva

NLog vam omogoča izhodne dnevnike v datoteke, e-poštna sporočila in zbirke podatkov, odvisno od vaših nastavitev.

NLog ASP.NET biti vključen v jedrni standardni sistem za sečnje. Med uporabo privzetega dnevnika je mogoče izpisati dnevnike v skladu z nastavitvami.

O ravni dnevnika

Microsoftovi dnevniki in NLogi so razdeljeni na šest stopenj, izhodne ravni pa so približno enake:

Raven
MicrosoftNLog
0 Sled Sled
1 Debug Debug
2 Informacije Info
3 Opozorilo Opozori
4 Napaka Napaka
5 Kritično Usodna
(6) (None) (Izklop)

Višja kot je raven, pomembnejša je hlod in bolj je velika, da bo napisana ne glede na izhodne omejitve dnevnika.

Navodila za beleženje dnevnika

Uvajanje paketa NLog

ASP.NET ste ustvarili temeljni projekt, dodajte paket.

Z desno tipko miške kliknite Odvisnosti za projekt in izberite Upravljanje paketov NuGet.

Kliknite zavihek Prebrskaj in v iskalno polje vnesite NLog, da prikažete pakete, povezane z NLogom.

Izberite NLog in nato kliknite gumb namestitve z izbrano najnovejšo stabilno različico.

Kliknite V redu.

Namestite tudi NLog.Web.AspNetCore.

Paket je bil dodan projektu.

Dodaj nlog.config

V projekt dodajte nlog.config, izhodno definicijo dnevnika NLog. Vsebina je v obliki XML, zato sem jo ustvaril kot datoteko XML. Ime datoteke mora biti nlog.config (manjše črke).

Ustvarite datoteko na naslednji način: Podrobne nastavitve bodo obravnavane pozneje.

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

Preverite, ali so lastnosti nlog.config nastavljene na Build Action: Content, Copy to Output Directory: Copy if New.

Urejanje aplikacije.json

Privzeto, ne glede na to, kako nastavite nlog.config, so samo Information te ravni izhod. To je zato, ker sečnja se zanaša tudi na appsetting.json.

Odprite appsetting.json Logging.LogLevel.Default in spremenite vrednost v Trace . Če uporabljate NLog, lahko prilagodite raven na strani NLog, tako da lahko izhod praktično vse ravni z nastavitvijo Trace appsetting.json.

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

Prav tako, med razvojem, appsettings. Nastavitve development.json so naložene, zato jih tudi spreminjamo.

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

Priprava programov za NLog

Dodajte program, da se lahko prijavite v mehanizem NLog.

Odprite .cs programsko datoteko in jo popravite na naslednji način:

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

Prijavi

Za MVC projekte, za strani Razor, bi bili prenesti na HomeComtroller IndexModel ILogger<IndexModel> logger konstruktorja. Nastavljen je tudi na zasebno polje, tako da ga lahko uporabite za _logger beleženje.

To je primer izhoda iz strani Razor, vendar lahko MVC izhod z isto kodo.

// 省略

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

Pri odpravljanju napak mislim, da je mogoče v mapi projekta izneti dnevniške datoteke.

Dnevnik lahko preverite tako, da pogledate vsebino datoteke.

Vzorčni komentar nlog.config

To razlagam po vrstnem redu, ampak ne razlagam manj pomembnih delov.

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

Obstajajo parametri, na primer nastavitve izhoda dnevnika za sam NLog.

internalLogFile bo cilj dnevnika. To je lahko koristno, na primer, če je prišlo do napake pri izhodu dnevnika samega. se nanaša na mapo za izvajanje ${basedir} programa.

internalLogLevel je izhodna raven dnevnika NLog. če Off je, ne bo izhodna.

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

Spremenljivka je nastavljena na to, v kateri postavitvi bo vsebina dnevnika izhodna. V kasnejše cilje lahko vnesete neposredno, če pa določite več istih postavitev, jih je lažje upravljati v eni spremenljivki.

Bolje se je sklicevati na uradno spletno stran, da vidite, katere parametre je mogoče določiti v postavitvi.

Za referenco so parametri, navedeni tukaj, izhodni v naslednji obliki:

Izhodna
vsebina parametra
longdate Datum in čas minute, kot so "2021-03-17 11:46:36.5034"
lastnosti dogodka Prikaže ID dogodka itd.
Ravni Ravni, kot sta sledenje in napaka
Sporočilo Sporočilo, navedeno v dnevniku programa
Izjema Kaj, če v dnevniku programa prenesete izjemo
klicni Mesto beleženje, ime datoteke itd.

Izhodni primer

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>

Določa cilj za izhod. Določite lahko več.

Prvi določa , dnevnik pa je natisnjena v izhodnem xsi:type="Trace" oknu Visual Studio. Uporablja se lahko predvsem za odpravljanje napak.

Druga določa in se prijavi v datoteko na xsi:type="File" določeni poti. Če določite pot, lahko dnevnik napišete v datoteko datuma dnevnika v času ${shortdate} dnevnika. Določa ${aspnet-appbasepath} tudi korensko mapo za spletni projekt. Vendar pa je med delovanjem bolje izstopati dnevniške datoteke izven spletnega imenika za zamenjavo in varnost programa.

Tretja je navedena in jo je mogoče prikazati v xsi:type="Console" konzoli v aplikaciji konzole. ASP.NET Core ni konzolna aplikacija, lahko pa se uporablja tudi v okoljih, kot sta Docker in Azure, ker je stanje mogoče prikazati v konzoli. To je opis na uradni spletni strani 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>

Tukaj določite raven in vrsto dnevnikov za izhod do kje. Ta opis se uporablja od vrha do vrha.

Prvi je izhod vseh dnevnikov v cilj, ker je raven name="*" writeTo določena med določanjem . To je navedeno v , tako da se prikaže v target TraceOutput izhodu Visual Studio.

Druga je izhod Microsoft.Hosting.Lifetime na izhod dnevnika v writeTo (コンソール) knjižnici. ConsoleLifetime povezave lahko preverite v konzolah, kot sta Azure in Docker. ker minlevel="Info" določa , in ni Trace Debug prijavljen. Tudi naslednje definicije ne izstopajo final="true" Microsoft.Hosting.Lifetime povezanih dnevnikov.

Tretji je ustaviti beleženje tako, da določite za in name="Microsoft.*" name="System.Net.Http.*" final="true" dnevnike. *je nadomestni znak, kar pomeni, da se nanaša na vse name Microsoft System.Net.Http sorodne knjižnice. , vendar ustavite tukaj maxlevel="Info" Trace , Debug Information ker Dnevnik , je tudi izhod v naslednji WArning Error Critical definiciji.

Četrti je izhod v datoteko, ki ni dnevnik final="true" ustavljen zgoraj.

Arhiviranje dnevnikov

Obstaja tudi način arhiviranje stare dnevniške datoteke v ločeni mapi za vsak datum z samo eno glavno dnevniški datoteko.

Na primer:

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

Tukaj uporabljeni parametri pomenijo:

Opis
parametra
arhivŠtevilka Datum ustvari arhivsko datoteko po datumu.
arhivEvery Dan se uporablja za dnevno arhiviranje. Obstajajo tudi načini za določanje "Mesec", "Ura", "Nedelja", itd.
arhivFileName Pot do arhiva do. {#} spremembe na podlagi arhiva po arhivu.
arhivDateFormat Oblika datuma po datumu arhiviranja imena datoteke.
maxArhiveFiles Določa, koliko datotek je treba arhivirati.

Obstajajo tudi načini arhiviranja ne-date metod. Če želite več informacij, glejte uradno spletno stran.

Ko se izvrši, je videti tako:

Pošiljanje e-poštnih sporočil na dnevnik

NLog omogoča tudi pošiljanje e-poštnih sporočil ob prijavi. Če pa pošljete e-poštno sporočilo, kot je dnevnik odpravljanja napak, bo postalo preveč za pošiljanje, Dobra ideja je, da ciljate samo omejene ravni dnevnika, kot sta Napaka in Usodno. Da bi se izognili tveganju okvare, kot je blokiranje poštnega strežnika zaradi prenosa Priporočamo, da določite e-poštni račun samo za dnevnik.

To je primer konfiguracije. Če želite dejansko poslati pošto, sledite strežniku SMTP, ki ga želite uporabiti.

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

Pisanje dnevnikov v zbirko podatkov

NLog lahko piše dnevnike tudi v zbirko podatkov. To je primer, zato si za podrobnosti oglejte uradno spletno stran.

V tem razdelku so opisani koraki za pisanje v strežnik SQL Server v drugem strežniku.

Najprej ustvarite tabelo za prijavo v ciljni SQL Server. Ker lahko izberete vrednost za pisanje, določite, kaj potrebujete kot dnevnik kot stolpec.

To je primer sql ustvarjanja tabele.

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

Za obdelavo zbirke podatkov je potrebna knjižnica odjemalca System.Data.SqlClient zbirke podatkov. Namestimo ga iz NuGeta.

Piše podatke o zbirki podatkov na appsettings.json. nlog.config omogoča nalaganje informacij v appsettings.json. Nastavitve so privlečne, zato jih nastavite glede na dejansko zbirko podatkov. Ključno ime je poljubno, vendar ga uporablja nlog.config.

{
  "": "省略",

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

Nastavite nlog.config na naslednji nač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>

Če ni napak za zagon, bo napisano na naslednji način:

Mimogrede.cs da poskus pisanja dnevnikov v zbirko podatkov v zgodnji fazi, na primer pred .cs CreateHostBuilder metod, ne uspe.

Get loggers from RequestServices in jih prijavite

Konstruktorju je lahko težko dodati vsakič, ko ustvarite nov krmilnik ILogger ali model strani. Druga možnost je, da RequestServices lahko dobiš od .

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

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

Če je tudi določanje lastnega krmilnika ali modela strani, lahko ustvarite načine razširitve ali osnovne razrede.

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

Primeri uporabe

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

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