Увійдіть до журналу за допомогою NLog

Дата створення сторінки :

Середовищі

Візуальна студія
  • Visual Studio 2019
ASP.NET ядро
  • 5.0 (MVC, сторінка бритви)

Спочатку

NLog дозволяє виводити журнали у файли, електронні листи та бази даних залежно від ваших налаштувань.

NLog ASP.NET бути включений в стандартну систему журналювання ядра. Вивід журналів можна виводити відповідно до параметрів під час використання типового журналу журналу.

Про рівні журналу

Журнали Microsoft і NLogs діляться на шість етапів, а рівні виводу приблизно однакові:

Вирівнювання MicrosoftNLog
0 Трасування Трасування
1 Налагодження Налагодження
2 Інформації Інформація
3 Попередження Попередити
4 Помилка Помилка
5 Критичних Фатальним
(6) (Немає) (Вимкнено)

Чим вище рівень, тим важливіше журнал, і тим більша ймовірність того, що він буде записаний незалежно від обмежень виводу журналу.

Інструкції з ведення журналу

Розгортання пакета NLog

ASP.NET ви створили проект Core, додайте пакет.

Клацніть правою кнопкою миші елементи Залежності для вашого проекту та виберіть пункт Керування пакетами NuGet.

Перейдіть на вкладку Огляд і введіть NLog у полі пошуку, щоб відобразити пакети, пов'язані з NLog.

Виберіть NLog, а потім натисніть кнопку установки з останньою стабільною версією.

Натисніть кнопку OK.

Також інсталюйте NLog.Web.AspNetCore.

Пакет додано до проекту.

Додати nlog.config

Додайте nlog.config, вихідне визначення журналу NLog, до проекту. Вміст має формат XML, тому я створив його як XML-файл. Ім'я файлу має бути nlog.config (у нижньому регістрі).

Створіть файл наступним чином: Детальні налаштування будуть розглянуті пізніше.

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

Переконайтеся, що для властивостей nlog.config встановлено значення Дія збірки: Вміст, Копіювати до каталогу виводу: Копіювати, якщо новий.

Редагування файлу appsetting.json

Типово, незалежно від того, як ви встановлюєте nlog.config, Information виводяться лише ці рівні. Це тому, що журналювання також покладається на appsetting.json.

Відкрийте файл appsetting.json Logging.LogLevel.Default і змініть значення на Trace . Якщо ви використовуєте NLog, ви можете налаштувати рівень на стороні NLog, щоб ви могли вивести практично всі рівні, Trace встановивши appsetting.json.

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

Крім того, під час розробки, аплікації. Налаштування Development.json завантажуються, тому ми змінюємо їх також.

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

Підготовка програм для NLog

Додайте програму, щоб ви могли увійти в механізм NLog.

Відкрийте .cs програму і виправте її наступним чином:

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

Журналювання

Для проектів MVC HomeComtroller , для сторінок IndexModel Razor, ви б ILogger<IndexModel> logger були передані конструктору. Він також встановлений в _logger приватному полі, так що ви можете використовувати його для журналу.

Нижче наведено приклад виводу зі сторінки Razor, але MVC може виводити з тим же кодом.

// 省略

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

При налагодженні, я думаю, що файл журналу може бути зроблено в папці проекту.

Ви можете перевірити журнал, дивлячись на вміст файлу.

Зразок коментаря nlog.config

Я пояснюю це по порядку, але я не пояснюю менш важливі частини.

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

Існують параметри, такі як параметри виводу журналу для самого NLog.

internalLogFile буде місцем призначення журналу. Це може бути корисно, наприклад, при наявності помилки у виводі самого журналу. ${basedir} посилається на папку виконання програми.

internalLogLevel — це вихідний рівень журналу NLog. Off якщо так, то він взагалі не буде виведений.

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

Змінна встановлюється в якому макеті буде виведено вміст журналу. Ви можете вводити текст безпосередньо в пізніші цілі, але якщо ви вкажете декілька однакових макетів, легше керувати ними в одній змінній.

Краще звернутися на офіційний сайт, щоб подивитися, які параметри можна вказати в макеті.

Для довідки вказані тут параметри виводяться в такому форматі:

Вихідний вміст параметра
довгий час Хвилини дати й часу, такі як "2021-03-17 11:46:36.5034"
властивості події Показує ідентифікатор події тощо виводу журналу, вказаного програмою
Рівень Такі рівні, як трасування та помилка
Повідомлення Повідомлення, указане під час журналювання програм
Винятком Що робити, якщо ви проходять виняток у програмі журналювання
номерний об'їд Місце ведення журналу, ім'я файлу тощо.

Приклад виводу

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>

Визначає кінцеве значення для виводу. Можна вказати кілька.

Перший вказує xsi:type="Trace" , і журнал друкується у вікні виводу Visual Studio. Він може бути використаний в основному для налагодження виконання.

