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接收Gmail新邮件并发送到gtalk的方法
Mar 10 Python
简单实现python爬虫功能
Dec 31 Python
Python模拟登陆淘宝并统计淘宝消费情况的代码实例分享
Jul 04 Python
Python文件读写常见用法总结
Feb 22 Python
Python 使用 Pillow 模块给图片添加文字水印的方法
Aug 30 Python
python实现一个点绕另一个点旋转后的坐标
Dec 04 Python
Python实现点云投影到平面显示
Jan 18 Python
python GUI库图形界面开发之PyQt5滑块条控件QSlider详细使用方法与实例
Feb 28 Python
Python使用tkinter实现摇骰子小游戏功能的代码
Jul 02 Python
如何利用python读取micaps文件详解
Oct 18 Python
详解python爬取弹幕与数据分析
Nov 14 Python
Python开发之QT解决无边框界面拖动卡屏问题(附带源码)
May 27 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类
2006/10/09 PHP
关于Zend Studio 配色方案插件的介绍
2013/06/24 PHP
php获取访问者IP地址汇总
2015/04/24 PHP
PHP中overload与override的区别
2017/02/13 PHP
innerHTML,outerHTML,innerTEXT三者之间的区别
2007/01/28 Javascript
jquery ajax同步异步的执行最终解决方案
2013/04/26 Javascript
Jquery带搜索框的下拉菜单
2013/05/06 Javascript
Javascript URI 解析介绍
2015/03/15 Javascript
jquery中JSON的解析方式
2015/03/16 Javascript
基于ajax实现文件上传并显示进度条
2015/08/03 Javascript
jQuery+json实现动态创建复杂表格table的方法
2016/10/25 Javascript
jQuery Validate格式验证功能实例代码(包括重名验证)
2017/07/18 jQuery
webpack搭建vue 项目的步骤
2017/12/27 Javascript
vue的常用组件操作方法应用分析
2018/04/13 Javascript
js中怎么判断两个字符串相等的实例
2019/01/17 Javascript
es6 for循环中let和var区别详解
2020/01/12 Javascript
微信小程序动态添加和删除组件的现实
2020/02/28 Javascript
python连接mysql并提交mysql事务示例
2014/03/05 Python
Python下载懒人图库JavaScript特效
2015/05/28 Python
Python语言的面相对象编程方式初步学习
2016/03/12 Python
python中(str,list,tuple)基础知识汇总
2018/02/20 Python
Python元组常见操作示例
2019/02/19 Python
python实现鸢尾花三种聚类算法(K-means,AGNES,DBScan)
2019/06/27 Python
Python 动态导入对象,importlib.import_module()的使用方法
2019/08/28 Python
Python3.7在anaconda里面使用IDLE编译器的步骤详解
2020/04/29 Python
Python3.9.0 a1安装pygame出错解决全过程(小结)
2021/02/02 Python
详解CSS3中border-image的使用
2015/07/18 HTML / CSS
Europcar西班牙:全球汽车租赁领域的领导者
2018/09/17 全球购物
网络通讯中,端口有什么含义,端口的取值范围
2012/11/23 面试题
教师实习的自我鉴定
2013/10/26 职场文书
幼儿园新学期寄语
2014/01/18 职场文书
总经理助理的职责
2014/03/14 职场文书
2015年度绩效考核工作总结
2015/05/27 职场文书
《揠苗助长》教学反思
2016/02/20 职场文书
anaconda python3.8安装后降级
2021/06/11 Python
vue css 相对路径导入问题级踩坑记录
2022/06/05 Vue.js