日志是服务器运维、问题排查、用户行为分析的核心依据。不同服务器(如 Nginx、Apache、Tomcat)的日志格式虽有差异,但核心逻辑均围绕 “记录请求与响应关键信息” 展开。本文将以 Nginx 日志为核心,从格式定义、字段解析、日志类型、实战场景等维度进行全面解析。Nginx 日志是服务器运行与业务运维的 “核心仪表盘”,其重要性贯穿于技术保障与业务优化的全流程。
Nginx 日志分为两类:访问日志(Access Log) 和 错误日志(Error Log),在主配置文件nginx.conf
或虚拟主机配置 /etc/nginx/conf.d/nginx.conf
定义。首先得找到nginx的所在位置,然后根据其配置信息找到日志信息。
访问日志是最常用的日志类型,记录 “谁在什么时间、用什么方式、访问了什么资源、服务器如何响应” 等信息,需先通过 log_format
定义格式,再通过 access_log
指定日志存储路径。说人话就是定义访问日志的路径、格式和缓冲区大小,记录所有用户请求。
Nginx 有一个默认的简单格式(无需显式定义),但生产环境中通常会自定义更详细的格式(如包含请求体大小、响应时间、用户代理等)。
格式类型 | 配置示例 | 说明 |
---|---|---|
默认格式 | 无需定义,直接使用:access_log /var/log/nginx/access.log; | 仅包含核心字段(远程 IP、时间、请求方法、URL、状态码、响应大小) |
自定义详细格式 | 参考下面的代码 | 包含用户代理、响应时间、上游服务时间等关键排查字段,推荐生产环境使用 |
自定义详细格式样例
# 定义 main_detail 格式(换行仅为可读性,实际配置可写为一行)
log_format main_detail
'$remote_addr - $remote_user [$time_local] ' # 客户端基础信息 + 请求时间
'"$request" $status $body_bytes_sent ' # 请求核心信息 + 响应状态与大小
'"$http_referer" "$http_user_agent" ' # 来源页 + 客户端设备特征
'$request_time $upstream_response_time ' # 性能指标:总耗时 + 上游服务耗时
'$http_x_forwarded_for $scheme $server_name ' # 代理场景真实IP + 协议 + 站点域名
'$request_method $request_uri'; # 单独拆分请求方法与请求路径
# 启用该格式(全局生效或绑定到具体 server 块),全局生效(在 http 块中配置)
access_log /var/log/nginx/access.log main_detail;
# 或仅对某站点生效(在 server 块中配置,优先级高于全局)
server {
listen 80;
server_name example.com;
access_log /var/log/nginx/example.com-access.log main_detail; # 站点专属日志文件
# 其他站点配置...
}
自定义格式中的 $变量名
是 Nginx 内置变量,对应日志中的具体值,下表为高频字段的详细解释:
变量名 | 日志示例 | 含义与作用 |
---|---|---|
$remote_addr | IP地址/ IP地址 | 客户端真实 IP(若有反向代理,需配置 real_ip_header 获取真实 IP) |
$remote_user | - | 客户端通过 HTTP 认证的用户名(未启用认证时为 -) |
$time_local | 31/Aug/2025 19:30:00 +0800 | 服务器本地时间(格式:日/月/年:时:分:秒 时区) |
$request | GET /index.html HTTP/1.1 | 完整请求信息,包含三部分:1. 请求方法(GET/POST/PUT/DELETE 等)2. 请求 URL(如 /api/user)3. HTTP 协议版本(HTTP/1.1/2.0) |
$status | 200 / 404 / 502 | HTTP 响应状态码(核心排查字段,见下文 “状态码含义”) |
$body_bytes_sent | 1536 | 服务器向客户端发送的响应体大小(单位:字节,不含响应头) |
$http_referer | 映射域名地址 | referer(来源页):用户从哪个页面跳转过来(直接输入 URL 时为 -),可用于防盗链 |
$http_user_agent | Mozilla/5.0 (Windows NT...) | User-Agent(UA):客户端设备信息(浏览器、操作系统、设备型号),用于用户画像 |
$request_time | 0.05 | 从请求进入 Nginx 到响应完成的总时间(单位:秒,含等待上游服务的时间) |
$upstream_response_time | 0.03 | Nginx 转发请求到上游服务(如 Tomcat、PHP-FPM)后,上游服务的响应时间(单位:秒,无上游服务时为 -),用于定位上游服务瓶颈 |
$http_x_forwarded_for | IP地址,使用逗号隔开,例如10.10.10.10,10.10.10.11 | 多层代理场景下的客户端 IP 链(第一个值为真实客户端 IP,后续为代理服务器 IP) |
$status
字段的状态码直接反映请求结果,常见状态码分类如下:
错误日志记录 Nginx 自身运行错误(如配置错误、连接失败)或请求处理中的异常(如无法连接上游服务),格式无需自定义,由 Nginx 自动生成,核心配置为 error_log
。
# 格式:error_log 日志路径 日志级别;
error_log /var/log/nginx/error.log warn;
日志级别决定记录的错误详细程度,生产环境推荐 warn
或 error
(避免日志过大),调试时用 debug
(需 Nginx 编译时开启 debug 模块):
级别 | 含义 |
---|---|
debug | 调试信息(最详细,含内部运行细节,仅用于开发 / 调试) |
info | 普通信息(如服务启动、配置重载) |
notice | 注意信息(非错误,但需关注,如端口复用) |
warn | 警告信息(潜在问题,如配置不规范、连接超时) |
error | 错误信息(影响请求处理的错误,如无法连接上游、文件权限不足) |
crit | 严重错误(影响服务运行的错误,如端口绑定失败) |
alert | 紧急错误(需立即处理,如配置文件语法错误导致服务无法启动) |
emerg | 致命错误(服务完全无法运行) |
2025/08/31 19:35:00 [error] 1234#0: *567 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.1.100, server: example.com, request: "GET /api/data HTTP/1.1", upstream: "http://127.0.0.1:8080/api/data", host: "sfasfasf.com"
2025/08/31 19:35:00
[error]
1234#0
(#0
为线程 ID)*567
(Nginx 内部标识该请求的连接)connect() failed (111: Connection refused)
(连接上游服务被拒绝)client: 192.168.1.100
request: "GET /api/data HTTP/1.1"
upstream: "http://127.0.0.1:8080/api/data"
(目标上游服务地址)除 Nginx 外,Apache(HTTP Server)和 Tomcat(Java 应用服务器)的日志格式与 Nginx 相似,但存在细节差异,下表对比核心信息:
服务器 | 日志类型 | 默认存储路径(Linux) | 核心字段差异 |
---|---|---|---|
Apache | 访问日志 | /var/log/httpd/access_log | 1. 时间格式:[31/Aug/2025:19:30:00 -0400](与 Nginx 一致)2. 新增 $remote_logname(客户端主机名,通常为 -)3. 响应大小字段为 $bytes_sent(含响应头,Nginx 的 $body_bytes_sent 不含) |
错误日志 | /var/log/httpd/error_log | 级别与 Nginx 类似,但格式前缀为 [Tue Aug 31 19:35:00.123 2025] [error] [pid 1234:tid 567](含线程 ID tid) | |
Tomcat | 访问日志(Access Log) | $CATALINA_HOME/logs/localhost_access_log.2025-08-31.txt | 1. 需在 conf/server.xml 中启用 AccessLogValve 组件2. 默认格式:192.168.1.100 - - [31/OAug/2025:19:30:00 +0800] "GET /index.jsp HTTP/1.1" 200 1234(与 Nginx 默认格式类似)3. 可自定义包含 responseTime(响应时间)、bytesSent(响应大小)等字段 |
错误日志(Catalina Log) | $CATALINA_HOME/logs/catalina.out | 1. 记录 Tomcat 自身运行错误(如启动失败、JVM 异常)和应用日志(如 Java 异常栈)2. 格式含时间戳和日志级别(如 2025-08-31 19:35:00.123 SEVERE [main] org.apache.catalina.core.StandardService.startInternal Failed to start connector) |
了解日志解析后,需结合实际场景定位问题,以下是我常遇到的高频场景以及排查思路:
用户反馈 “页面打不开,显示 502”
$status
为 502,$upstream_response_time
为 -
(表示未连接到上游)。502
或 Connection refused
,若日志显示 connect() failed (111: Connection refused) while connecting to upstream
,说明 Nginx 无法连接上游服务(如 Tomcat)。telnet 127.0.0.1 8080
(假设上游端口为 8080),若提示 “连接拒绝”,则上游服务(Tomcat)未启动,需重启 Tomcat 并查看 catalina.out
日志定位启动失败原因(如端口被占用、配置错误)。网站访问速度慢,排查瓶颈
$request_time
(总时间)和 $upstream_response_time
(上游时间)。$upstream_response_time
较大(如 >1s):瓶颈在上游服务(如 Tomcat 处理慢),需查看 Tomcat 应用日志(如 SQL 执行慢、代码逻辑耗时)。$upstream_response_time
小(如 <0.1s),但 $request_time
大:瓶颈在 Nginx 或网络,需检查 Nginx 配置(如是否开启 gzip、缓存)或客户端网络(如 $remote_addr
来自海外,需考虑 CDN 加速)。发现 “大量 403 错误,来自同一 IP”
$status=403
且 $remote_addr=192.168.1.200
的请求,确认请求的 URL(如 /admin/login
)。allow 192.168.1.0/24; deny all;
,而 192.168.1.200 不在允许列表)。nginx
无读取 /var/www/html/xxx.jpg
的权限),需执行 chmod 644 /var/www/html/xxx.jpg
修正权限。日志会持续生成,若不管理会导致磁盘占满,同时原始日志查询效率低,避免日志膨胀与提高查询效率,需配合以下工具优化。
日志切割:使用 logrotate
(Linux 自带工具)按天 / 按大小切割日志,避免单个日志文件过大。示例配置(/etc/logrotate.d/nginx
)如下:
/var/log/nginx/*.log {
daily # 按天切割
rotate 7 # 保留7天日志
compress # 压缩旧日志(gzip)
delaycompress # 延迟压缩(保留当天日志不压缩)
missingok # 日志文件不存在时不报错
notifempty # 空日志不切割
create 0640 nginx nginx # 新建日志文件的权限和所有者
}
日志分析工具:对于大规模日志(如日活百万级网站),需使用 ELK Stack(Elasticsearch + Logstash + Kibana)或 Grafana Loki 等工具,实现日志的收集、存储、检索和可视化(如按状态码统计请求量、按 IP 统计访问次数)。
日志是服务器的 “黑盒记录仪”,核心在于下面三个点:
$status
(状态码)、$request_time
(响应时间)、错误原因描述。$upstream_response_time
)。原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。