根据当前时间戳读取日志

时间:2016-06-20 19:38:52

标签: shell unix logging

我有一个这样的日志文件:(example.log)

2016-06-13 04:50:10.327 39571893 [Thread-39-a-b-c-bolt] INFO  JobLoader c.t.c.i.i.b.abcBolt - Setting other variation theme
2016-06-13 04:50:10.327 39571893 [Thread-39-a-b-c-bolt] INFO  JobLoader c.t.c.i.i.b.abcBolt - Stripping abc hierarchy
2016-06-13 04:50:10.328 39571894 [Thread-39-a-b-c-bolt] INFO  JobLoader c.t.c.i.i.b.abcBolt - Transforming date attributes
2016-06-13 04:50:10.328 39571894 [Thread-39-a-b-c-bolt] INFO  JobLoader c.t.c.i.i.b.abcBolt - Creating API object for incoming data

现在我只想读取最近4小时的日志(不是最后一个日志的最后4个小时,但是当前系统时间的最后4个小时;可能有0个日志,但必须创建空文件)并存储日志(完全不变)在一个单独的文件中。我可以只比较时间戳,或者我必须提取小时,分钟和秒并应用逻辑吗?

我的尝试:

x=$((4*3600))
current = date
awk -F 'JobLoader' -v current=$current -v x=$x '{ ______ | getline d; if (current-d<=x)print $0 }' example.log > output.txt

我在如何grep当前日志的当前时间以及是否可以像我一样进行比较时遇到问题?

实际上我对日志进行了连续操作,即将第16和第20个字段提取到一个单独的文件中。我根据建议这样做:

awk ' {
    cutoff=$(date -d "now -4 hours" +%s)
    date=$(cut -c1-19 <<<"$line")
    ts=$(date -d "$date" +%s)
    if [ $cutoff -le $ts ]; then
        print $3
    fi    
} ' /home/example.log >> output.txt

但我收到的错误是:

awk: cmd. line:2:     cutoff=$(date -d "now -4 hours" +%s)
awk: cmd. line:2:                                      ^ syntax error
awk: cmd. line:3:     date=$(cut -c1-19 <<<"$line")
awk: cmd. line:3:                        ^ syntax error
awk: cmd. line:4:     ts=$(date -d "$date" +%s)
awk: cmd. line:4:                           ^ syntax error
awk: cmd. line:5:     if [ $cutoff -le $ts ]; then
awk: cmd. line:5:                          ^ syntax error

我在这里做错了什么?请建议仅基于awk的解决方案。我不能用sed等。

1 个答案:

答案 0 :(得分:1)

有几种方法可以解决这个问题:awkperl。就个人而言,我只喜欢纯粹的bash解决方案:

cutoff=$(date -d "now -4 hours" +%s)
while read line; do
    date=$(cut -c1-19 <<<"$line")
    ts=$(date -d "$date" +%s)
    if [ $cutoff -le $ts ]; then
        echo "$line"
    else
        break
    fi
done < <(tac $1)

以下是发生的事情:

  • 第一行,我们将截止时间设置为UNIX时间戳(%s),这是从当前时钟(now -4 hours)开始的四个小时
  • 然后对于给定文件中的每一行,从最后一行读到第一行tac $1
  • 我们删除了日期部分,即前20个字符(-c1-19),然后将其转换为UNIX时间戳(-d "$date"
  • 然后我们将日志行时间戳与截止值进行比较:如果日志行日期大于截止值,我们将打印该行。如果没有,我们结束循环。

当然,这假设您的日志文件单调增加,并且每行以日期开头。您还可以访问GNU日期和tac。如果你想要很多便携性,awk就是你要走的路。如果你想要一个淘汰剧本,那么,我会使用bash。