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的垃圾回收机制深入分析
Jul 16 Python
编写Python的web框架中的Model的教程
Apr 29 Python
Python统计日志中每个IP出现次数的方法
Jul 06 Python
Python 实现 贪吃蛇大作战 代码分享
Sep 07 Python
解决Python 遍历字典时删除元素报异常的问题
Sep 11 Python
python Pygame的具体使用讲解
Nov 03 Python
python PyQt5/Pyside2 按钮右击菜单实例代码
Aug 17 Python
使用python实现飞机大战游戏
Mar 23 Python
PyQt5 界面显示无响应的实现
Mar 26 Python
Jupyter Notebook远程登录及密码设置操作
Apr 10 Python
keras 权重保存和权重载入方式
May 21 Python
通俗讲解python 装饰器
Sep 07 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
晋城吧对DiscuzX进行的前端优化要点
2010/09/05 PHP
PHP中nowdoc和heredoc使用需要注意的一点
2014/03/21 PHP
php求一个网段开始与结束IP地址的方法
2015/07/09 PHP
PHP实现HTML页面静态化的方法
2015/11/04 PHP
PHP实现的用户注册表单验证功能简单示例
2019/02/25 PHP
jQuery+css实现炫目的动态块漂移效果
2016/01/28 Javascript
Web安全测试之XSS实例讲解
2016/08/15 Javascript
Vue.JS入门教程之处理表单
2016/12/01 Javascript
js实现把图片的绝对路径转为base64字符串、blob对象再上传
2016/12/29 Javascript
浅谈javascript中的 “ &amp;&amp; ” 和 “ || ”
2017/02/02 Javascript
利用jquery正则表达式在页面验证url网址输入是否正确
2017/04/04 jQuery
Angular2使用Angular-CLI快速搭建工程(二)
2017/05/21 Javascript
让你彻底掌握es6 Promise的八段代码
2017/07/26 Javascript
详解基于Vue cli生成的Vue项目的webpack4升级
2018/06/19 Javascript
vue实现点击关注后及时更新列表功能
2018/06/26 Javascript
详解搭建es6+devServer简单开发环境
2018/09/25 Javascript
JavaScript 面向对象程序设计详解【类的创建、实例对象、构造函数、原型等】
2020/05/12 Javascript
[57:22]完美世界DOTA2联赛PWL S2 FTD vs PXG 第二场 11.27
2020/12/01 DOTA
python获取本机mac地址和ip地址的方法
2015/04/29 Python
初步剖析C语言编程中的结构体
2016/01/16 Python
Python回文字符串及回文数字判定功能示例
2018/03/20 Python
numpy.delete删除一列或多列的方法
2018/04/03 Python
Python爬虫实现简单的爬取有道翻译功能示例
2018/07/13 Python
基于python3实现socket文件传输和校验
2018/07/28 Python
Python3中编码与解码之Unicode与bytes的讲解
2019/02/28 Python
python实现把两个二维array叠加成三维array示例
2019/11/29 Python
Python selenium爬取微博数据代码实例
2020/05/22 Python
python实现按日期归档文件
2021/01/30 Python
HTMl5的存储方式sessionStorage和localStorage详解
2014/03/18 HTML / CSS
美国韩国化妆品和护肤品购物网站:Beautytap
2018/07/29 全球购物
自我评价的正确写法
2013/09/19 职场文书
新农村建设标语
2014/06/24 职场文书
2014年群众路线教育实践活动整改措施
2014/09/24 职场文书
巴黎圣母院观后感
2015/06/10 职场文书
小区物业管理2015年度工作总结
2015/10/22 职场文书
Java实现多线程聊天室
2021/06/26 Java/Android