使用 awk 或其他 cli 工具提取日志行中的 json 字段

使用 awk 或其他 cli 工具提取日志行中的 json 字段

这是我们当前使用的系统中的日志格式,现在要更改整个系统的日志格式并不容易。我需要一种方法来提取日志及其字段中的 json 对象。这样我就可以更轻松地查看日志,因为当前消息的大小太大。

这是日志格式

A B C {"field name one":value of field , "msg": "a sample message", "c": c}

这是一个示例日志。请注意,字段 A、B、C 没有空格,但 json 对象的字段和值可能有空格。

service_name/syslog.log:2022-09-24T16:18:01.38754199Z stdout F {"level":"info","ts":1664036281.3874626,"msg":"system sample message","host":"host_name","processor":"test","reqId":"1234"}

通过 cli,我只想打印 msg 中的值。我怎样才能做到这一点?

答案1

jq是操作JSON的常用工具。 将返回JSON 文档中密钥jq -r .msg的解码值。msg

您可以cut通过从字段 4 开始提取字段来获取 JSON 数据 ( cut -d ' ' -f 4-)

因此将它们结合起来:

cut -d ' ' -f 4- | jq -r .msg

例如

echo '2022-09-24T16:18:01.38754199Z stdout F {"level":"info","ts":1664036281.3874626,"msg":"system sample message","host":"host_name","processor":"test","reqId":"1234"}' | cut -d ' ' -f 4- | jq -r .msg
system sample message

答案2

$ jq -r -R 'sub("[^{]*"; "") | fromjson.msg' file
system sample message

这用于jq将输入读取为一组“原始”文本行。每行的文本都用sub()in进行修剪jq,以删除第一行之前的任何内容{。然后使用 将该文本的其余部分转换为 JSON 对象,并提取fromjson该对象的值。msg

答案3

使用(以前称为 Perl_6)

...使用 Raku 的JSON::Tiny模块:

~$ raku -MJSON::Tiny -ne 'my %json = from-json($_.comb( / "\{" ~ "\}" .* / )); 
                          put %json{"msg"};'   file.txt

或者:

~$ raku -MJSON::Tiny -ne '$_.comb( / "\{" ~ "\}" .*  / ) andthen  
                          my %json = from-json($_); 
                          put %json{"msg"};'   file.txt

或者:

~$ raku -MJSON::Tiny -ne 'put %(from-json($_.comb( / "\{" ~ "\}" .*  / ))){"msg"};  file.txt

注意:上面的代码$_.comb可以缩写为.comb. Raku 中的前导.点很常见:它意味着调用主题变量后面的例程$_


上面,Raku编程语言用于提取JSON内容。使用-ne逐行非自动打印标志逐行读取输入。输入comb的文本匹配由大括号括起来的零个或多个(贪婪)字符的模式(“波形符”符号,请参阅下面的链接)。使用该方法解析该文本from-json($_),并将结果存储在%-sigiled 哈希中%json(前两个答案)。

最后输出结果:msg 钥匙取消引用以返回关联的价值。请注意,您可以使用put %json<msg>而不是双引号形式,并且可以添加一个or next来跳过没有所需msg键的行。

输入示例:

service_name/syslog.log:2022-09-24T16:18:01.38754199Z stdout F {"level":"info","ts":1664036281.3874626,"msg":"system sample message","host":"host_name","processor":"test","reqId":"1234"}

示例输出:

system sample message

注意:有时查看语言的数据内部表示很有启发性,因此整个%json哈希如下所示(使用.say for %json.sort最后一个语句):

host => host_name
level => info
msg => system sample message
processor => test
reqId => 1234
ts => 1664036281.3874626

https://docs.raku.org/language/regexes#Tilde_for_nesting_structs
https://raku.land/cpan:MORITZ/JSON::Tiny
https://raku.org

相关内容