.NET CoreアプリケーションでNLogを使う
.NET Coreアプリケーションでログ出力にはNLogが良いみたいですね。
NLog
NLogは導入が容易で拡張性が高いログ出力ライブラリで、最近ではlog4netよりも人気があるようです。
.NET Coreの場合は、NLog.Extensions.Loggingを使います。
NLogのインストール
project.jsonにNLog.Extensions.Logging
を記載してインストールします。
{ "version": "1.0.0-*", "dependencies": { "Microsoft.Extensions.Configuration": "1.1.0", "NLog.Extensions.Logging": "1.0.0-rtm-beta2" }, "frameworks": { "netcoreapp1.1": { "dependencies": { "Microsoft.NETCore.App": { "type": "platform", "version": "1.1.0" } }, "imports": "dnxcore50" } } }
NLog.config
プロジェクトフォルダの直下にNLog.configファイルを作成します。
targets
タグ内でログの出力先(ここではfile.txt)を指定します。rules
タグ内で指定のtargetへの出力条件(ここではDebugレベル以上)を記載します。
<?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"> <targets> <target name="logfile" xsi:type="File" fileName="file.txt" /> </targets> <rules> <logger name="*" minlevel="Debug" writeTo="logfile" /> </rules> </nlog>
アプリケーション実装
今回はコンソールアプリケーションでログ出力させてみます。
NLog.LogManager#GetCurrentClassLogger
でLogger
オブジェクトを取得しています。
引数なしの場合、生成したクラス(ここではProgram
)が呼び出し元(caller)のクラスとしてログに出力されます。
using System; using NLog; namespace ConsoleApplication { public class Program { private static Logger _logger = LogManager.GetCurrentClassLogger(); public static void Main(string[] args) { _logger.Trace("trace message"); _logger.Debug("debug message"); _logger.Info("info message"); _logger.Warn("warn message"); _logger.Error("error message"); _logger.Fatal("fatal message"); } } }
実行すると、file.txtに以下のように出力されます。
Traceレベルが出力されていないことと、Programが呼び出し元として出力されていることに注意してください。
2017-02-24 21:36:40.1753|DEBUG|Program|debug message 2017-02-24 21:36:40.2848|INFO|Program|info message 2017-02-24 21:36:40.2848|WARN|Program|warn message 2017-02-24 21:36:40.2848|ERROR|Program|error message 2017-02-24 21:36:40.2857|FATAL|Program|fatal message
ログレイアウトをカスタマイズする
NLog.configのtargetsタグではログのレイアウトを細かく設定できます。
例えば↓の感じで設定すると、実行中のクラスとメソッドと行番号まで出力されます。
<targets> <target name="logfile" xsi:type="File" fileName="file.txt" layout="${level:uppercase=true:padding=-5} ${longdate} "${message}" ${callsite}#${callsite-linenumber}" /> </targets>
DEBUG 2017-02-24 21:35:09.8425 "debug message" ConsoleApplication.Program.Main#13 INFO 2017-02-24 21:35:10.0356 "info message" ConsoleApplication.Program.Main#14 WARN 2017-02-24 21:35:10.0377 "warn message" ConsoleApplication.Program.Main#15 ERROR 2017-02-24 21:35:10.0391 "error message" ConsoleApplication.Program.Main#16 FATAL 2017-02-24 21:35:10.0421 "fatal message" ConsoleApplication.Program.Main#17
JSONやCSVへの出力も全く難しくなく、例えばJSONの場合はlayout
タグでJsonLayout
を指定するだけでOKです。
<targets> <target name="logfile" xsi:type="File" fileName="file.txt"> <layout xsi:type="JsonLayout"> <attribute name="level" layout="${level}" /> <attribute name="timestamp" layout="${longdate}" /> <attribute name="message" layout="${message}" /> <attribute name="callsite" layout="${callsite}#${callsite-linenumber}" /> </layout> </target> </targets>
{ "level": "Debug", "timestamp": "2017-02-24 21:27:15.0592", "message": "debug message", "callsite": "ConsoleApplication.Program.Main#13" }
他にもいろいろなレイアウトがあります。
ログの出力クラス(Layout render)は自前で実装することもできます。
ログ出力先を切り替える
例えば、ログレベルがError以上の場合は、通常のログファイルに加えて別のファイルに出力したいといったケースもあるかと思います。
その場合、targetsに通常のログ出力用とErrorログ出力用の2つのtargetを定義して、rulesでログレベルに応じてtargetを切り替えることになります。
下のように設定すると、errorlog.txtにはログレベルがErrorまたはFatalのみが出力されるようになります。
<targets> <target name="logfile" xsi:type="File" fileName="log.txt" /> <target name="errorlogfile" xsi:type="File" fileName="errorlog.txt" /> </targets> <rules> <logger name="*" minlevel="Debug" writeTo="logfile" /> <logger name="*" minlevel="Error" writeTo="errorlogfile" /> </rules>
出力先にはファイル以外にもメールやDBやコンソールに出力できます。
まとめ
Layout renderやtargetの自前実装について触れませんでしたが、そういった拡張をしなくてもちょっとしたアプリケーションなら十分なログが得られることがわかりました。