構造化ログを整形してtailで内容確認したい
code:json
{
"Timestamp": "2023-12-26T00:00:00.0000000+09:00",
"Level": "Error",
"MessageTemplate": "{CallerFilePath}|{CallerMethodName}|{CallerLineNumber}L|{Message}|{StackTrace}",
"Exception": "エラー内容",
"Properties": {
"CallerFilePath": "C:\\repository\\Sample\\Sample\\Program.cs",
"CallerMethodName": "Main",
"CallerLineNumber": 40,
"Message": "...",
"StackTrace": " 場所 System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)...",
"ProcessId": 100,
"ProcessName": "Sample",
"EnvironmentUserName": "DOMAIN\\user",
"EnvironmentName": "Develop",
"MachineName": "PC",
"AssemblyVersion": "1.0.0.0",
"AssemblyName": "Sample"
}
}
やりたいこと
1. このファイルを1行ずつ読み出したい
tail -fでできそうだが…?
2. 自分が確認したいため、読みやすいように整形したい
3. valueを集めたり、不要なkeyを出力から除外したい
jqでできそうだが…?
出力方法
むりやりつなげてこうなった
code:bash
file='filepath'
tail -f -q ${file} | while read -r line; do
echo "$line" | jq -r '. | {Level,Timestamp,Exception,Process,Call,Message,Properties}' | jq -r '.Process = (.Properties.ProcessId | tostring) + " " + .Properties.EnvironmentUserName8: + " " + .Properties.ProcessName' | jq -r '.Call = (.Properties.CallerFilePath | split("\\") | last) + "#" + .Properties.CallerMethodName + " " + (.Properties.CallerLineNumber | tostring) + "L"' | jq -r '.Message = .Properties.Message' | jq -r '.Timestamp = .Timestamp:16' | jq -Cr 'del(.Properties)' done
こんな感じで出力される
code:json
{
"Level": "Information",
"Timestamp": "2023-12-26T11:20",
"Exception": null,
"Process": "760 user1 Sample",
"Call": "formSample.cs#button_Click 110L",
"Message": "アレを実行"
}
{
"Level": "Error",
"Timestamp": "2023-12-26T11:20",
"Exception": "System.ComponentModel.Win32Exception (0x80004005): 指定されたファイルが見つかりません。\r\n...",
"Process": "760 user1 Sample",
"Call": "formSample.cs#button_Click 115L",
"Message": "ファイルがないみたい"
}
ハマったところ
1. このファイルを1行ずつ整形して読み出したい
2. 自分が確認したいため、読みやすいように整形したい
Properties下にある内容を結合してProcessに代入する
型変換(数値から文字列tostring)
文字列結合
トリミング([n:m])
文字列分割(split())
code:bash
jq -r '.Process = (.Properties.ProcessId | tostring) + " " + .Properties.EnvironmentUserName8:' jq -r '.Timestamp = .Timestamp:16' jq -r '.Call = (.Properties.CallerFilePath | split("\\") | last)'
3. valueを集めたり、不要なkeyを出力から除外したい
新しいkeyを作る
code:bash
jq -r '. | {Level,Timestamp,Exception,Process,Call,Message,Properties}'
keyを削除する
del()
code:bash
jq -r 'del(.Properties)'
パイプでつなげすぎてもう一度書けって言われたら解析から始めないといけなさそう…
こうなったver.1(途中で諦めた)
code:bash
file='filepath'
tail -f -q ${file} | while read -r line; do
echo "$line" | jq -r '. | "[\(.Level:4)] \(.Timestamp:19) \(.Properties.EnvironmentUserName8:) \(.Properties.ProcessName) \(.Properties.ProcessId) \(.Properties.CallerFilePath | split("\\") | last)#\(.Properties.CallerMethodName) \(.Properties.CallerLineNumber)L"' done