最近看了眼Nginx的日志,发现个人博客的日志上有很多爬虫在抓数据,还有在扫描漏洞的,搞不明白普普通通的一个个人博客得罪了谁。于是决定做一个简单的Nginx日志解析工具来稍微分析下数据。
Nginx的格式
Nginx日志对于统计、系统服务排错很有用。Nginx日志主要分为两种:access_log(访问日志)和error_log(错误日志)。通过访问日志我们可以得到用户的IP地址、浏览器的信息,请求的处理时间等信息。错误日志记录了访问出错的信息,可以帮助我们定位错误的原因。本文将详细描述一下如何配置Nginx日志。
access_log
访问日志主要记录客户端的请求。客户端向Nginx服务器发起的每一次请求都记录在这里。客户端IP,浏览器信息,referer,请求处理时间,请求URL等都可以在访问日志中得到。当然具体要记录哪些信息,你可以通过log_format指令定义。
Nginx预定义了名为combined日志格式,如果没有明确指定日志格式默认使用该格式:
log_format combined '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"';
如果不想使用Nginx预定义的格式,可以通过log_format指令来自定义。下面是log_format指令中常用的一些变量:
字段 | 含义 | 示例 |
– | 占位符 | – |
body_bytes_sent | 响应body字节数 | 3650 |
bytes_sent | 响应总字节数 | 175 |
host | IP或域名(不包括端口) | 10.10.10.14 |
http_host | IP或域名(包括端口) | 10.10.10.14:81 |
http_referer | referer信息 | http://10.10.10.14/ |
http_user_agent | UA信息 | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36 |
http_x_forwarded_for | XFF信息 | 192.168.1.1 |
remote_addr | 客户端地址 | 10.10.10.1 |
remote_user | 客户端认证用户名 | admin |
request | 请求URI和协议 | GET /favicon.ico HTTP/1.1 |
request_body | 请求的body | |
request_length | 请求长度 | 571 |
request_method | 请求方法 | GET |
request_time | 请求处理时间 | 0.000 |
response_body | 返回的body | |
response_header_data | 响应头数据 | |
schema | 协议 | http |
server_name | 虚拟主机名称 | |
server_port | 服务器端口 | |
server_protocol | 服务器协议 | |
ssl_cipher | 交换数据中的算法 | |
ssl_protocol | SSL协议版本 | |
status | 返回状态码 | 404 |
time_local | 时间戳 | 16/Jun/2019:23:29:50 -0400 |
upstream_addr | 后端提供服务地址 | |
upstream_connect_time | 与服务器连接所花费的时间 | |
upstream_response_time | 后端处理时间 | |
upstream_status | upstream状态 | 200 |
以下为一个默认记录格式下的请求记录:
123.6.49.9 - - [28/Dec/2023:00:26:02 +0800] "GET /aic-bic.html HTTP/2.0" 200 16923 "http://baidu.com/" "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Mobile Safari/537.36"
error_log
Nginx 的 error.log 记录了服务器在运行过程中遇到的错误和异常信息,这些信息对于管理员来说是非常重要的调试和排查工具。error.log 中包含的信息通常可以帮助管理员了解服务器的状态和运行情况,以及定位问题所在。下面是 error.log 中常见的几类信息:
- 启动和关闭信息:log 中会记录服务器的启动和关闭信息,包括启动时间、运行时间、关闭原因等。这些信息对于管理员来说是了解服务器状态的重要参考。
- 请求处理错误:如果服务器在处理请求时出现错误,log 会记录相关的错误信息,包括请求的 URL、客户端 IP、错误类型等。这些信息可以帮助管理员定位问题所在,如请求超时、请求大小超出限制等。
- 连接和网络错误:如果服务器在处理连接或网络时出现错误,log 会记录相关的错误信息,如不能连接到后端服务器、连接超时等。这些信息可以帮助管理员找到网络问题所在。
- 服务器错误:如果服务器本身出现错误,如内存不足、磁盘满了等,log 会记录相应的错误信息。这些信息可以帮助管理员及时发现并解决服务器问题。
- 安全问题:如果服务器受到攻击或发现安全问题,log 也会记录相关信息,如恶意请求、攻击尝试等。这些信息对于管理员来说是保护服务器安全的重要参考。
需要注意的是,error.log 记录的信息可能会包含敏感信息,如客户端 IP、请求 URL 等,因此需要妥善保护日志文件的访问权限,以免被未授权的用户查看或利用。
Python解析Nginx日志
这次要解析的主要是针对access.log进行解析,解析日志代码如下:
import re import pandas as pd with open('data/www.biaodianfu.com.access.log', 'r') as file: logs = file.readlines() log_pattern = r'(\d+\.\d+\.\d+\.\d+) - (.+?) \[(.+?)\] "(.+?)" (\d+) (\d+) "(.+?)" "(.+?)"' parsed_logs = [] for log in logs: match = re.match(log_pattern, log) if match: parsed_logs.append(match.groups()) df = pd.DataFrame(parsed_logs, columns=['ip', 'remote_user', 'time_local', 'request', 'status', 'body_bytes_sent', 'http_referer', 'user_agent']) df['time_local'] = pd.to_datetime(df['time_local'], format='%d/%b/%Y:%H:%M:%S %z').dt.tz_localize(None) df[['method', 'path', 'protocol']] = df['request'].str.split(' ', n=2, expand=True) def judge_request_type(path): if path: path = path.split('?')[0] if path.endswith(('.jpg', '.jpeg', '.png', '.gif', '.svg')): return '图片' elif path.endswith(('/feed')): return 'Feed' elif path.endswith(('.html', '.php')): return '网页' elif path.endswith('.js'): return 'JavaScript文件' elif path.endswith('.css'): return 'CSS文件' elif path.endswith(('.woff2', '.ttf')): return '字体' else: return '其他' else: return '首页' df['request_type'] = df['path'].apply(judge_request_type) # 调整显示设置 # pd.set_option('display.max_columns', 10) # pd.set_option('display.max_rows', 50) # pd.set_option('display.width', 1000) # pd.set_option('display.max_colwidth', 50) # print(df.head()) df.to_excel('nginx-log.xlsx')
这段代码的主要逻辑是定义了一个正则表达式 log_pattern,用于匹配 Nginx 日志的各个字段,并将它们作为一个元组添加到 parsed_logs 列表中。然后将数据转换为Pandas的DataFrame,再进行一些逻辑上的处理。然后保存到Excel中。由于数据量较少后续统计在Excel中进行。
看来博客质量高,也容易遭爬