【问题标题】:Format and pretty print log via tail通过tail格式化和漂亮的打印日志
【发布时间】:2019-07-04 17:36:42
【问题描述】:

我有这个日志文件,我经常检查它,并且由于它的格式,打印出来时更容易阅读。我想这样做。

在文件中记录如下:

2019-07-04T09:53:04-07:00   some.package.placeholder.stderr {"log": "The content", "foo": "bar", "baz": "blah"}
2019-07-04T10:15:37-07:00   some.package.placeholder.stderr {"log": "I'm actually", "foo": "bar", "baz": "blah"}
2019-07-04T10:15:37-07:00   some.package.placeholder.stderr {"log": "Interested on", "foo": "bar", "baz": "blah"}

我想做一些类似的事情

tail -f myLogFile | grep [...?...] | jq '.log'

所以当我追尾时:

The content
I'm actually
Interested on

甚至:

2019-07-04T09:53:04-07:00   The content
2019-07-04T10:15:37-07:00   I'm actually
2019-07-04T10:15:37-07:00   Interested on

【问题讨论】:

  • some.package.placeholder.stder 可以包含空格吗?
  • @Cyrus 不适用于这种情况,但时间戳、package.placeholder 和实际的 json 可以用制表符/空格分隔

标签: json logging grep jq tail


【解决方案1】:

使用 GNU grep 获取 -o

$ tail file | grep -o '{[^}]*}' | jq -r '.log'
The content
I'm actually
Interested on

使用任何 awk:

$ tail file | awk 'sub(/.*{/,"{")' | jq -r '.log'
The content
I'm actually
Interested on

$ tail file | awk '{d=$1} sub(/.*{/,""){$0="{\"date\": \""d"\", " $0} 1' | jq -r '.date + " " + .log'
2019-07-04T09:53:04-07:00 The content
2019-07-04T10:15:37-07:00 I'm actually
2019-07-04T10:15:37-07:00 Interested on

最后一个通过将输入中的日期字段合并到 json 中来工作,这样 jq 就可以选择并使用日志字段打印它。

【讨论】:

  • 大概还想使用 jq 的 --unbuffered 命令行选项?
  • @peak idk 老实说,我只是在学习jq,但您似乎确实想使用一些东西来关闭缓冲,所以如果这就是jq 的选项那么是的,您可能还想在打印每一行后向 awk 命令添加 fflush() 或插入 stdbuf 或类似调用。
【解决方案2】:

如果日志行是制表符分隔的,您可以读取原始行并在制表符上拆分。然后您可以解析 json 并过滤到您心中的内容,并根据需要重新组合。

$ tail -f myLogFile | jq -Rr 'split("\t") | [.[0], (.[2] | fromjson.log)] | join("\t")'
2019-07-04T09:53:04-07:00   The content
2019-07-04T10:15:37-07:00   I'm actually
2019-07-04T10:15:37-07:00   Interested on

【讨论】:

  • 看起来棒极了,但是当我在 cygwin 上使用 jq 1.6 版进行尝试时,我得到了 assertion "cb == jq_util_input_next_input_cb" failed: file "/usr/src/ports/jq/jq-1.6-1.x86_64/src/jq-1.6/src/util.c", line 371, function: jq_util_input_get_position Aborted (core dumped)
  • 嗯,我无法调试并查看导致此问题的原因,但从消息来看,我猜这是 tail 如何通过输出的问题。我当时在 git bash 中自己尝试过,但它不能实时工作,我认为它应该这样做。
  • 我从 jq '...' file 收到的错误消息与从 tail file | jq 收到的错误消息相同。这可能只是 cygwin 的事情,idk。我刚开始学习jq,所以没怎么用过。一个快速的谷歌想出了github.com/stedolan/jq/issues/1588,但如果它是同一个问题,我知道。
【解决方案3】:

这是我使用的一个可以在管道和文件参数中使用的东西:

cat /usr/local/bin/j2t
#!/bin/bash

function usage {
  cat <<EOF
Usage:
        $0 <json filename>
    or
        tail -F <json filename> | $0
EOF
}

if (($# == 0)); then
    {
        sed "s/@\(timestamp\)/\1/" | jq -r '[.timestamp, .pri.facility, .pri.severity, .message] | join("\t")'
    } < /dev/stdin

else
    if [ -r "$1" ] ; then
        sed "s/@\(timestamp\)/\1/" $1 | jq -r '[.timestamp, .pri.facility, .pri.severity, .message] | join("\t")'
    else
        help
    fi
fi

例如:(如果你的 daemon.log 是 json)

j2t /var/log/daemon.log
level: 63, builder: awillia2)
2021-08-14T00:00:06.820642+00:00        daemon  INFO     Starting Run Clamscan...
2021-08-14T00:00:06.846405+00:00        daemon  INFO     Started Run Clamscan.

应该重新格式化时间,有点长。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-07
    • 2021-11-06
    • 1970-01-01
    • 2011-05-06
    • 2016-02-25
    • 2012-03-07
    • 2021-09-19
    相关资源
    最近更新 更多