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 相关文章推荐
9种python web 程序的部署方式小结
Jun 30 Python
100行Python代码实现自动抢火车票(附源码)
Jan 11 Python
python 爬虫一键爬取 淘宝天猫宝贝页面主图颜色图和详情图的教程
May 22 Python
python实现泊松图像融合
Jul 26 Python
Python 利用切片从列表中取出一部分使用的方法
Feb 01 Python
Pandas库之DataFrame使用的学习笔记
Jun 21 Python
Python中那些 Pythonic的写法详解
Jul 02 Python
Python3.7基于hashlib和Crypto实现加签验签功能(实例代码)
Dec 04 Python
django 扩展user用户字段inlines方式
Mar 30 Python
Python接口测试环境搭建过程详解
Jun 29 Python
利用python下载scihub成文献为PDF操作
Jul 09 Python
pandas apply多线程实现代码
Aug 17 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
php发送get、post请求的6种方法简明总结
2014/07/08 PHP
php fread读取文件注意事项
2016/09/24 PHP
php + WebUploader实现图片批量上传功能
2019/05/06 PHP
Ext JS Grid在IE6 下宽度的问题解决方法
2009/02/15 Javascript
node.js 一个简单的页面输出实现代码
2012/03/07 Javascript
setTimeout函数兼容各主流浏览器运行执行效果实例
2013/06/13 Javascript
jquery数组封装使用方法分享(jquery数组遍历)
2014/03/25 Javascript
JavaScript实现表格点击排序的方法
2015/05/11 Javascript
JavaScript实现给按钮加上双重动作的方法
2015/08/14 Javascript
jQuery实现多级联动下拉列表查询框
2016/01/18 Javascript
javascript瀑布流布局实现方法详解
2016/02/17 Javascript
jQuery基于$.ajax设置移动端click超时处理方法
2016/05/14 Javascript
Bootstrap 轮播(Carousel)插件
2016/12/26 Javascript
jQuery自定义插件详解及实例代码
2016/12/29 Javascript
vue.js移动数组位置,同时更新视图的方法
2018/03/08 Javascript
用vue快速开发app的脚手架工具
2018/06/11 Javascript
vue组件开发之用户无限添加自定义填写表单的方法
2018/08/28 Javascript
Angular(5.2-&gt;6.1)升级小结
2018/12/27 Javascript
Angular实现svg和png图片下载实现
2019/05/05 Javascript
javascript实现的字符串转换成数组操作示例
2019/06/13 Javascript
微信小程序实现注册登录功能(表单校验、错误提示)
2019/12/10 Javascript
Python写的创建文件夹自定义函数mkdir()
2014/08/25 Python
TensorFlow安装及jupyter notebook配置方法
2017/09/08 Python
Python数据结构与算法之使用队列解决小猫钓鱼问题
2017/12/14 Python
python opencv 读取本地视频文件 修改ffmpeg的方法
2019/01/26 Python
pytorch 图像中的数据预处理和批标准化实例
2020/01/15 Python
Homestay中文官网:全球寄宿家庭
2018/10/18 全球购物
意大利奢侈品牌在线精品店:Jole.it
2020/11/23 全球购物
十一酒店活动方案
2014/02/20 职场文书
大学生村官考核材料
2014/05/23 职场文书
2014离婚协议书范文
2014/09/10 职场文书
儿园租房协议书范本
2014/12/02 职场文书
党支部半年考察意见
2015/06/01 职场文书
Python多线程 Queue 模块常见用法
2021/07/04 Python
php png失真的原因及解决办法
2021/11/17 PHP
java如何实现获取客户端ip地址的示例代码
2022/04/07 Java/Android