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通过ssh-powershell监控windows的方法
Jun 02 Python
python获取文件路径、文件名、后缀名的实例
Apr 23 Python
anaconda如何查看并管理python环境
Jul 05 Python
Django REST framework 如何实现内置访问频率控制
Jul 23 Python
使用Pyinstaller转换.py文件为.exe可执行程序过程详解
Aug 06 Python
Tensorflow 多线程与多进程数据加载实例
Feb 05 Python
Python loguru日志库之高效输出控制台日志和日志记录
Mar 07 Python
使用python处理题库表格并转化为word形式的实现
Apr 14 Python
快速解决jupyter notebook启动需要密码的问题
Apr 21 Python
解决IDEA 的 plugins 搜不到任何的插件问题
May 04 Python
python中线程和进程有何区别
Jun 17 Python
从Pytorch模型pth文件中读取参数成numpy矩阵的操作
Mar 04 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中处理模拟rewrite 效果
2006/12/09 PHP
php获取本周星期一具体日期的方法
2015/04/20 PHP
PHP实现的AES双向加密解密功能示例【128位】
2018/09/03 PHP
boxy基于jquery的弹出层对话框插件扩展应用 弹出层选择器
2010/11/21 Javascript
JavaScript控制Session操作方法
2013/01/17 Javascript
让复选框只能选择一项的方法
2013/10/08 Javascript
DOM基础教程之使用DOM控制表单
2015/01/20 Javascript
javascript实现密码强度显示
2015/03/18 Javascript
你知道setTimeout是如何运行的吗?
2016/08/16 Javascript
jquery仿京东侧边栏导航效果
2017/03/02 Javascript
原生JS中slice()方法和splice()区别
2017/03/06 Javascript
jQuery+datatables插件实现ajax加载数据与增删改查功能示例
2018/04/17 jQuery
vue使用自定义icon图标的方法
2018/05/14 Javascript
vue router 源码概览案例分析
2018/10/09 Javascript
基于jQuery实现可编辑的表格
2019/12/11 jQuery
关于Node.js中频繁修改代码重启服务器的问题
2020/10/15 Javascript
Jquery Fade用法详解
2020/11/06 jQuery
几个提升Python运行效率的方法之间的对比
2015/04/03 Python
python正则表达式之作业计算器
2016/03/18 Python
Python数据拟合与广义线性回归算法学习
2017/12/22 Python
python使用opencv驱动摄像头的方法
2018/08/03 Python
python使用requests模块实现爬取电影天堂最新电影信息
2019/04/03 Python
python多线程并发实例及其优化
2019/06/27 Python
Python画图高斯分布的示例
2019/07/10 Python
Python 实现网课实时监控自动签到、打卡功能
2020/03/12 Python
python脚本监控logstash进程并邮件告警实例
2020/04/28 Python
丝芙兰巴西官方商城:SEPHORA巴西
2016/10/31 全球购物
Unix里面如何在后台运行程序
2016/10/14 面试题
学习全国两会精神心得体会范文
2014/03/17 职场文书
健康教育评估方案
2014/05/25 职场文书
财务人员岗位职责
2015/02/03 职场文书
酒店人事专员岗位职责
2015/04/07 职场文书
酒店客房服务员岗位职责
2015/04/09 职场文书
2015年共青团工作总结
2015/05/15 职场文书
详解Python requests模块
2021/06/21 Python
使用GO语言实现Mysql数据库CURD的简单示例
2021/08/07 Golang