如果每行包含时间戳,如何使用 bash 获取日志记录频率?
How to get frequency of logging using bash if each line contains a timestamp?
我有一个程序,它在运行期间写入一个文本文件。在此文本文件中,每一行由 4 个部分组成。
- 线程 ID(一个数字)
- 格式为 yyyy-mm-dd 的日期
- 格式为 12:34:56.123456
的时间戳
- 一个函数名
- 程序打印出的一些有用的评论
日志行的示例如下所示:
127894 2020-07-30 22:04:30.234124 foobar caught an unknown exception
127895 2020-07-30 22:05:30.424134 foobar clearing the programs cache
127896 2020-07-30 22:06:30.424134 foobar recalibrating dankness
日志按时间顺序打印,我想知道如何获得这些日志的最高频率。例如,我想知道程序在一天中的哪一分钟或哪一秒最拥塞。
理想情况下,我想要一个可以告诉我的输出,例如,“最高记录频率在 22:04:00 和 22:05:00 之间,在此时间范围内打印了 10 行日志”。
让我们考虑这个测试文件:
$ cat file.log
127894 2020-07-30 22:04:30.234124 foobar caught an unknown exception
127895 2020-07-30 22:05:20.424134 foobar clearing the programs cache
127895 2020-07-30 22:05:30.424134 foobar clearing the programs cache
127895 2020-07-30 22:05:40.424134 foobar clearing the programs cache
127896 2020-07-30 22:06:30.424134 foobar recalibrating dankness
127896 2020-07-30 22:06:40.424134 foobar recalibrating dankness
获取最拥堵分钟数,排名顺序为:
$ awk '{sub(/:[^:]*$/, "", ); a[" "]++} END{for (d in a)print a[d], d}' file.log | sort -nr
3 2020-07-30 22:05
2 2020-07-30 22:06
1 2020-07-30 22:04
22:05 在日志文件中出现了 3 次,因此是最拥塞的,其次是 22:06。
要仅获取最拥挤的分钟数,请添加 head
。例如:
$ awk '{sub(/:[^:]*$/, "", ); a[" "]++} END{for (d in a)print a[d], d}' file.log | sort -nr | head -1
3 2020-07-30 22:05
注意我们select这里是基于第二个和第三个字段。日志消息文本中的日期或时间不会混淆此代码。
工作原理
sub(/:[^:]*$/, "", )
删除第三个字段中分钟后的所有内容。
a[" "]++
计算日期和时间(最多分钟)出现的次数。
读取整个文件后,for (d in a)print a[d], d
打印出观察到的每个日期的计数和日期。
sort -nr
将计数最高的输出排序在顶部。 (或者,我们可以让 awk 进行排序,但 sort -nr
简单且可移植。)
排序到第二
我们可以获得秒分辨率,而不是分钟分辨率:
$ awk '{sub(/\.[^.]*$/, "", ); a[" "]++} END{for (d in a)print a[d], d}' file.log | sort -nr
1 2020-07-30 22:06:40
1 2020-07-30 22:06:30
1 2020-07-30 22:05:40
1 2020-07-30 22:05:30
1 2020-07-30 22:05:20
1 2020-07-30 22:04:30
使用 GNU 实用程序:
grep -o ' [0-9][0-9]:[0-9][0-9]' file.log | sort | uniq -c | sort -nr | head -n 1
版画
frequency HH:MM
HH:MM
是出现频率最高的小时和分钟,frequency
是出现频率最高的。如果您删除 | head -n 1
,那么您将看到按频率排序的频率和分钟列表。
我有一个程序,它在运行期间写入一个文本文件。在此文本文件中,每一行由 4 个部分组成。
- 线程 ID(一个数字)
- 格式为 yyyy-mm-dd 的日期
- 格式为 12:34:56.123456 的时间戳
- 一个函数名
- 程序打印出的一些有用的评论
日志行的示例如下所示:
127894 2020-07-30 22:04:30.234124 foobar caught an unknown exception
127895 2020-07-30 22:05:30.424134 foobar clearing the programs cache
127896 2020-07-30 22:06:30.424134 foobar recalibrating dankness
日志按时间顺序打印,我想知道如何获得这些日志的最高频率。例如,我想知道程序在一天中的哪一分钟或哪一秒最拥塞。
理想情况下,我想要一个可以告诉我的输出,例如,“最高记录频率在 22:04:00 和 22:05:00 之间,在此时间范围内打印了 10 行日志”。
让我们考虑这个测试文件:
$ cat file.log
127894 2020-07-30 22:04:30.234124 foobar caught an unknown exception
127895 2020-07-30 22:05:20.424134 foobar clearing the programs cache
127895 2020-07-30 22:05:30.424134 foobar clearing the programs cache
127895 2020-07-30 22:05:40.424134 foobar clearing the programs cache
127896 2020-07-30 22:06:30.424134 foobar recalibrating dankness
127896 2020-07-30 22:06:40.424134 foobar recalibrating dankness
获取最拥堵分钟数,排名顺序为:
$ awk '{sub(/:[^:]*$/, "", ); a[" "]++} END{for (d in a)print a[d], d}' file.log | sort -nr
3 2020-07-30 22:05
2 2020-07-30 22:06
1 2020-07-30 22:04
22:05 在日志文件中出现了 3 次,因此是最拥塞的,其次是 22:06。
要仅获取最拥挤的分钟数,请添加 head
。例如:
$ awk '{sub(/:[^:]*$/, "", ); a[" "]++} END{for (d in a)print a[d], d}' file.log | sort -nr | head -1
3 2020-07-30 22:05
注意我们select这里是基于第二个和第三个字段。日志消息文本中的日期或时间不会混淆此代码。
工作原理
sub(/:[^:]*$/, "", )
删除第三个字段中分钟后的所有内容。
a[" "]++
计算日期和时间(最多分钟)出现的次数。
读取整个文件后,for (d in a)print a[d], d
打印出观察到的每个日期的计数和日期。
sort -nr
将计数最高的输出排序在顶部。 (或者,我们可以让 awk 进行排序,但 sort -nr
简单且可移植。)
排序到第二
我们可以获得秒分辨率,而不是分钟分辨率:
$ awk '{sub(/\.[^.]*$/, "", ); a[" "]++} END{for (d in a)print a[d], d}' file.log | sort -nr
1 2020-07-30 22:06:40
1 2020-07-30 22:06:30
1 2020-07-30 22:05:40
1 2020-07-30 22:05:30
1 2020-07-30 22:05:20
1 2020-07-30 22:04:30
使用 GNU 实用程序:
grep -o ' [0-9][0-9]:[0-9][0-9]' file.log | sort | uniq -c | sort -nr | head -n 1
版画
frequency HH:MM
HH:MM
是出现频率最高的小时和分钟,frequency
是出现频率最高的。如果您删除 | head -n 1
,那么您将看到按频率排序的频率和分钟列表。