Используйте NLog для входа в журнал

Дата создания страницы :

окружающая среда

Визуальная студия
  • Визуальная студия 2019
ASP.NET ядро
  • 5.0 (MVC, страница Бритва)

сначала

NLog позволяет создавать журналы файлов, электронных писем и баз данных в зависимости от настроек.

NLog ASP.NET быть включен в стандартную систему регистрации ядра. При использовании регистратора по умолчанию можно выводить журналы в соответствии с настройками.

Об уровнях журнала

Журналы Майкрософт и 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": "*"
}

Кроме того, во время разработки, appsettings. Настройки 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 のセットアップ
}

лесозаготовка

Для проектов HomeComtroller MVC, для страниц Razor, вы были бы переданы IndexModel 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})" />

Переменная устанавливается на то, что макет содержимое журнала будет выход дюйма Вы можете ввести непосредственно в более поздние цели, но если вы укажете несколько одного и того же макета, легче управлять ими в одной переменной.

Лучше обратиться на официальный сайт, чтобы узнать, какие параметры могут быть указаны в макете.

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

Параметр вывода содержимого
longdate Дата и время минут, таких как "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, потому что состояние может отображаться в консоли. Это описание на официальном сайте 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>

Здесь вы укажете, какой уровень и какой тип журналов для вывода, где. Это описание применяется сверху вверх.

Во-первых, name="*" выработать все журналы к цели, поскольку writeTo уровень указан при указании. Это target указано в , поэтому он TraceOutput появляется в выходе Visual Studio.

Microsoft.Hosting.LifetimeВо-вторых, выход на выход журнала в writeTo (コンソール) библиотеке. КонсолиLifetime ассоциации могут быть проверены в консолях, таких как 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}" />

Используемые здесь параметры означают:

Описание параметра
архивНумеров Дата создает архив файла по дате.
архив Все День используется для архивов на ежедневной основе. Есть также способы указать "Месяц", "Час", "Воскресенье" и т.д.
archiveFileName Путь к архиву. изменения на архивной основе.
archiveDateFormat Дата за датой формат даты архива имени файла.
maxArchiveFiles Уточняется, сколько файлов в архиве до.

Существуют также способы архивировать недаты методов. Для получения дополнительной информации см.

При выполнении, это выглядит так:

Отправка электронных писем на журнал

NLog также позволяет отправлять электронные письма при регистрации. Однако, если вы отправляете электронное письмо, такое как журнал отладки, это станет слишком много, чтобы отправить, Это хорошая идея, чтобы целевой только ограниченные уровни журнала, такие как ошибка и фатальной. Кроме того, чтобы избежать риска сбоя, например, блокировки почтового сервера из-за овсяной передачи, Рекомендуем указать учетную запись электронной почты только для журнала.

Ниже приводится пример конфигурации. Если вы хотите отправить почту, следуйте серверу 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 также может писать журналы в базу данных. Ниже приводится пример, поэтому, пожалуйста, обратитесь к официальному сайту для получения подробной информации.

В этом разделе описаны шаги для записи на сервере S'L на другом сервере.

Во-первых, создайте таблицу для входа в целевой сервер S'L. Так как вы можете выбрать значение для записи, определить, что вам нужно, как журнал в качестве столбца.

Ниже приводится пример создания таблицы S'L.

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