【问题标题】:How to get last 10 minutes of logs from remote host如何从远程主机获取最近 10 分钟的日志
【发布时间】:2019-06-03 04:46:54
【问题描述】:

我正在尝试从远程主机(我在 icinga2 中使用此脚本)从 /var/log/maillog 获取最后的 x 分钟日志,但没有运气。

我尝试了几种 awk、sed 和 grep 的组合,但似乎都没有奏效。我认为这是双引号与单引号的问题,但我使用它们并没有任何帮助。

host=$1
LOG_FILE=/var/log/maillog

hour_segment=$(ssh -o 'StrictHostKeyChecking=no' myUser@${host} 2>/dev/null "sed -n "/^$(date --date='10 minutes ago' '+%b %_d %H:%M')/,\$p" ${LOG_FILE}")

echo "${hour_segment}"

使用 bash -x 运行脚本时,我得到以下输出:

bash -x ./myScript.sh host.domain
+ host=host.domain
+ readonly STATE_OK=0
+ STATE_OK=0
+ readonly STATE_WARN=1
+ STATE_WARN=1
+ LOG_FILE=/var/log/maillog
+++ date '--date=10 minutes ago' '+%b %_d %H:%M'
++ ssh -o StrictHostKeyChecking=no myUser@host.domain 'sed -n /^Jan' 8 '12:56/,$p /var/log/maillog'
+ hour_segment=
+ echo ''

Maillog 日志文件输出。我也希望 $hour_segment 看起来像下面的输出,这样我就可以对其应用过滤器:

head -n 5 /var/log/maillog
Jan  6 04:03:36 hostname imapd: Disconnected, ip=[ip_address], time=5
Jan  6 04:03:36 hostname postfix/smtpd[9501]: warning: unknown[ip_address]: SASL LOGIN authentication failed: authentication failure
Jan  6 04:03:37 hostname imapd: Disconnected, ip=[ip_address], time=5
Jan  6 04:03:37 hostname postfix/smtpd[7812]: warning: unknown[ip_address]: SASL LOGIN authentication failed: authentication failure
Jan  6 04:03:37 hostname postfix/smtpd[7812]: disconnect from unknown[ip_address]

【问题讨论】:

  • 请发布一些具有预期输出的示例数据。
  • 我已将邮件日志输出添加到帖子中。
  • 这种格式有很多问题:Jan 6 04:03:36 形式的日期不能排序为Feb 29 < Jan 6 并且没有年份,这意味着很难确定你是哪一月需要。 2019 年的一个或 1919 年的一个。 ...
  • 我查看了我必须使用的邮件日志,它们是轮换的。可以肯定地说在给定日志文件中只有“1”一月吗?

标签: bash awk ssh sed grep


【解决方案1】:

使用 GNU awk 的时间函数:

$ awk '
BEGIN {
    m["Jan"]=1               # convert month abbreviations to numbers 
    # fill in the rest       # fill in the rest of the months
    m["Dec"]=12
    nowy=strftime("%Y")      # assume current year, deal with Dec/Jan below
    nowm=strftime("%b")      # get the month, see above comment
    nows=strftime("%s")      # current epoch time
}
{                            # below we for datespec for mktime
    dt=(nowm=="Jan" && $1=="Dec"?nowy-1:nowy) " " m[$1] " " $2 " " gensub(/:/," ","g",$3)
    if(mktime(dt)>=nows-600) # if timestamp is less than 600 secs away
        print                # print it
}' file

假定为当前年份。如果是 1 月并且日志有 12 月,我们会从 mktime 的日期规范中减去一年:(nowm=="Jan" && $1=="Dec"?nowy-1:nowy)。 Datespec:Jan 6 04:03:37 -> 2019 1 6 04 03 37 并以纪元形式进行比较:1546740217

编辑:由于没有人在 cmets 中实现我的规格,我将自己做。 tac 反向输出文件,awk 在给定时间范围内打印记录(t-现在或未来),并在遇到时间范围之外的日期时退出:

$ tac file | awk -v t=600 '   # time in seconds go here
BEGIN {
    m["Jan"]=1
    # add more months
    m["Dec"]=12
    nowy=strftime("%Y")
    nowm=strftime("%b")
    nows=strftime("%s")
} {
    dt=(nowm=="Jan" && $1=="Dec"?nowy-1:nowy) " " m[$1] " " $2 " " gensub(/:/," ","g",$3)
    if(mktime(dt)<nows-t)     # this changed some
        exit                
    else 
        print
}' 

【讨论】:

  • 非常好!需要明确的是,这仅在您的日志文件包含最多 1 年的数据时才有效。
  • 是的。正确的方法是使用tac 倒退日志并在时间戳超过 10 分钟后退出。我将把这个规范留在这里,让别人来实际实现它。
  • 谢谢!没有这一年似乎是一种真正的痛苦。我试试看,看看会发生什么:)
  • 更新了另一个版本。
【解决方案2】:

想出一个 100% 防弹的强大解决方案非常困难,因为我们缺少最关键的信息,即年份

假设您想要 2020 年 3 月 1 日00:05:00最后 10 分钟的可用数据。这有点烦人,因为 February 29 2020 存在。但在 2019 年,它不会。

我在这里提出一个丑陋的解决方案,只关注第三个字段(时间),我将做出以下假设:

  • 日志文件按时间排序
  • 每天至少有一个日志!

在这些条件下,我们可以从第一个可用时间开始跟踪滑动窗口

如果您在文件extractLastLog.awk 中保护以下内容

{ t=substr($3,1,2)*3600 + substr($3,4,2)*60 + substr($3,7,2) + offset}
(t < to) { t+=86400; offset+=86400 }
{ to = t }
(NR==1) { startTime = t; startIndex = NR }
{ a[NR]=$0; b[NR]=t }
{ while ( startTime+timeSpan*60 <= t ) { 
      delete a[startIndex]
      delete b[startIndex]
      startIndex++; startTime=b[startIndex]
  }
}
END { for(i=startIndex; i<=NR; ++i) print a[i] }

那么您可以通过以下方式提取最后 23 分钟:

awk -f extractLastLog.awk -v timeSpan=23 logfile.log

我给出的第二个条件(每天至少有一个日志!)需要不要弄乱结果。在上面的代码中,我计算的时间相当简单,HH*3600 + MM*60 + SS + offset。但我声明,如果当前时间小于前一次,这意味着我们在不同的日子,因此我们将偏移量更新为 86400 秒。因此,如果您有两个条目,例如:

Jan 09 12:01:02 xxx 
Jan 10 12:01:01 xxx 

它会起作用,但是这个

Jan 09 12:01:00 xxx 
Jan 10 12:01:01 xxx 

不会工作。它不会意识到天变了。其他会失败的情况是:

Jan 08 12:01:02 xxx 
Jan 10 12:01:01 xxx 

因为它不知道它跳了两天。由于几个月的原因,对此进行更正并不容易(这都归功于闰年)。

正如我所说,它很丑,但可能有用。

【讨论】:

  • 喜欢最后的评论它很丑,但可能有用。 :D
  • 不错的一个!另一个尝试的选项,感谢输入 kvantour!
猜你喜欢
  • 2019-09-23
  • 2016-01-01
  • 2012-01-29
  • 2022-01-11
  • 2016-05-07
  • 2015-01-18
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
相关资源
最近更新 更多