JSONで情報を出力するログがいくつかあります。これはelasticsearchへの収集用です。
一部のテスターや運用担当者は、サーバー上のログを読み取れるようにしたいと考えています。
JSONの例を以下に示します。
{
"@timestamp": "2015-09-22T10:54:35.449+02:00",
"@version": 1,
"HOSTNAME": "server1.example",
"level": "WARN",
"level_value": 30000,
"logger_name": "server1.example.adapter",
"message": "message"
"stack_trace": "ERROR LALALLA\nERROR INFO NANANAN\nSOME MORE ERROR INFO\nBABABABABABBA BABABABA ABABBABAA BABABABAB\n"
}
等々。
Jqに\ n文字の代わりに改行を印刷させることは可能ですか?
最初に与えられた入力は、完全に有効なJSONではありません。目的の出力が何であるかは明確ではありませんが、以下が興味深いかもしれません。これは、jqの現在のバージョン(バージョン1.5)用に書かれていますが、jq 1.4に簡単に適合させることができます。
def json2qjson:
def pp: if type == "string" then "\"\(.)\"" else . end;
. as $in
| foreach keys[] as $k (null; null; "\"\($k)\": \($in[$k] | pp)" ) ;
def data: {
"@timestamp": "2015-09-22T10:54:35.449+02:00",
"@version": 1,
"HOSTNAME": "server1.example",
"level": "WARN",
"level_value": 30000,
"logger_name": "server1.example.adapter",
"message": "message",
"stack_trace": "ERROR LALALLA\nERROR INFO NANANAN\nSOME MORE ERROR INFO\nBABABABABABBA BABABABA ABABBABAA BABABABAB\n"
};
data | json2qjson
出力:
$ jq -rnf json2qjson.jq
"@timestamp": "2015-09-22T10:54:35.449+02:00"
"@version": 1
"HOSTNAME": "server1.example"
"level": "WARN"
"level_value": 30000
"logger_name": "server1.example.adapter"
"message": "message"
"stack_trace": "ERROR LALALLA
ERROR INFO NANANAN
SOME MORE ERROR INFO
BABABABABABBA BABABABA ABABBABAA BABABABAB
"
承知しました! -r
オプションを使用すると、jqは文字列の内容をJSONエスケープ文字列としてではなく、端末に直接出力します。
jq -r '.stack_trace'
jq
onlyを使用する制約がない限り、jq
出力をsed
:
cat the-input | jq . | sed 's/\\n/\n/g'
入力にもタブがある場合(JSONでは\t
)、次のようになります。
cat the-input | jq . | sed 's/\\n/\n/g; s/\\t/\t/g'
これは、Javaスタックトレース行がstack_trace
で始まるため、<tab>at<space>
がJavaによって生成された場合(ログのソースが何であるかを知らなかった場合)に特に便利です。
警告:当然、これは正しいではありません。つまり、\\n
を含むJSON入力は ""出力になりますが、 "n"出力になるはずです。正しくはありませんが、人間がデータを覗くには十分です。 sed
パターンは、これを処理するようにさらに改善できます(読みやすさを犠牲にして)。