やりたいこと
以前、自前でログを取るためのクラスを作ったりしたが、マルチスレッドの場合に同時に書き込んだりすると落ちるなど、問題があった。
頑張って自分で作るのもいいが、世の中には便利なログ取りライブラリがある様子。
最近NLogというのに触れる機会があったので、それの使い方をちょっと調べてみる。
やったこと
ログを取りたいプロジェクトに、NLogをnugetでインストールする。2022/10月時点の最新は5.0.4。
前提
- VisualStudion2022 v17.3.0
- C#
- NLog v5.0.4
設定をする(NLog.configを書いて配置)
まずは、NLogのチュートリアルを見ながら、NLogの設定をする。
設定は、コードからも、コンフィグファイル(NLog.config)でも行える。
Nlog.configという名前のファイルをPJに追加して、「ローカルにコピー」にしておけば、勝手にexeの横にコピーされて、その設定で動いてくれる。
設定は、コードからもできる様子だが、今回はやらない。
ターゲットの指定(ログを何に出力するか)
ターゲットは複数指定できる。
ターゲットには、ログファイルのほかにConsole出力なんかもある。
(ほかにもいろいろあるようだが、今回は試さない)
→https://nlog-project.org/config/?tab=targets
→メールとかもできるっぽい。
複数指定すると、ログファイルとconsole表示の両方に出力する、なんかもできる。
ログの中身をつくる(Layoutを書く)
ログの中身は<target >
の中のlayout
をいじることでカスタムできる。
基本は下記になっているらしい。
<target name="logfile" xsi:type="File" fileName="file.txt" layout="`${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}`" />
どんな項目を出せるか=layoutにどういう値をセットできるか、を下記を見ながらいろいろやる。
https://nlog-project.org/config/?tab=layout-renderers
csvっぽいログにしたいときは、下記のように、layout
のxsi:type
をCsvLayout
にして、
column
に出力したい内容をセットしていく。
参考:https://github.com/NLog/NLog/wiki/CsvLayout
<?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 xsi:type="File" name="csvFileExample" fileName="./CsvLogExample.csv"> <layout xsi:type="CsvLayout" delimiter="Enum" withHeader="false"> <column name="time" layout="${longdate}" /> <column name="level" layout="${level:upperCase=true}"/> <column name="message" layout="${message}" /> <column name="callsite" layout="${callsite:includeSourcePath=true}" /> <column name="stacktrace" layout="${stacktrace:topFrames=10}" /> <column name="exception" layout="${exception:format=ToString}"/> <column name="property1" layout="${event-properties:property1}"/> </layout> </target> <target name="logfile" xsi:type="File" fileName="ConfigByNlogConfig.log" /> <target name="logconsole" xsi:type="Console" /> </targets> <rules> <logger name="*" minlevel="Info" writeTo="logconsole" /> <logger name="*" minlevel="Debug" writeTo="logfile" /> <logger name="*" minlevel="Info" writeTo="csvFileExample" /> </rules> </nlog>
サンプル
下記サンプルで、マルチスレッドで同時に書き込むようなことをやってみたところ、 特に落ちたりすることなくログを取れた。スレッドセーフにつくってくれてるっぽい。
<?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 xsi:type="File" name="csvFileExample" fileName="./CsvLogExample.csv"> <layout xsi:type="CsvLayout" delimiter="Enum" withHeader="false"> <column name="time" layout="${longdate}" /> <column name="level" layout="${level:upperCase=true}"/> <column name="message" layout="${message}" /> <column name="callsite" layout="${callsite:includeSourcePath=true}" /> <column name="stacktrace" layout="${stacktrace:topFrames=10}" /> <column name="exception" layout="${exception:format=ToString}"/> <column name="property1" layout="${event-properties:property1}"/> </layout> </target> </targets> <rules> <logger name="*" minlevel="Info" writeTo="csvFileExample" /> </rules> </nlog>
using NLog; namespace NlogJikken { internal class Program { private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger(); static void Main(string[] args) { Console.WriteLine("Hello, World!"); //var config = new NLog.Config.LoggingConfiguration(); //var logfile = new NLog.Targets.FileTarget() { FileName = "ConfigByCode.log" }; //var logconsole = new NLog.Targets.ConsoleTarget(); //config.AddRule(LogLevel.Info, LogLevel.Fatal, logconsole); //config.AddRule(LogLevel.Debug, LogLevel.Fatal, logfile); ////NLog.LogManager.Configuration = config; Task.Run(()=> { for (int i = 0; i < 50; i++) { Logger.Info(i); } }); Task.Run(() => { for (int i = 0; i < 50; i++) { Logger.Info(i); } }); Console.ReadLine(); } } }
参考
NLog nuget
https://www.nuget.org/packages/NLog/
NLogリポジトリのTutorial
https://github.com/nlog/nlog/wiki
https://github.com/nlog/nlog/wiki/Tutorial
NLog.configを探す場所のルール
https://github.com/nlog/nlog/wiki/Configuration-file#file-locations
ログのターゲット(何に出力するのか、fileなのか、Consoleなのか)
https://nlog-project.org/config/?tab=targets
レイアウト(標準(特に書式なしの横にツラツラ書くヤツ)なのが、csvなのか、jsonなのか)の指定の書き方
https://nlog-project.org/config/?tab=layouts
csvのレイアウトの例
https://github.com/NLog/NLog/wiki/CsvLayout
ログの中身のカスタム(さわりの部分)
https://github.com/nlog/nlog/wiki/Tutorial#layouts-and-layoutrenderers
ログの中身のカスタム(具体的にどう書けばいいか)
https://nlog-project.org/config/?tab=layout-renderers
参考書
WinUI3
WinUI3でアプリを作ろうと思ったときのとっかかりによかった。
msdocsに書いてある情報を、体系的に、順番に読みたいな、というときによいかも。(ただし英語)
この本で分からなかった、かゆいところに手が届かなかった部分を私は記事にしてる感じ。
C#①
表紙に書いてある通り、教科書として最適。
これからC#を勉強したいけど、ネットだけで勉強するのは効率が悪いから体系的に学べる本が欲しいときや、
ちょっとC#を勉強してコード書けるようになったけど、もう少し広く深く知りたいなというときによいと思う。
私は仕事で触れるコードを軸に、基本ネットで断片的にC#を学んだので、その知識の隙間を埋めて枝葉を広げるためにとても分かりやすかった。
C#②
C#の文法的に色々できるのは分かったが、いざ実装するときに、わかったことを使ってどう実装すればいいのか?と悩んだときに指針になりそうな本。
「プロパティ等の名前の付け方、どうすればいい?」「情報をクラス外部に見せるときに、プロパティにすべき?メソッドにすべき?」「異常だと判定したいとき、どんなときにどんな例外をスローすべき?」などなど、勉強になる部分が山ほどあった。
私のように「コードは書くけどこれであってるのか自信がない、レビューで指摘されるのが嫌だ、実装時の(心の)よりどころが欲しい」という人に最適。