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中的CURL PycURL使用例子
Jun 01 Python
python通过shutil实现快速文件复制的方法
Mar 14 Python
python实现在sqlite动态创建表的方法
May 08 Python
python开发之thread线程基础实例入门
Nov 11 Python
Python实现好友全头像的拼接实例(推荐)
Jun 24 Python
Python入门之三角函数atan2()函数详解
Nov 08 Python
pandas.DataFrame 根据条件新建列并赋值的方法
Apr 08 Python
对numpy中shape的深入理解
Jun 15 Python
django框架使用orm实现批量更新数据的方法
Jun 21 Python
pip安装python库的方法总结
Aug 02 Python
QML使用Python的函数过程解析
Sep 26 Python
Django Model层F,Q对象和聚合函数原理解析
Nov 12 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的ASP防火墙
2006/10/09 PHP
PHP4实际应用经验篇(4)
2006/10/09 PHP
检查url链接是否已经有参数的php代码 添加 ? 或 &amp;
2010/02/09 PHP
php下过滤html代码的函数 提高程序安全性
2010/03/02 PHP
PHP设计模式之装饰者模式代码实例
2015/05/11 PHP
CI映射(加载)数据到view层的方法
2016/03/28 PHP
在JavaScript并非所有的一切都是对象
2013/04/11 Javascript
jquery统计用户选中的复选框的个数
2014/06/06 Javascript
教你一步步用jQyery实现轮播器
2016/12/18 Javascript
jQuery实现的简单在线计算器功能
2017/05/11 jQuery
前端把html表格生成为excel表格的实例
2017/09/19 Javascript
vue+axios+element ui 实现全局loading加载示例
2018/09/11 Javascript
JavaScript 判断iPhone X Series机型的方法
2019/01/28 Javascript
Vue Autocomplete 自动完成功能简单示例
2019/05/25 Javascript
解决使用layui的时候form表单中的select等不能渲染的问题
2019/09/18 Javascript
vue通过v-html指令渲染的富文本无法修改样式的解决方案
2020/05/20 Javascript
[02:15]2014DOTA2国际邀请赛 赛后退役选手回顾
2014/08/01 DOTA
[04:11]DOTA2亚洲邀请赛小组赛第一日 TOP10精彩集锦
2015/01/30 DOTA
Python常用列表数据结构小结
2014/08/06 Python
教你用Type Hint提高Python程序开发效率
2016/08/08 Python
Python3中使用PyMongo的方法详解
2017/07/28 Python
python生成圆形图片的方法
2020/03/25 Python
python:按行读入,排序然后输出的方法
2019/07/20 Python
python实现扫雷游戏
2020/03/03 Python
使用OpenCV去除面积较小的连通域
2020/07/05 Python
vscode配置anaconda3的方法步骤
2020/08/08 Python
对Pytorch 中的contiguous理解说明
2021/03/03 Python
豪华床上用品、床单和浴室必需品:Peacock Alley
2019/09/04 全球购物
关于幼儿的自我评价
2013/12/18 职场文书
幼儿园义卖活动方案
2014/01/17 职场文书
《巨人的花园》教学反思
2014/02/12 职场文书
晚归检讨书
2014/02/19 职场文书
2015年网管个人工作总结
2015/05/22 职场文书
文化大革命观后感
2015/06/17 职场文书
干部作风纪律整顿心得体会
2016/01/23 职场文书
MySQL单表千万级数据处理的思路分享
2021/06/05 MySQL