在我的日志文件中,我有三种类型的日志消息:信息,警告和错误。我只想捕获错误消息,但是由于错误消息的类型不同并且同一错误消息可能在日志文件中出现多次,因此我只想捕获每种类型的错误只有一次。我可以在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"
因此,基本上,我需要过滤日志文件以获取错误消息,并且每种类型只有一个错误。
仅:
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-
命令uniq -f 1
用空格分割。这没有效果,因为第一个空格,时间之后的字符串是唯一的。
改为使用uniq -s 20
。这将忽略前20个字符。
它适用于时间戳,因为在大多数情况下它们具有固定的长度。