【NGINX--11】利用访问日志、错误日志和 请求跟踪进行调试和故障排除

1、配置访问日志

需要配置访问日志格式,以将内置变量添加到请求日志中。

配置访问日志格式:

http {
    log_format geoproxy
        '[$time_local] $remote_addr ' 
        '$realip_remote_addr $remote_user '
        '$proxy_protocol_server_addr $proxy_protocol_server_port ' 
        '$request_method $server_protocol '
        '$scheme $server_name $uri $status ' 
        '$request_time $body_bytes_sent ' 
        '$geoip_city_country_code3 $geoip_region ' 
        '"$geoip_city" $http_x_forwarded_for ' 
        '$upstream_status $upstream_response_time ' 
        '"$http_referer" "$http_user_agent"';
    # ...
}

该日志格式配置被命名为 geoproxy,使用了大量内置变量来演示 NGINX 日志记录功能。该配置可输出发起请求时服务器上的本地时间、打开连接的 IP 地址,以及客户端的 IP 地址,因为 NGINX 根据 geoip_proxy 或 real_header 指令知道这些信息。

当 server 下的 listen 指令使用了 proxy_protocol 参数时,带 $ proxy_protocol_server_ 前缀的变量可用于从 PROXY 协议头中获取服务端相关信息。$remote_user 表示通过 Basic 认证的用户名;后面还包含请求方法、协议版本和协议类型,例如 HTTP 或HTTPS。当然也记录了匹配的 server 上下文名称、请求 URI 和响应状态码。

记录的统计信息包括以毫秒为单位的处理时间以及发送给客户端的消息体大小。此外,有关国家、地区和城市的信息也被记录在内。X-Forwarded-For HTTP 请求头可表明请求是否来自其它代理服务器转发。upstream 模块支持一些用于显示上游服务器响应状态和上游请求响应时间的内置变量。最后,有关客户端请求来源和客户端所用浏览器的信息也被记录在内。

log_format 指令仅在 HTTP 上下文中有效。可选参数 escape 可指定字符串转义类型,可选值有:default、json 和 none。none 表示禁用转义字符。default 时,字符 "、\ 以及其他值小于 32 或大于 126 的字符用 \xXX 来转义。如果找不到变量值,则使用连字符(-)替代。对于 json 转义,JSON 字符串中所有不允许的字符都将被转义,如:字符 " 和 \ 用 " 和 \ 来表示,值小于 32 的字符用 \n、\r、\t、\b、\f 或 \u00XX 来表示。

此日志配置的日志条目如下所示:

[25/Nov/2016:16:20:42 +0000] 10.0.1.16 192.168.0.122 Derek
GET HTTP/1.1 http www.example.com / 200 0.001 370 USA MI 
"Ann Arbor" - 200 0.001 "-" "curl/7.47.0"

如要使用此日志格式,则使用 access_log 指令,并将日志文件路径和格式名称geoproxy 用作参数:

server {
    access_log /var/log/nginx/access.log geoproxy;
    # ...
}

access_log 指令使用日志文件路径和格式名称作为参数。该指令在许多上下文中都有效,可根据上下文采用不同的日志路径和/或日志格式。buffer、flush 和 gzip 等参数可配置日志写入日志文件的频率以及文件是否被压缩。还可通过 if 指令设置输出条件,如果条件值为 0 或空字符串,则访问将不被记录。
详解
NGINX 中的 log 模块允许您为许多不同的场景配置日志格式,以根据需要记录到不同日志文件中。在实际运用中,为不同上下文配置不同的日志格式非常有用,您可以在日志中使用不同的模块和内置变量,或者集中提供所有必要信息。日志也能记录以JSON 格式和 XML 格式创建的字符串。这些日志将帮助您了解流量模式、客户端使用情况和客户端来源等。此外,访问日志还可以帮助您发现与上游服务器或特定 URI 相关的响应延迟和问题。访问日志还可用于在测试环境中解析和回放流量模式,以模仿真实的用户交互。日志在应用故障排除、调试或市场分析中发挥着至关重要的作用。

2、配置错误日志

需要配置错误日志,以更深入地了解 NGINX 服务器问题。

使用 error_log 指令定义日志路径和日志级别:

error_log /var/log/nginx/error.log warn;

