Linux读取日志文件并进行过滤以仅获取一次相同类型的日志消息

问题描述 投票:1回答:2

在我的日志文件中,我有三种类型的日志消息:信息,警告和错误。我只想捕获错误消息,但是由于错误消息的类型不同并且同一错误消息可能在日志文件中出现多次,因此我只想捕获每种类型的错误只有一次。我可以在Ubuntu终端中使用什么命令?我已经尝试过:

grep -E 'level=error' server.log | sort --unique

但是这也给了我'信息'和'警告'信息。

然后我使用了此命令,但仍然得到所有三种类型的消息,而不仅仅是错误消息。

grep 'error' server.log | uniq -f 1

参数-f 1是跳过时间戳字段,因为它始终是唯一的。

例如,我的日志消息是:

.
.
.
11-03-2020 11:53:32" level=info msg="Starting up" file="etc/load/startwith.txt"
11-03-2020 11:53:33" level=info msg="Started" file="etc/load/startwith.txt"
11-03-2020 11:54:29" level=warning msg="Some fields missing" file="etc/load/startwith.php" 
11-03-2020 11:54:47" level=info msg="Started the process" file="etc/load/startwith.php" 
11-03-2020 11:54:51" level=info msg="Connecting to database" file="etc/db/dbinfo.php" 
11-03-2020 11:54:53" level=error msg="Database connection failed" file="etc/db/dbinfo.php"  
11-03-2020 13:26:22" level=info msg="Started back-up process" file="etc/load/startwith.php" 
11-03-2020 13:26:23" level=info msg="Starting up" file="etc/load/startwith.txt"
11-03-2020 13:26:26" level=error msg="Start up failed" file="etc/db/startwith.php" 
11-03-2020 13:26:27" level=info msg="Starting up" file="etc/load/startwith.txt"
11-03-2020 13:26:31" level=error msg="Start up failed" file="etc/db/startwith.php"
11-03-2020 13:26:32" level=info msg="Starting up" file="etc/load/startwith.txt"
11-03-2020 13:26:35" level=warning msg="Duplicate fields found" file="etc/load/startwith.php" 
11-03-2020 13:26:36" level=info msg="Started the process" file="etc/load/startwith.php" 
11-03-2020 13:26:37" level=info msg="Connecting to database" file="etc/db/dbinfo.php"
11-03-2020 13:26:38" level=info msg="Success. Connected to the database" file="etc/db/db-success.php"
11-03-2020 13:26:38" level=info msg="Inserting data to database" file="etc/db/dboperation.php"
11-03-2020 13:26:39" level=warning msg="Null fields found" file="etc/db/dboperation.php"
11-03-2020 13:26:39" level=info msg="Data inserted" file="etc/db/dboperation.php"
11-03-2020 13:26:39" level=info msg="Disconnected" file="etc/db/dboperation.php"
11-03-2020 13:26:43" level=info msg="Inserting data to database" file="etc/db/dboperation.php"
11-03-2020 13:26:43" level=error msg="Required data missing" file="etc/db/dboperation.php"
11-03-2020 13:26:44" level=info msg="Inserting data to database" file="etc/db/dboperation.php"
11-03-2020 13:26:44" level=error msg="Required data missing" file="etc/db/dboperation.php"
.
.
.

上述日志中的错误的预期输出(3种不同类型的错误,不是总错误发生)将是:

11-03-2020 11:54:53" level=error msg="Database connection failed" file="etc/db/dbinfo.php" 
11-03-2020 13:26:31" level=error msg="Start up failed" file="etc/db/startwith.php"
11-03-2020 13:26:44" level=error msg="Required data missing" file="etc/db/dboperation.php"

因此,基本上,我需要过滤日志文件以获取错误消息,并且每种类型只有一个错误。

linux shell ubuntu grep uniq
2个回答
0
投票

仅:

awk '/error/ && !seen[$4]++'

或使用引号作为分隔符以包含完整的msg="this text"消息,例如:

awk -F'"' '/error/ && !seen[$3]++'

[您可以不用awk来完成-grep error然后是nl数字行,然后sort -u在字段中以msg=唯一排序,然后在行号上重新排序并用cut删除行号。或者,可以用msg="part"提取sed以简化sort标记化。像这样:

grep error | sed 's/.* msg="\([^"]*\)"/\1\t&/' | nl -w1 |
sort -t $'\t' -u -k2,2 | sort -n -k1 | cut -f3-

0
投票

命令uniq -f 1用空格分割。这没有效果,因为第一个空格,时间之后的字符串是唯一的。

改为使用uniq -s 20。这将忽略前20个字符。

它适用于时间戳,因为在大多数情况下它们具有固定的长度。

© www.soinside.com 2019 - 2024. All rights reserved.