Другий вказує xsi:type="File" та реєструє файл за вказаним шляхом. Якщо ${shortdate} вказати шлях, можна записати журнал у файл дати журналу на момент журналу. Також ${aspnet-appbasepath} указує кореневу папку веб-проекту. Однак при експлуатації краще виводити файли журналу за межі веб-каталогу для заміни програми і безпеки.

Третій xsi:type="Console" вказаний і може відображатися в консолі в консольному додатку. ASP.NET Core не є консольним додатком, але його також можна використовувати в таких середовищах, як Docker і Azure, оскільки стан може відображатися в консолі. Про це йдеться в описі на офіційному сайті НЛог.

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

Тут ви можете вказати, який рівень і який тип журналів слід виводити туди. Цей опис застосовується зверху догори.

По-перше, name="*" вивести всі журнали до кінцевого значення, оскільки рівень writeTo задається під час зазначення . Це target зазначено у програмі , тому він TraceOutput з'являється у виводі Visual Studio.

Другий - Microsoft.Hosting.Lifetime вивід до виводу журналу в writeTo (コンソール) бібліотеці. Асоціації ConsoleLifetime можна перевіряти в таких консолях, як Azure і Docker. minlevel="Info" оскільки він Trace Debug указує , і не записуються до журналу. Крім того, наступні визначення не виводяться final="true" Microsoft.Hosting.Lifetime пов'язані журнали.

Третій name="Microsoft.*" — припинити name="System.Net.Http.*" final="true" журналювання, вказавши для журналів і журналів. name *є символом узагальнення, що означає, Microsoft System.Net.Http що він відноситься до всіх пов'язаних бібліотек. , але зупиніться maxlevel="Info" Trace тут , тому Debug Information що WArningЖурнал Error , , також вивід у наступних Critical визначеннях.

Четвертий вивід у final="true" файл, крім журналу, зупиненого вище.

Журнали архіву

Існує також спосіб архівації старого файлу журналу в окремій папці для кожної дати лише з одним основним файлом журналу.

Наприклад:

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

Параметри, що використовуються тут, означають:

Опис параметра
архівНумерація Date створює файл архіву за датою.
архівВивияви День використовується для архівування на щоденній основі. Є також способи вказати "Місяць", "Година", "Неділя" і т.д.
ім'я файлу архіву Шлях до архіву до. {#} змінюється на основі архівації.
архівФормату Формат дати архіву імені файлу за датою.
максимальна кількість файлів архію Визначає кількість файлів для архівації.

Існують також способи архівування нестандартних методів. Для отримання додаткової інформації дивіться офіційний сайт.

При виконанні виглядає наступним чином:

Надсилати повідомлення електронної пошти за журнал

NLog також дозволяє відправляти електронні листи при реєстрації. Однак, якщо ви надішлете повідомлення електронної пошти, наприклад, журнал налагодження, його стане занадто Варто орієнтуватися лише на обмежені рівні журналу, такі як Error і Fatal. Крім того, щоб уникнути ризику збою, наприклад, блокування поштового сервера через передачу overs, Рекомендовано вказати обліковий запис електронної пошти лише для журналу.

Нижче наведено приклад конфігурації. Якщо ви хочете насправді відправити пошту, дотримуйтесь СЕРВЕРА SMTP ви хочете використовувати.

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

Запис журналів до бази даних

NLog також може записувати журнали до бази даних. Нижче наведено приклад, тому, будь ласка, зверніться до офіційного веб-сайту для отримання детальної інформації.

У цьому розділі описано кроки записування на SQL Server на іншому сервері.

Спочатку створіть таблицю для журналювання в цільовому SQL Server. Оскільки ви можете вибрати значення для запису, визначте, що вам потрібно, як журнал як стовпець.

Нижче наведено приклад створення таблиці 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

Для обробки бази даних System.Data.SqlClient потрібна клієнтська бібліотека бази даних. Давайте встановимо його з NuGet.

Записує інформацію про базу даних на appsettings.json. nlog.config дозволяє завантажувати інформацію в appsettings.json. Параметри є під сумнівом, тому, будь ласка, встановіть їх відповідно до фактичної бази даних. Назва ключа довільна, але використовується nlog.config.

{
  "": "省略",

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

Встановіть nlog.config наступним чином:

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

Якщо помилок для запуску немає, вона буде записана наступним чином:

До речі.cs що спроба запису журналів в базу даних на ранній стадії, наприклад, до того, як програмні CreateHostBuilder .cs, може вийти з ладу.

Отримайте лісорубів від RequestServices та зайдіть до них

Це може бути стомлюючим для додавання в конструктор кожного разу, коли ви ILogger створюєте новий контролер або модель сторінки. Крім того, RequestServices ви можете отримати від .

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

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

Якщо вказати власний контролер або модель сторінки також громіздко, ви можете створити методи розширення або базові класи.

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

Використання інцидентів

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

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