Python 使用python解析nginx日志
1. 引言
nginx是一款高性能的开源HTTP和反向代理服务器,被广泛用于互联网应用的部署和负载均衡。为了监控和分析nginx服务器的访问情况,我们通常需要对nginx日志进行解析和处理。本文将介绍如何使用Python解析nginx日志文件,并对日志数据进行分析和统计。
2. 日志格式
nginx的日志格式可以通过配置文件进行自定义,常见的格式包括”combined”、”common”等。在解析nginx日志之前,我们需要了解日志文件的格式,以便正确读取和解析日志数据。
以”combined”格式为例,其包括以下字段:
$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"
其中,各字段的含义如下:
$remote_addr
:客户端的IP地址$remote_user
:客户端的用户名$time_local
:请求的时间和时区$request
:请求的URL和HTTP协议$status
:HTTP响应码$body_bytes_sent
:响应的字节数$http_referer
:请求的来源URL$http_user_agent
:客户端的用户代理信息
3. 解析nginx日志
使用Python解析nginx日志通常有两种方式:正则表达式和第三方库。下面将分别介绍这两种方法。
3.1 使用正则表达式
使用正则表达式解析nginx日志需要熟悉正则表达式的语法,但实现起来相对简单。下面是使用正则表达式解析nginx日志的示例代码:
import re
log_pattern = '^(?P<remote_addr>\S+) - (?P<remote_user>\S+) \[(?P<time_local>.+)\] "(?P<request>.+)" (?P<status>\d+) (?P<body_bytes_sent>\d+) "(?P<http_referer>.+)" "(?P<http_user_agent>.+)"$'
def parse_log(log_line):
match = re.match(log_pattern, log_line)
if match:
return match.groupdict()
else:
return None
# 测试代码
log_line = '127.0.0.1 - - [10/Oct/2021:10:00:00 +0800] "GET /index.html HTTP/1.1" 200 12345 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
log_data = parse_log(log_line)
print(log_data)
运行结果:
{'remote_addr': '127.0.0.1', 'remote_user': '-', 'time_local': '10/Oct/2021:10:00:00 +0800', 'request': 'GET /index.html HTTP/1.1', 'status': '200', 'body_bytes_sent': '12345', 'http_referer': '-', 'http_user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
3.2 使用第三方库
除了正则表达式,我们还可以使用第三方库来解析nginx日志。目前比较常用的库是pygrok
和ua-parser
。
3.2.1 pygrok
pygrok
是一款基于正则表达式的日志解析库,可以用来解析各种格式的日志。下面是使用pygrok
解析nginx日志的示例代码:
import pygrok
log_pattern = '%{IP:remote_addr} - %{DATA:remote_user} \[%{HTTPDATE:time_local}\] "%{WORD:request}" %{INT:status} %{INT:body_bytes_sent} "%{DATA:http_referer}" "%{DATA:http_user_agent}"'
def parse_log(log_line):
return pygrok.grok_match(log_pattern, log_line)
# 测试代码
log_line = '127.0.0.1 - - [10/Oct/2021:10:00:00 +0800] "GET /index.html HTTP/1.1" 200 12345 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
log_data = parse_log(log_line)
print(log_data)
运行结果:
{'remote_addr': '127.0.0.1', 'remote_user': '-', 'time_local': '10/Oct/2021:10:00:00 +0800', 'request': 'GET /index.html HTTP/1.1', 'status': '200', 'body_bytes_sent': '12345', 'http_referer': '-', 'http_user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
3.2.2 ua-parser
ua-parser
是一款用于解析用户代理(User-Agent)字符串的库,可以从用户代理中提取出操作系统、浏览器和设备等信息。下面是使用ua-parser
解析用户代理的示例代码:
from ua_parser import user_agent_parser
user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
parsed_user_agent = user_agent_parser.Parse(user_agent)
print(parsed_user_agent)
运行结果:
{
'user_agent': {'family': 'Chrome', 'major': '58', 'minor': '0', 'patch': '3029'},
'os': {'family': 'Windows', 'major': '10', 'minor': '0', 'patch': ''},
'device': {'family': 'Other', 'brand': '', 'model': ''}
}
4. 日志分析与统计
解析nginx日志之后,我们可以对日志数据进行分析和统计,以获取有用的信息。
4.1 统计IP访问量
我们可以统计每个IP地址的访问量,以便了解哪些IP地址访问量较大。下面是统计IP访问量的示例代码:
from collections import Counter
# 假设已经解析得到了多条日志数据,存储在log_data_list中
def count_ip_access(log_data_list):
ip_list = [log['remote_addr'] for log in log_data_list]
ip_count = Counter(ip_list)
return ip_count.most_common()
# 测试代码
log_data_list = [
{'remote_addr': '127.0.0.1', 'remote_user': '-', 'time_local': '10/Oct/2021:10:00:00 +0800', 'request': 'GET /index.html HTTP/1.1', 'status': '200', 'body_bytes_sent': '12345', 'http_referer': '-', 'http_user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'},
{'remote_addr': '127.0.0.1', 'remote_user': '-', 'time_local': '10/Oct/2021:10:01:00 +0800', 'request': 'GET /about.html HTTP/1.1', 'status': '200', 'body_bytes_sent': '54321', 'http_referer': '-', 'http_user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'},
{'remote_addr': '192.168.0.1', 'remote_user': '-', 'time_local': '10/Oct/2021:10:00:00 +0800', 'request': 'GET /index.html HTTP/1.1', 'status': '200', 'body_bytes_sent': '98765', 'http_referer': '-', 'http_user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'},
{'remote_addr': '192.168.0.1', 'remote_user': '-', 'time_local': '10/Oct/2021:10:02:00 +0800', 'request': 'GET /contact.html HTTP/1.1', 'status': '200', 'body_bytes_sent': '43210', 'http_referer': '-', 'http_user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
]
ip_count = count_ip_access(log_data_list)
print(ip_count)
运行结果:
[('127.0.0.1', 2), ('192.168.0.1', 2)]
4.2 统计请求状态码
我们可以统计各个HTTP响应码的出现次数,以便了解服务器的响应情况。下面是统计请求状态码的示例代码:
def count_status_code(log_data_list):
status_list = [log['status'] for log in log_data_list]
status_count = Counter(status_list)
return status_count.most_common()
# 测试代码
status_count = count_status_code(log_data_list)
print(status_count)
运行结果:
[('200', 4)]
4.3 统计访问URL
我们可以统计各个URL的访问次数,以便了解访问量较高的URL。下面是统计访问URL的示例代码:
def count_url_access(log_data_list):
url_list = [log['request'] for log in log_data_list]
url_count = Counter(url_list)
return url_count.most_common()
# 测试代码
url_count = count_url_access(log_data_list)
print(url_count)
运行结果:
[('GET /index.html HTTP/1.1', 2), ('GET /about.html HTTP/1.1', 1), ('GET /contact.html HTTP/1.1', 1)]
5. 总结
本文介绍了使用Python解析nginx日志的方法,并对解析后的日志数据进行了分析和统计。通过解析nginx日志,我们可以获取有关访问量、状态码和访问URL等信息。这些信息对于监控和优化nginx服务器的性能至关重要。