查询日志 操作日志正确姿势

平时线上系统,经常会出现bug(没有bug的系统是不存在的),掌握多一些的查看日志的技巧就显得尤为重要,可以更快速的定位和发现问题,缩短bug引起的故障时间。

那么,面试中我也经常去问一下应聘者这个问题:平时查看日志都用到了那些命令?

大多数回答的都是:tail,grep。还有一些其他的,下面具体说一下

cat

-n 可以显示行号

cat -n test.log |grep "关键字"

demo

cat -n test.log |tail -n +63820|head -n 20

tail -n +63820表示查询63820行之后的日志
head -n 20 则表示在前面的查询结果里再查前20条记录

cat -n info.log |grep "关键字" |more

这样就分页打印了,通过点击空格键翻页

tail

最常用的指令,实时查看新输出的增量log日志信息

tail -f [logfile]

tail -n 100 [logfile] 查询日志最后(最新)的100行

tail -n +100 [logfile] 查询从日志文件的第100行开始

tail -n 100 [logfile] | grep '结果' --color –color是查询结果带颜色

head -n 100 [logfile] 查询日志文件中的头10行日志

head -n -100 [logfile] 查询日志文件除了最后10行的其他所有日志

grep

grep -v 'ERROR' error.log 排除

grep -C 50 "关键字" info.log

-C : 匹配的上下文显示行数

-A : 匹配的行下显示的行数

-B : 匹配的行上显示的行数

查找不含”ERROR”的行

sed

操作符 名字 效果
[地址范围]/p 打印 打印[指定的地址范围]
[地址范围]/d 删除 删除[指定的地址范围]
s/pattern1/pattern2/ 替换 将指定行中, 将第一个匹配到的pattern1, 替换为pattern2.
[地址范围]/s/pattern1/pattern2/ 替换 *地址范围*指定的每一行中, 将第一个匹配到的pattern1, 替换为pattern2.
[地址范围]/y/pattern1/pattern2/ transform *地址范围*指定的每一行中, 将pattern1中的每个匹配到pattern2的字符都使用pattern2的相应字符作替换. (等价于tr命令)
g 全局 在每个匹配的输入行中, 将每个模式匹配都作相应的操作. (译者注: 不只局限于第一个匹配)

sed -n ‘10,15p’ [logfile] 查看日志文件的第10~15行

查找2017-07-03 21:21 ~ 2017-07-03 21:22内的日志

sed -n '/2017-07-03 21:21/,/2017-07-03 21:22/p' info.log

查找2017-07-03 21:21:34 ~ 2017-07-03 21:21:39内的所有日志

sed -n '/2017-07-03 21:21:34/,/2017-07-03 21:21:39/p' info.log

例1:(摘自abs的sed小册子)

8d 删除输入的第8行.
/^$/d 删除所有空行.
1,/^$/d 从输入的开头一直删除到第1个空行(第一个空行也删除掉).
/Jones/p 只打印那些包含”Jones”的行(使用-n选项).
s/Windows/Linux/ 在每个输入行中, 将第一个出现的”Windows”实例替换为”Linux”.
s/BSOD/stability/g 在每个输入行中, 将所有”BSOD”都替换为”stability”.
s/ *$// 删除掉每行结尾的所有空格.
s/00*/0/g 将所有连续出现的0都压缩成单个的0.
/GUI/d 删除掉所有包含”GUI”的行.
s/GUI//g 将所有”GUI”都删除掉, 并保持剩余部分的完整性.

访问次数最多的IP TOP10

当网络流量突然持续异常时,很有可能是有恶意访问,最快的解决方式就是找出访问量最多的几个ip,暂时禁止其访问,然后再仔细观察

# cat access_log | cut -f1 -d “ “ | sort | uniq -c | sort -rnk 1 | head -10

被访问次数最多的URL TOP10

了解哪些Url资源的访问量最大,可以帮助我们有针对性的进行优化

# cat access_log | cut -f7 -d “ “ | sort | uniq -c | sort -rnk 1 | head -10

被请求资源中大小最大的 TOP10

文件大小太大的话会严重影响访问速度,有必要找出大文件进行分析

# cat access_log | sort -rnk 10 | head -10

命令解释

这几个命令都是使用了管道“|”把多个命令进行连接,上一个命令的结果交给下一个命令来处理

cat

显示文件内容

cut

是一个选取命令,就是将数据以行为单位进行分析,取出我们想要的

-d : 自定义分隔符,默认为制表符

-f : 与-d一起使用,指定显示哪列

第一个命令中的:cut -f1 -d “ “

含义:以空格进行分割,显示结果中的第一列

sort

将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出

没有参数时就是整行排序

-t : 分隔符,默认是用 [tab] 键来分隔

-k : 选择以哪列进行排序

-n : 使用数字格式进行排序,默认是以文字型态来排序的

-r : 反向排序

uniq

首先比较相邻的行,然后除去第二行和该行的后续副本,重复的行一定要相邻,所以通常与 sort 联合使用,先用 sort 进行排序,然后使用 uniq 去重

-c : 在输出行前面加上每行出现的次数

head

显示结果中头部区域

-10 : 显示头部的10行

综合解释

日志文件的内容示例

183.195.232.39 - - [28/Dec/2015:22:31:48 +0800] “GET /ui-nav.js HTTP/1.1” 304 -

183.195.232.39 - - [28/Dec/2015:22:31:48 +0800] “GET /ui-toggle.js HTTP/1.1” 304 -

183.195.232.38 - - [28/Dec/2015:22:31:48 +0800] “GET /ui-toggle.js HTTP/1.1” 304 -

以第一个命令(查看访问量最大的前10个IP)为例

# cat access_log | cut -f1 -d “ “ | sort | uniq -c | sort -k 1 -n -r | head -10

cat access_log

先读取 access_log 的内容

cut -f1 -d “ “

然后对每行以空格进行分割,只显示第一列(日志的第一列为IP)

输出的结果为:

183.195.232.39

183.195.232.39

183.195.232.38

sort

接下来对IP进行升序排序

输出的结果为:

183.195.232.38

183.195.232.39

183.195.232.39

uniq -c

删除重复的IP,删除的同时记录下相同的IP数量,显示到IP的前面

输出的结果为:

1 183.195.232.38

2 183.195.232.39

sort -k 1 -n -r

对第一列以数字格式倒序排序

输出的结果为:

2 183.195.232.39

1 183.195.232.38

head -10

只显示头10条

坚持技术分享,您的支持将鼓励我继续创作!