在配置 error_log 指令时,路径是必选的,但日志级别是可选的,默认为 error。除 if 语句以外,该指令在所有上下文中都有效。日志级别包括 debug(调试)、info(信息)、notice(注意)、warn(警告)、error(错误)、crit(严重)、alert(警报)和 emerg(紧急)。上述日志级别的排列顺序也是严重程度从低到高的顺序。debug 日志级别仅在 NGINX 配置了 --with-debug 标记时可用。
详解
当配置文件无法正常工作时,应首先查看错误日志。错误日志也是定位由 FastCGI 等应用服务器所产生的错误的利器。还可以使用错误日志来调试 worker 进程连接、内存分配、客户端 IP 和服务器。错误日志虽然不支持自定义日志格式,但也遵循特定格式 —— 先列出日期,随后列出日志级别和具体消息。

3、转发日志到 Syslog

需要将日志转发到 Syslog 侦听器,以便将日志聚合到集中式日志服务中。

使用 error_log 和 access_log 指令将日志发送到 Syslog 侦听器:

error_log syslog:server=10.0.1.42 debug;
access_log syslog:server=10.0.1.42,tag=nginx,severity=info geoproxy;

error_log 和 access_log 指令的 syslog 参数后面紧跟冒号和一些参数选项。这些选项包括必要的日志服务标识,如:需要连接的 IP 地址、DNS 名称或 Unix socket,以及 facility、severity、tag 和 nohostname 等可选标记。server 选项在指定指 IP 地址或 DNS 名称时设置端口号,默认为 UDP 514。facility 选项是指日志消息的 facility 值,取 Syslog RFC 标准定义的 23 个值之一;默认值为 local7。tag 选项表示消息的标记,默认值为 nginx。severity 选项默认为 info,表示所发送消息的日志级别。nohostname 标记禁止将 hostname 字段添加到 syslog 消息头中,不取值。
详解
Syslog 是一种在单台服务器或服务器集群上发送和收集日志消息的标准协议。在多个主机上运行相同服务的多个实例时,将日志发送到集中位置有助于调试。这被称作聚合日志。聚合日志允许您在一个地方查看日志,无需切换服务器,并通过时间戳将日志文件合并在一起。常见的日志聚合堆栈有 Elasticsearch、Logstash 和 Kibana,统称为 ELK 堆栈。NGINX 可使用 access_log 和 error_log 指令,轻松将这些日志传输到 Syslog 侦听器。

4、请求跟踪

需要将 NGINX 日志与应用日志相关联,以了解请求的端到端处理过程。
解决方案
使用 request 的唯一识别变量,并将其传递给应用以进行记录:

log_format trace '$remote_addr - $remote_user [$time_local] ' 
                 '"$request" $status $body_bytes_sent ' 
                 '"$http_referer" "$http_user_agent" ' 
                 '"$http_x_forwarded_for" $request_id';
upstream backend { 
    server 10.0.0.42;
}
server {
    listen 80;
    # 将 X-Request-ID 标头添加到对客户端的响应中
    add_header X-Request-ID $request_id;
    location / {
        proxy_pass http://backend;
        # 将 X-Request-ID 标头发送到应用端
        proxy_set_header X-Request-ID $request_id; 
        access_log /var/log/nginx/access_trace.log trace;
    }
}

在本示例配置中,配置了名为 trace 的 log_format,并在日志中使用了 $ request_id 变量。还在发起上游请求时,通过使用 proxy_set_header 指令将请求 ID 添加到请求头里,将此 $ request_id 变量传递给了上游应用。此外,还通过使用 add_header 指令,在响应头中设置请求 ID,将请求 ID 传回客户端。
详解
该功能在 NGINX Plus R10 和 NGINX 1.11.0 版本中可用,$request_id 提供了一个随机生成的 32 位十六进制字符串,这些字符可以用来唯一性标识请求。通过将此标识符传递给客户端和应用,您可以将日志与请求相关联。在前端客户端,你可通过响应头收到该请求唯一性标识字符串,并且可以利用它在日志中搜索与请求相关联的条目。您还需要在应用日志中捕获和记录此请求唯一性标头,从而在日志之间建立真正的端到端关联。基于这项功能,NGINX 让跨应用栈跟踪请求变为可能。

5、用于 NGINX 的 OpenTracing

拥有一台支持 OpenTracing 的跟踪服务器,需要与 NGINX 或 NGINX Plus 相集成。

确保拥有一台兼容 OpenTracing 的服务器,并且在 NGINX 或 NGINX Plus 节点上安装了正确的客户端。
需要使用面向该特定服务器的插件配置文件。该解决方案将演示 Jaeger 和 Zipkin。

