Python解析nginx日志文件


Posted in Python onMay 11, 2015

项目的一个需求是解析nginx的日志文件。
简单的整理如下:

日志规则描述

首先要明确自己的Nginx的日志格式,这里采用默认Nginx日志格式:

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
          '$status $body_bytes_sent "$http_referer" '
          '"$http_user_agent" "$http_x_forwarded_for"';

其中一条真实记录样例如下:

172.22.8.207 - - [16/Dec/2014:17:57:35 +0800] "GET /report?DOmjjuS6keWJp+WculSQAgdUkAIPODExMzAwMDJDN0FC HTTP/1.1" 200 0 "-" "XXXXXXX/1.0.16; iPhone/iOS 8.1.2; ; 8DA77E2F91D0"

其中,客户端型号信息用XXXXXXX代替。

项目中已经按照业务规则对Nginx日志文件进行了处理命名规则如下:

ID-ID-YYMMDD-hhmmss
并且所有的日志文件存放在统一路径下。

解决思路

获取所有日志文件path

这里使用Python的glob模块来获取日志文件path

import glob
def readfile(path):
  return glob.glob(path + '*-*-*-*')

获取日志文件中每一行的内容

使用Python的linecache模块来获取文件行的内容

import linecache


def readline(path):
  return linecache.getlines(path)

注意:linecache模块使用了缓存,所以存在以下问题:

在使用linecache模块读取文件内容以后,如果文件发生了变化,那么需要使用linecache.updatecache(filename)来更新缓存,以获取最新变化。

linecache模块使用缓存,所以会耗费内存,耗费量与要解析的文件相关。最好在使用完毕后执行linecache.clearcache()清空一下缓存。

当然,作为优化,这里可以利用生成器来进行优化。暂且按下不表。

处理日志条目

一条日志信息就是一个特定格式的字符串,因此使用正则表达式来解析,这里使用Python的re模块。
下面,一条一条建立规则:

规则

ip = r"?P<ip>[\d.]*"
  date = r"?P<date>\d+"
  month = r"?P<month>\w+"
  year = r"?P<year>\d+"
  log_time = r"?P<time>\S+"
  method = r"?P<method>\S+"
  request = r"?P<request>\S+"
  status = r"?P<status>\d+"
  bodyBytesSent = r"?P<bodyBytesSent>\d+"
  refer = r"""?P<refer>
       [^\"]*
       """
  userAgent=r"""?P<userAgent>
        .*
        """

解析

p = re.compile(r"(%s)\ -\ -\ \[(%s)/(%s)/(%s)\:(%s)\ [\S]+\]\ \"(%s)?[\s]?(%s)?.*?\"\ (%s)\ (%s)\ \"(%s)\"\ \"(%s).*?\"" %( ip, date, month, year, log_time, method, request, status, bodyBytesSent, refer, userAgent ), re.VERBOSE)

m = re.findall(p, logline)

这样,就可以得到日志条目中各个要素的原始数据。

格式及内容转化

得到日志原始数据之后,需要根据业务要求,对原始数据进行格式及内容转化。
这里需要处理的内容包括:时间,request,userAgent

时间格式转化

在日志信息原始数据中存在Dec这样的信息,利用Python的time模块可以方便的进行解析

import time
def parsetime(date, month, year, log_time):
  time_str = '%s%s%s %s' %(year, month, date, log_time)
  return time.strptime(time_str, '%Y%b%d %H:%M:%S')

解析request

在日志信息原始数据中得到的request的内容格式为:

/report?XXXXXX
这里只需要根据协议取出XXXXXX即可。
这里仍然采用Python的re模块

import re
def parserequest(rqst):
  param = r"?P<param>.*"
  p = re.compile(r"/report\?(%s)" %param, re.VERBOSE)
  return re.findall(p, rqst)

接下来需要根据业务协议解析参数内容。这里需要先利用base64模块解码,然后再利用struct模块解构内容:

import struct
import base64
def parseparam(param):
  decodeinfo = base64.b64decode(param)
  s = struct.Struct('!x' + bytes(len(decodeinfo) - (1 + 4 + 4 + 12)) + 'xii12x')
  return s.unpack(decodeinfo)

解析userAgent

在日志信息原始数据中userAgent数据的格式为:

XXX; XXX; XXX; XXX
根据业务要求,只需要取出最后一项即可。
这里采用re模块来解析。

