Günlüğe kaydetmek için NLog'yi kullanma
Ortam
- Visual Studio
-
- Visual Studio 2019
- ASP.NET Çekirdek
-
- 5.0 (MVC, Razor sayfası)
İlk başta
NLog, ayarlarınıza bağlı olarak dosyalara, e-postalara ve veritabanlarına günlüklerin çıktısını almanızı sağlar.
NLog ASP.NET core'un standart günlük sistemine dahil edilecektir. Varsayılan günlükçü kullanılırken günlükleri ayarlara göre çıkarmak mümkündür.
Günlük düzeyleri hakkında
Microsoft günlükleri ve NLog'lar altı aşamaya ayrılır ve çıktı düzeyleri kabaca aynıdır:
Düzey | Microsoft | NLog |
---|---|---|
0 | Izleme | Izleme |
1 | Hata ayıklama | Hata ayıklama |
2 | Bilgi | Bilgi |
3 | Uyarı | Uyarmak |
4 | Hata | Hata |
5 | Kritik | Ölümcül |
(6) | (Yok) | (Kapalı) |
Düzey ne kadar yüksekse, günlük o kadar önemlidir ve günlük çıktı kısıtlamalarına bakılmaksızın yazılması o kadar olasıdır.
Günlüğe kaydetme yönergeleri
NLog Paket Dağıtımı
ASP.NET bir Çekirdek projesi oluşturduysanız, bir paket ekleyin.
Projeniz için Bağımlılıklar'ı sağ tıklatın ve NuGet Paketlerini Yönet'i seçin.
Gözat sekmesini tıklatın ve NLog ile ilgili paketleri görüntülemek için arama alanına NLog yazın.
NLog'u seçin ve ardından en son kararlı sürümün seçili olduğu yükle düğmesini tıklatın.
Tamam'ı tıklatın.
Ayrıca NLog.Web.AspNetCore'u yükleyin.
Paket projeye eklendi.
nlog.config ekle
Projeye NLog günlüğünün çıktı tanımı olan nlog.config ekleyin. İçerik XML biçiminde, bu yüzden xml dosyası olarak oluşturdum. Dosya adı nlog.config (küçük harf) olmalıdır.
Dosyayı aşağıdaki gibi oluşturun: Ayrıntılı ayarlar daha sonra tartışılacaktır.
<?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 özelliklerinin Yapı Eylemi: İçerik, Çıktı Dizinine Kopyala: Yeniyse Kopyala olarak ayarlandığından emin olun.
Appsetting.json'ı düzenleme
Varsayılan olarak, nlog.config dosyasını nasıl ayarlarsanız ayarlayın, Information
yalnızca bu düzeyler çıktıdır.
Bunun nedeni, günlüğe kaydetmenin appsetting.json'a da dayanmasıdır.
appsetting.json adresini açın Logging.LogLevel.Default
ve değeri ' olarak Trace
değiştirin.
NLog kullanıyorsanız, NLog tarafındaki düzeyi ayarlayabilirsiniz, böylece Trace
appsetting.json'ı ayarlayarak hemen hemen tüm düzeylerin çıktısını alabilirsiniz.
{
"Logging": {
"LogLevel": {
"Default": "Trace",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Ayrıca, geliştirme sırasında, uygulamalar. Geliştirme.json ayarları yüklendi, bu yüzden onları da değiştiriyoruz.
{
"DetailedErrors": true,
"Logging": {
"LogLevel": {
"Default": "Trace",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
NLog için program hazırlama
NLog mekanizmasında oturum açabilmeniz için bir program ekleyin.
.cs program dosyasını açın ve aşağıdaki gibi düzeltin:
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 のセットアップ
}
Günlüğü
MVC projeleri HomeComtroller
için , Razor sayfaları için, IndexModel
ILogger<IndexModel> logger
oluşturucuya geçirilirdiniz.
Ayrıca özel alanda da _logger
ayarlanır, böylece günlüğe kaydetmek için kullanabilirsiniz.
Aşağıda Razor sayfasından çıktı örneği verilmiştir, ancak MVC aynı kodla çıktı alabilir.
// 省略
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("ページを表示するタイミングでログを出力します。");
}
}
Hata ayıklarken, projenin klasöründe bir günlük dosyası yapılabileceğini düşünüyorum.
Dosyanın içeriğine bakarak günlüğü kontrol edebilirsiniz.
Örnek nlog.config yorumu
Sırayla açıklıyorum ama daha az önemli kısımları açıklamıyorum.
<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'un kendisi için günlük çıktı ayarları gibi parametreler vardır.
internalLogFile
günlüğün hedefi olacaktır. Bu, örneğin günlüğün çıktısında bir hata varsa yararlı olabilir. ${basedir}
programın yürütme klasörüne başvurur.
internalLogLevel
NLog günlüğünün çıkış düzeyidir. Off
eğer öyleyse, hiç çıkış olmayacaktır.
<!-- ログの出力レイアウトを変数 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})" />
Değişken, günlüğün içeriğinin hangi düzende çıktılanacağına ayarlanır. Daha sonraki hedeflere doğrudan yazabilirsiniz, ancak aynı düzenin katlarını belirtirseniz, bunları tek bir değişkende yönetmek daha kolaydır.
Düzende hangi parametrelerin belirtilebileceğini görmek için resmi web sitesine başvurmak daha iyidir.
Başvuru için, burada belirtilen parametreler aşağıdaki biçimde çıktıdır:
Parametre | çıktı içeriği |
---|---|
uzun zaman | "2021-03-17 11:46:36.5034" gibi tarih ve saat dakikaları |
olay özellikleri | Program tarafından belirtilen günlük çıktısının olay kimliği vb. |
Düzey | İzleme ve Hata gibi düzeyler |
İleti | Program günlüğünde belirtilen ileti |
Özel durum | Program günlüğünde özel durum geçirirseniz ne olur? |
Callsite | Günlük konumu, dosya adı vb. |
Çıktı örneği
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>
Çıktı hedefi belirtir. Birden çok belirtilebilir.
İlki xsi:type="Trace"
belirtir ve günlük Visual Studio çıktı penceresinde yazdırılır.
Öncelikle hata ayıklama yürütme için kullanılabilir.
İkincisi, xsi:type="File"
belirtilen yoldaki bir dosyayı belirtir ve günlüğe kaydeder.
Yolda ${shortdate}
belirtirseniz, günlüğü günlüğün tarihindeki dosyaya yazabilirsiniz.
Ayrıca, ${aspnet-appbasepath}
Web projesinin kök klasörünü de belirtir.
Ancak, çalışırken, program değiştirme ve güvenlik için Günlük dosyalarını Web dizininin dışında çıkarmak daha iyidir.
Üçüncüsü xsi:type="Console"
belirtilir ve konsol uygulamasında konsolda görüntülenebilir.
ASP.NET Core'un kendisi bir konsol uygulaması değildir, ancak durum konsolda görüntülenebildiğinden Docker ve Azure gibi ortamlarda da kullanılabilir.
Bu, NLog resmi web sitesindeki açıklamadır.
<!-- ロガー名からターゲットにマップするルール -->
<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>
Burada, hangi düzeyin ve ne tür günlüklerin nereye çıkart verileceğini belirtirsiniz. Bu açıklama yukarıdan üste uygulanır.
Birincisi, name="*"
belirtilirken düzey belirtildiğinden, hedefe tüm günlüklerin writeTo
çıktısını almaktır.
Bu , target
içinde belirtilendir, bu nedenle TraceOutput
Visual Studio çıktısında görünür.
İkincisi, Microsoft.Hosting.Lifetime
kitaplıktaki günlük çıktısına writeTo (コンソール)
çıktıdır.
ConsoleLifetime ilişkileri Azure ve Docker gibi konsollarda iade edilebilir.
minlevel="Info"
Trace
Debug
belirttiğinden ve günlüğe kaydedilmediğinden.
Ayrıca, sonraki tanımlar ilgili günlüklerin çıktısını final="true"
Microsoft.Hosting.Lifetime
yapmaz.
Üçüncüsü, name="Microsoft.*"
name="System.Net.Http.*"
için ve final="true"
günlükleri belirterek günlüğe kaydetmeyi durdurmaktır.
name
*bir joker karakterdir, bu da Microsoft
System.Net.Http
ilgili tüm kütüphaneleri ifade ettiği anlamına gelir.
, ama burada dur maxlevel="Info"
Trace
, Debug
Information
çünkü
WArning
Error
, günlüğü de sonraki Critical
tanımlarda çıktıdır.
Dördüncüsü, final="true"
yukarıda durdurulan günlük dışında bir dosyaya çıktıdır.
Günlükleri arşivle
Eski günlük dosyasını her tarih için ayrı bir klasörde yalnızca bir ana günlük dosyasıyla arşivleme yöntemi de vardır.
Örneğin:
<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}" />
Burada kullanılan parametreler şu anlama gelir:
Parametre | açıklaması |
---|---|
arşivSayılama | Tarih, tarihe göre bir arşiv dosyası oluşturur. |
arşivEvery | Gün günlük olarak arşivlemek için kullanılır. "Ay", "Saat", "Pazar" vb. |
archiveFileAdı | Arşivleme yolu. {#} arşiv bazında değişir. |
arşivDateFormat | Dosya adının tarihe göre arşiv tarihi biçimi. |
maxArchiveFiles | Kaç dosyanın arşivlenerek arşivlendiğini belirtir. |
Tarih dışı yöntemleri arşivlemenin yolları da vardır. Daha fazla bilgi için resmi web sitesine bakın.
Yürütüldüğünde şöyle görünür:
Günlük başına e-posta gönderme
NLog ayrıca günlüğe kaydetme sırasında e-posta göndermenizi sağlar. Ancak, hata ayıklama günlüğü gibi bir e-posta gönderirseniz, göndermek çok fazla olur, Hata ve Önemli gibi yalnızca sınırlı günlük düzeylerini hedeflemek iyi bir fikirdir. Buna ek olarak, aşırı iletim nedeniyle posta sunucusunu engellemek gibi hata riskini önlemek için, Yalnızca günlük e-posta hesabı belirtmenizi öneririz.
Aşağıda bir yapılandırma örneği verilmiştir. Gerçekten posta göndermek istiyorsanız, kullanmak istediğiniz SMTP sunucusunu izleyin.
<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>
Günlükleri veritabanına yazma
NLog ayrıca veritabanına günlük yazabilir. Aşağıda bir örnek verilmiştir, bu nedenle ayrıntılar için lütfen resmi web sitesine bakın.
Bu bölümde, farklı bir sunucuda SQL Server'a yazma adımları açıklanmaktadır.
İlk olarak, hedef SQL Server'da oturum açmak için bir tablo oluşturun. Yazacak değeri seçebildiğinize göre, günlük olarak neye ihtiyacınız olduğunu sütun olarak tanımlayın.
Aşağıda tablo oluşturma SQL örneği verilmiştir.
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
Veritabanı işleme için bir veritabanı istemci kitaplığı System.Data.SqlClient
gereklidir.
NuGet'ten yükleyelim.
Veritabanı bilgilerini appsettings.json'a yazar. nlog.config, bilgileri appsettings.json dosyasına yüklemenizi sağlar. Ayarlar belirsizdir, bu yüzden lütfen bunları gerçek veritabanına göre ayarlayın. Anahtar adı rasgeledir, ancak nlog.config tarafından kullanılır.
{
"": "省略",
"NlogConnection": {
"DbHost": "ServerName\\SQLEXPRESS",
"Database": "TestDatabase",
"User": "UserName",
"Password": "********"
}
}
nlog.config dosyasını aşağıdaki gibi ayarlayın:
<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>
Çalıştırılacak hata yoksa, aşağıdaki gibi yazılır:
Bu arada.cs program .cs yöntemleri gibi erken bir aşamada veritabanına günlük yazmaya çalışmanın başarısız CreateHostBuilder
olabileceğini unutmayın.
RequestServices'ten günlükçüleri alma ve günlüğe kaydetme
Her yeni denetleyici veya sayfa modeli oluşturduğunuzda oluşturucuya eklemek sıkıcı ILogger
olabilir.
Alternatif olarak, RequestServices
'den alabilirsiniz.
public void OnGet()
{
// RequestServices から ILogger を取得する
var logger = (ILogger<IndexModel>)HttpContext.RequestServices.GetService(typeof(ILogger<IndexModel>));
logger.LogInformation("ページを表示するタイミングでログを出力します。");
}
Kendi denetleyicinizi veya sayfa modelinizi belirtmek de hantalsa, uzantı yöntemleri veya temel sınıflar oluşturabilirsiniz.
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>));
}
Kullanım örnekleri
public void OnGet()
{
// RequestServices から ILogger を取得する (this. は必要)
var logger = this.GetLogger();
logger.LogInformation("ページを表示するタイミングでログを出力します。");
}