名为 /etc/jaeger/jaeger-config.json 的 Jaeger 插件配置示例如下所示:

{
    "service_name": "nginx",
    "sampler": { 
        "type": "const", 
        "param": 1
    },
    "reporter": {
        "localAgentHostPort": "Jaeger-server-IP-address:6831"
    }
}

名为 /etc/zipkin/zipkin-config.json 的 Zipkin 插件配置示例如下所示:

{
    "service_name": "nginx",
    "collector_host": "Zipkin-server-IP-address",
    "collector_port": 9411
}

如果使用 NGINX Plus,则按照《NGINX Plus OpenTracing 管理员指南》从 NGINX Plus 仓库安装 OpenTracing 模块。

如果使用开源 NGINX,则访问“NGINX OpenTracing 模块版本”页面,查找与系统兼容的预构建动态模块或使用源代码编译该 NGINX 模块。或者,在 Docker 环境中,可使用 Docker Hub 上名为 opentracing/nginx-opentracing 的镜像快速开始测试。

使用动态加载的模块(包括 NGINX Plus 安装)时,可通过添加下述 load_module 指令,向 NGINX 告知该模块在文件系统上的位置,来确保将其加载到 NGINX 配置中。值得注意的是,load_module 指令仅在主(顶级)上下文中有效。

load_module modules/ngx_http_opentracing_module.so;

当一个兼容 OpenTracing 的服务器开始侦听,客户端已安装到 NGINX 节点上,插件配置部署完毕,以及 NGINX 模块加载完毕后,即可对 NGINX 进行配置,以发起跟踪请求。以下代码提供了加载跟踪插件并将 NGINX 配置为标记请求的示例。其中包含加载跟踪插件的指令,而 Jaeger 和 Zipkin 插件及其配置文件的默认位置已在前面提供。

可根据用例取消对适当厂商示例的注释。

# 加载厂商跟踪器
#opentracing_load_tracer /usr/local/libjaegertracing_plugin.so
# /etc/jaeger/jaeger-config.json;
#opentracing_load_tracer /usr/local/lib/libzipkin_opentracing_plugin.so
# /etc/zipkin/zipkin-config.json;
# 开启所有请求追踪
opentracing on; 
# 设置捕捉 NGINX 变量值的附加标记
opentracing_tag bytes_sent $bytes_sent;
opentracing_tag http_user_agent $http_user_agent;
opentracing_tag request_time $request_time;
opentracing_tag upstream_addr $upstream_addr;
opentracing_tag upstream_bytes_received $upstream_bytes_received;
opentracing_tag upstream_cache_status $upstream_cache_status;
opentracing_tag upstream_connect_time $upstream_connect_time;
opentracing_tag upstream_header_time $upstream_header_time;
opentracing_tag upstream_queue_time $upstream_queue_time;
opentracing_tag upstream_response_time $upstream_response_time;

server {
    listen 9001;
    location / {
        # 用于 OpenTracing Span 的操作名
        # 默认为 location 代码块的名称,
        # 但可取消对此指令的注释,以进行自定义。
        #opentracing_operation_name $uri;
        # 传播活动 Span 上下文 upstream,
        # 以便后端可继续跟踪。
        opentracing_propagate_context;
        # 应用的 location 服务示例
        proxy_pass http://10.0.0.2:8080;
    }
}

详解
OpenTracing 设置并非无关紧要,相反它在性能和事务的分布式监控方面发挥着重要作用。这些工具支持团队高效发现根本原因和开展依赖性分析,利用数据精准定位问题。NGINX 可以用作 API 网关,对应用之间的请求进行路由和授权,并为在复杂系统中跟踪请求提供全面信息。

NGINX 可使用自身可用的任何变量标记请求,以帮助跟踪系统用户充分了解请求的行为。本示例提供了使用 OpenTracing 跟踪代理请求的有限示例。由于 opentracing_tag 指令在 http、server 和 location 上下文中均有效,因此可利用 NGINX 获取大量数据。
参考资料
“OpenTracing NGINX 模块 GitHub”
《NGINX Plus OpenTracing 动态模块管理员指南》
Datadog 指南中的“代理跟踪”插件指南
“面向 NGINX 和 NGINX Plus 的 OpenTracing”
“采用 NGINX Ingress Controller for Kubernetes 支持 OpenTracing”

  • 17
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白--AI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值