我正在寻找过去 n 分钟的日志。我尝试了一些选项,但如果没有为特定时间戳指定日志,则大多数选项都不起作用。
例如:
如果当前时间是 ,则工作正常2019-07-27 09:00:01
,并且我查找 10 分钟前到当前时间的日志。如果日志文件中有一行,它会起作用2019-07-27 08:50:01
,但如果在此时间戳的日志中没有行,它不会打印任何内容。
for (( i = 10; i >=0; i-- )) ; do grep $(date +%R -d "-$i min") test.log
我还尝试了线程中给出的 awk 选项 获取最近 30 分钟的日志
但是,只要日志文件中有一行开头没有日期时间戳,它就不起作用。
awk -vStartDate=`date -d'now-30 min' +%H:%M:%S` '{ if ($2 > StartDate) print $0}' test.log
我的日志文件中的示例行是:
2019-07-27 01:28:35,8291 DEBUG [TestLogger] - Parameters: [100, IN%]
2019-07-27 01:28:35,8292 ERROR [TestLogger] - Query with error:
SELECT COUNT(*) FROM <table_name>
2019-07-27 01:28:35,8293 ERROR [TestLogger] - 'Connection reset' while executing statement
2019-07-27 01:28:35,8294 WARN [TestReportAction] - Count Error: TestReportAction - 'Connection reset' while executing statement
它也应该修剪行号,同时匹配逗号后给出的时间,
。
答案1
如果您同时安装了perl
perlDate::Parse
模块,则可以使用以下命令来执行此操作:
perl -MDate::Parse -F, -a -n -e \
'BEGIN { $start=time() - 600 ; $p=0};
if ($p) { print } else {
$logtime = str2time($F[0]);
$p=1 if ($logtime >= $start)}' /path/to/logfile
此 perl 单行假设日志文件的时间戳和数据其余部分之间的字段分隔符是逗号 ( -F,
),并使用 perl 的自动拆分选项 ( -a
) 将每个输入行自动拆分到数组中@F
。
它使用变量 $p 作为打开或关闭打印的切换开关,默认为关闭 (0)。如果 $p 打开,则打印当前行,否则使用Date::Parse
sstr2time()
函数将日志条目的时间戳转换为 time_t 值(纪元正弦秒数,1970-01-01 00:00:00),然后检查日志行是否时间戳 >= 所需的开始时间(600 秒、10 分钟前)。如果是,则将 $p 设置为 on (1)。
如果您有更复杂的需求,最好编写一个独立的 Perl 脚本,而不是尝试将其作为单行代码来完成 - 与使用文本编辑器相比,在 bash 命令行上进行编辑是一件 PITA 的事情。您可以从转换上面的一行开始:
#!/usr/bin/perl
use Date::Parse;
$start = time() - 600;
$p = 0;
while (<>) {
if ($p) {
print
} else {
my (@F) = split /,/;
my $logtime = str2time($F[0]);
$p = 1 if ($logtime >= $start);
}
}
例如,修改此脚本以从第一个命令行参数获取开始时间是相当容易的,而不是将其硬编码为-600秒。
这可以用 perl 来完成awk
,但是 perl 的 Date::Parse 模块很好并且易于使用,比在 awk 中编写日期解析代码容易得多。 日期::解析很容易从 CPAN 安装,并且可以打包用于某些 Linux 发行版(例如,在libtimedate-perl
debian 上的包中)。
相同的基本算法也可以用 python 或任何其他具有不错的日期解析功能的语言编写。