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读取浮点数和读取文本文件示例
May 06 Python
Python中字典的基本知识初步介绍
May 21 Python
实例讲解Python中函数的调用与定义
Mar 14 Python
Python的“二维”字典 (two-dimension dictionary)定义与实现方法
Apr 27 Python
教大家玩转Python字符串处理的七种技巧
Mar 31 Python
浅谈python数据类型及类型转换
Dec 18 Python
Python控制键盘鼠标pynput的详细用法
Jan 28 Python
在python里面运用多继承方法详解
Jul 01 Python
python对csv文件追加写入列的方法
Aug 01 Python
如何解决安装python3.6.1失败
Jul 01 Python
Python pandas对excel的操作实现示例
Jul 21 Python
Python使用socket_TCP实现小文件下载功能
Oct 09 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之sphinx
2013/05/15 PHP
php加密解密函数authcode的用法详细解析
2013/10/28 PHP
php简单获取目录列表的方法
2015/03/24 PHP
Yii2中使用join、joinwith多表关联查询
2016/06/30 PHP
php中时间函数date及常用的时间计算
2017/05/12 PHP
PHP使用curl_multi_select解决curl_multi网页假死问题的方法
2018/08/15 PHP
PHP安装BCMath扩展的方法
2019/02/13 PHP
tp5.1 框架数据库-数据集操作实例分析
2020/05/26 PHP
js不是基础的基础
2006/12/24 Javascript
一个简单的javascript类定义例子
2009/09/12 Javascript
JQuery 选择器、过滤器介绍
2011/02/14 Javascript
JQuery each打印JS对象的方法
2013/11/13 Javascript
js中switch case循环实例代码
2013/12/30 Javascript
浅谈javascript中onbeforeunload与onunload事件
2015/12/10 Javascript
jquery  实现轮播图详解及实例代码
2016/10/12 Javascript
vue-router跳转页面的方法
2017/02/09 Javascript
浅析javaScript中的浅拷贝和深拷贝
2017/02/15 Javascript
d3.js入门教程之数据绑定详解
2017/04/28 Javascript
Angular之toDoList的实现代码示例
2017/12/02 Javascript
JS前端知识点总结之页面加载事件,数组操作,DOM节点操作,循环和分支
2019/07/04 Javascript
Vue Extends 扩展选项用法完整实例
2019/09/17 Javascript
js实现mp3录音通过websocket实时传送+简易波形图效果
2020/06/12 Javascript
python发送邮件接收邮件示例分享
2014/01/21 Python
基于python OpenCV实现动态人脸检测
2018/05/25 Python
使用Python的SymPy库解决数学运算问题的方法
2019/03/27 Python
Python基于paramunittest模块实现excl参数化
2020/04/26 Python
keras中的History对象用法
2020/06/19 Python
TensorFlow低版本代码自动升级为1.0版本
2021/02/20 Python
Java文件和目录(IO)操作
2014/08/26 面试题
品学兼优的大学生自我评价
2013/09/20 职场文书
家长给幼儿园的表扬信
2014/01/09 职场文书
装修五一活动策划案
2014/01/23 职场文书
总经理工作职责范文
2014/03/14 职场文书
关心下一代工作先进事迹
2014/08/15 职场文书
群众路线组织生活会发言材料
2014/10/17 职场文书
MySQL 8.0 Online DDL快速加列的相关总结
2021/06/02 MySQL