import re
def parseuseragent(useragent):
  agent = r"?P<agent>.*"
  p = re.compile(r".*;.*;.*;(%s)" %agent, re.VERBOSE)
  return re.findall(p, useragent)

至此,nginx日志文件解析基本完成。
剩下的工作就是根据业务需要,对获得的基本信息进行处理。

以上所述就是本文的全部内容了,希望大家能够喜欢。

Python 相关文章推荐
python实现的文件同步服务器实例
Jun 02 Python
python 2.6.6升级到python 2.7.x版本的方法
Oct 09 Python
Python批量查询域名是否被注册过
Jun 21 Python
Django 导出 Excel 代码的实例详解
Aug 11 Python
Python enumerate索引迭代代码解析
Jan 19 Python
在PyCharm下打包*.py程序成.exe的方法
Nov 29 Python
Django框架序列化与反序列化操作详解
Nov 01 Python
python ubplot使用方法解析
Jan 10 Python
windows支持哪个版本的python
Jul 03 Python
Opencv常见图像格式Data Type及代码实例
Nov 02 Python
Python爬虫之Selenium下拉框处理的实现
Dec 04 Python
Pytorch 如何加速Dataloader提升数据读取速度
May 28 Python
Python字符串替换实例分析
May 11 #Python
Python使用django获取用户IP地址的方法
May 11 #Python
总结Python编程中三条常用的技巧
May 11 #Python
python求解水仙花数的方法
May 11 #Python
pymongo为mongodb数据库添加索引的方法
May 11 #Python
python判断windows系统是32位还是64位的方法
May 11 #Python
Python中使用装饰器时需要注意的一些问题
May 11 #Python
You might like
探讨Hessian在PHP中的使用分析
2013/06/13 PHP
支持中文的PHP按字符串长度分割成数组代码
2015/05/17 PHP
PHP new static 和 new self详解
2017/02/19 PHP
Yii框架实现的验证码、登录及退出功能示例
2017/05/20 PHP
php 算法之实现相对路径的实例
2017/10/17 PHP
关于Yii2框架跑脚本时内存泄漏问题的分析与解决
2019/12/01 PHP
Centos7.7 64位利用本地完整安装包安装lnmp/lamp套件教程
2021/03/09 Servers
javascript的键盘控制事件说明
2008/04/15 Javascript
IE FF OPERA都可用的弹出层实现代码
2009/09/29 Javascript
Javascript中的this绑定介绍
2011/09/22 Javascript
js 链式延迟执行DOME
2012/01/04 Javascript
实现局部遮罩与关闭原理及代码
2013/02/04 Javascript
详解JS获取HTML DOM元素的8种方法
2017/06/17 Javascript
使用 Javascript 实现浏览器推送提醒功能的示例
2017/11/03 Javascript
vue实现添加与删除图书功能
2018/10/07 Javascript
es6 symbol的实现方法示例
2019/04/02 Javascript
vue实现多条件和模糊搜索功能
2019/05/28 Javascript
[01:15:15]VG VS EG Supermajor小组赛B组胜者组第一轮 BO3第二场 6.2
2018/06/03 DOTA
Python获取文件ssdeep值的方法
2014/10/05 Python
Python中selenium实现文件上传所有方法整理总结
2017/04/01 Python
Python简单读写Xls格式文档的方法示例
2018/08/17 Python
selenium使用chrome浏览器测试(附chromedriver与chrome的对应关系表)
2018/11/29 Python
python GUI实现小球满屏乱跑效果
2019/05/09 Python
python 监控logcat关键字功能
2020/09/04 Python
以设计师精品品质提供快速时尚:PopJulia
2018/01/09 全球购物
美国伴娘礼服商店:Evening Collective
2019/10/07 全球购物
Oral-B荷兰:牙医最推荐的品牌
2020/02/25 全球购物
点菜员岗位职责范本
2014/02/14 职场文书
马智宇婚礼主持词
2014/03/22 职场文书
公职人员索取回扣检举信
2014/04/04 职场文书
中学生评语大全
2014/04/18 职场文书
李培根演讲稿
2014/05/22 职场文书
咖啡店创业计划书
2014/08/15 职场文书
期末个人总结范文
2015/02/13 职场文书
2015年安全员工作总结范文
2015/04/22 职场文书
2016应届毕业生自荐信范文
2016/01/28 职场文书