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多线程编程中的join函数使用心得
Sep 02 Python
朴素贝叶斯算法的python实现方法
Nov 18 Python
在Python中使用sort()方法进行排序的简单教程
May 21 Python
Python简单网络编程示例【客户端与服务端】
May 26 Python
Python编程使用tkinter模块实现计算器软件完整代码示例
Nov 29 Python
python设置值及NaN值处理方法
Jul 03 Python
Tornado实现多进程/多线程的HTTP服务详解
Jul 25 Python
Python CVXOPT模块安装及使用解析
Aug 01 Python
Python爬虫 批量爬取下载抖音视频代码实例
Aug 16 Python
详解python中eval函数的作用
Oct 22 Python
python3正则模块re的使用方法详解
Feb 11 Python
Python常用GUI框架原理解析汇总
Dec 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
微信支付开发交易通知实例
2016/07/12 PHP
javascript 日期常用的方法
2009/11/11 Javascript
JQuery 拾色器插件发布-jquery.icolor.js
2010/10/20 Javascript
jquery win 7透明弹出层效果的简单代码
2013/08/06 Javascript
js 实现菜单左右滚动显示示例介绍
2013/11/21 Javascript
JS组件Bootstrap实现图片轮播效果
2016/05/16 Javascript
Bootstrap table分页问题汇总
2016/05/30 Javascript
JavaScript来实现打开链接页面的简单实例
2016/06/02 Javascript
zepto与jquery的区别及zepto的不同使用8条小结
2016/07/28 Javascript
jQuery+ThinkPHP+Ajax实现即时消息提醒功能实例代码
2017/03/21 jQuery
微信小程序组件之srcoll-view的详解
2017/10/19 Javascript
react-navigation 如何判断用户是否登录跳转到登录页的方法
2017/12/01 Javascript
通过jquery toggleClass()属性制作文章段落更改背景颜色
2018/05/21 jQuery
node.js调用C++函数的方法示例
2018/09/21 Javascript
详解vue 2.6 中 slot 的新用法
2019/07/09 Javascript
Vue基础配置讲解
2019/11/29 Javascript
JavaScript Window窗口对象属性和使用方法
2020/01/19 Javascript
在vue项目中封装echarts的步骤
2020/12/25 Vue.js
Python中还原JavaScript的escape函数编码后字符串的方法
2014/08/22 Python
Python原始字符串与Unicode字符串操作符用法实例分析
2017/07/22 Python
Python实现识别手写数字大纲
2018/01/29 Python
python实现点对点聊天程序
2018/07/28 Python
解决python3运行selenium下HTMLTestRunner报错的问题
2018/12/27 Python
Python使用while循环花式打印乘法表
2019/01/28 Python
关于Python 常用获取元素 Driver 总结
2019/11/24 Python
在python里创建一个任务(Task)实例
2020/04/25 Python
终于搞懂了Keras中multiloss的对应关系介绍
2020/06/22 Python
关于python中导入文件到list的问题
2020/10/31 Python
css3实现平移效果(transfrom:translate)的示例
2020/11/13 HTML / CSS
HTML5 embed标签定义和用法详解
2014/05/09 HTML / CSS
美国畅销的跑步机品牌:ProForm
2017/02/06 全球购物
韩国江南富人区高端时尚百货商场:Galleria(格乐丽雅)
2018/03/27 全球购物
XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式?
2016/01/12 面试题
《石榴》教学反思
2014/03/02 职场文书
经费申请报告范文
2015/05/18 职场文书
Redis唯一ID生成器的实现
2022/07/07 Redis