有什么
- 有 14 台机器(意味着我们有 14 份日志)
- 一台可以连到这 14 太机器的机器(有Python 2.6)
要做什么
- 获取 14 台机器上某时间段内的包含某特征的日志,再取出其中的特定内容
怎么做
- 使用 pssh 工具在 14 台机器执行 grep 命令获取包含某特征的日志
- 将 14 份日志作为标准输入传给 Python 脚本
- Python 解析 stdin(标准输入),将日期转化为 Python 中的日期格式,判断之后将符合条件的特定内容取出并输出到 stdout(标准输出)
开始
一. 使用 pssh 工具在 14 台机器执行 grep 命令获取包含某特征的日志
- # 安装 pssh 工具
- pip install pssh
- # 使用 pssh 工具
- pssh -l root -h RS_bj_14.txt -o result "grep some_tag /data/logs/api.log"
- -l 的意思是使用哪个用户执行
- -h 是指定主机列表文件(换行隔开)
- -o 是指定执行结果保存的文件夹
- ***是需要执行的命令
结果:
红色执行失败的的那两台机器未包含符合我们筛选条件的日志
二. 将 14 份日志作为标准输入传给 Python 脚本
14 份日志作为标准输入传给 Python 脚本:
- cat result/* | ./ab-result-format.py 15 15 00 10 > result_we_want.log
Python 脚本
- #!/usr/bin/python
- import sys
- import time
- format = '%Y-%m-%dT%H:%M:%S+08:00'
- h_start = int(sys.argv[1])
- h_end = int(sys.argv[2])
- m_start = int(sys.argv[3])
- m_end = int(sys.argv[4])
- stdin = sys.stdin.read().strip()
- line_list = stdin.split('\n')
- for item in line_list:
- infos = item.split()
- time_object = time.strptime(infos[0], format)
- if h_start <= time_object.tm_hour <= h_end \
- and m_start <= time_object.tm_min <= m_end:
- print infos[8], infos[3], infos[4]
先交代一下我们分析的日志格式:
Nginx 日志格式(log_format)
为了方便查看,日志格式和日志中的空格都用换行代替
- $time_iso8601
- $remote_addr
- $host
- $request_time
- $upstream_response_time
- $request
- $status
- $upstream_addr
- $session_id;
(实际的一条日志)
- 2017-12-19T00:03:57+08:00
- 2003:da8:2004:1000:a0a:ffd2:f0:9b1c
- [2003:da8:2004:1000:0a13:ffaa:00f0:9b1c]
- 0.454
- 0.448
- POST
- /?Action=SubmitSyncTaskWithData
- HTTP/1.1
- 200
- [2003:da8:2004:1000:****:dd8b:00b7:38ae]:8080
- f228d3941798f0d92c877a92a265f679
Python 脚本做了这么几件事:
- 接受 4 个参数,分别是起始的小时和分钟,备用
- 读取标准输入 sys.stdin.read(),去掉头尾无用的字符 strip(),循环处理每行日志
- 拆分每行日志 split()
- 将时间字符串专为时间对象,根据 4 个参数判断小时和分钟(这里处理的比较粗糙,跨小时就没办法处理了,有兴趣的读者可以做的更精细一点)
- 时间条件符合,打出需要的部分(这里我需要的是 session_id, request_time, upstream_response_time 所以我们print infos, infos, infos注:Python 的 print 就是标准输出
***我们使用 >将 Python 脚本的标准输出重定向到 result_we_want.log 文件