Nginx和New Relic:使用OpenTelemetry来集中和可视化跟踪信息
目前情况
nginx是一个被广泛使用的高性能和稳定的Web服务器。它具备负载均衡、反向代理和缓存功能,并且在Web应用程序构建中是必不可少的。由于其灵活的配置和可扩展性,nginx已成为许多企业和服务所信赖的软件。
新的雷力公司利用基础设施和应用性能管理(APM)代理来收集中间件和应用程序的状态和性能信息。APM代理通过收集事务的跟踪数据和日志,可以按事务单元追踪应用程序性能的下降,并自动识别输出的日志。
要提高Web应用程序的可观测性,必须使用nginx的可视化功能。特别是通过自动化分析应用程序与nginx之间的关联性和每个事务,可以实现调查效率和工时减少。
简述
本文将使用OpenTeremetry来收集nginx的遥测数据中的指标和追踪,并详细说明在New Relic中可视化数据的配置步骤。
对于nginx的仪表化,我们将使用OpenTelemetry nginx模块。该模块利用了OpenTelemetry的分布式追踪功能,使得收集nginx的遥测数据成为可能。
在New Relic平台上查看遥测数据
我将介绍如何通过OpenTelemetry Collector将由OpenTelemetry nginx模块收集的遥测数据与New Relic集成,以便查看数据。
前提 tí)
我正在使用Docker Compose来构建验证环境。
project/
├─ containers /
│ ├─ nginx.dockerfile
│ └ php.dockerfile
├─ nginx /
│ ├─ nginx.conf
│ └ default.conf
├─ src /
│ ├─ index.php
│ └ test.php
└ docker-compose.yml
version: '3'
services:
# nginx
web:
container_name: nginx_web
platform: 'linux/amd64'
build:
context: .
dockerfile: ./containers/nginx.dockerfile
ports:
- "8080:80"
depends_on:
- php
# PHP
php:
container_name: php-fpm
platform: 'linux/amd64'
build:
context: .
dockerfile: ./containers/php.dockerfile
environment:
# 環境変数でNew Relicのライセンスキーを設定
- NEW_RELIC_LICENSE_KEY
为了后续的PHP应用程序,我们安装了New Relic的APM代理程序,以收集应用程序的遥测数据。
FROM php:7-fpm
COPY ./src /var/www/html
# New RelicのAPMエージェントの導入
RUN \
curl -L https://download.newrelic.com/php_agent/release/newrelic-php5-10.11.0.3-linux.tar.gz | tar -C /tmp -zx && \
export NR_INSTALL_USE_CP_NOT_LN=1 && \
export NR_INSTALL_SILENT=1 && \
/tmp/newrelic-php5-*/newrelic-install install && \
rm -rf /tmp/newrelic-php5-* /tmp/nrinstall* && \
sed -i \
# New Relicのライセンスキーの設定
-e 's/"REPLACE_WITH_REAL_KEY"/"${NEW_RELIC_LICENSE_KEY}"/' \
# New Relicで表示されるアプリケーションの名称
-e 's/newrelic.appname = "PHP Application"/newrelic.appname = "Docker PHP Application"/' \
-e 's/;newrelic.daemon.app_connect_timeout =.*/newrelic.daemon.app_connect_timeout=15s/' \
-e 's/;newrelic.daemon.start_timeout =.*/newrelic.daemon.start_timeout=5s/' \
/usr/local/etc/php/conf.d/newrelic.ini
安装 OpenTelemetry Collector
首先,通过OpenTelemetry Collector将nginx的遥测数据集成到New Relic。 首先,需要进行OpenTelemetry Collector的配置。
+ # OpenTelemetry Collector
+ otel-collector:
+ container_name: otel-collector
+ platform: 'linux/amd64'
+ image: otel/opentelemetry-collector-contrib:0.83.0
+ restart: always
+ command: ["--config=/etc/otel-config.yml", ""]
+ volumes:
+ - ./otel-config.yml:/etc/otel-config.yml
+ environment:
+ # 環境変数でNew Relicのライセンスキーを設定
+ - NEW_RELIC_LICENSE_KEY
为了将数据从OpenTelemetry Collector传送到New Relic,需要进行exporters的设置。这些设置内容参考了New Relic的官方文档。
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
exporters:
otlp:
endpoint: https://otlp.nr-data.net:4317
headers:
api-key: ${NEW_RELIC_LICENSE_KEY} # New Relicのライセンスキーを環境変数に設定
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [otlp]
logs:
receivers: [otlp]
processors: [batch]
exporters: [otlp]
OpenTelemetry和New Relic之间的协作使用了OTLP协议,因此不需要额外添加插件等。关于OpenTelemetry和New Relic的协作详细介绍,请参考此篇博客。
构建模块
中国的母语,只需要一种选择:
GitHub Actions 提供了使用 OpenTelemetry nginx 模块的方法,通过从.so文件进行下载并使用。但是,由于要求是操作系统为Linux,且nginx版本必须是Stable(1.18.0)或mainline(1.19.8),在Docker环境中无法使用。
因此,我们将通过构建模块来使用它。由于GitHub的Readme提供的信息有限,我们会参考此处的问题进行操作。
FROM nginx:1.23.1-alpine as builder
RUN apk update \
&& apk add --update \
alpine-sdk build-base cmake linux-headers libressl-dev pcre-dev zlib-dev \
curl-dev protobuf-dev c-ares-dev \
re2-dev abseil-cpp
# 依存関係にある gRPC のビルド
ENV GRPC_VERSION v1.43.2
RUN git clone --shallow-submodules --depth 1 --recurse-submodules -b ${GRPC_VERSION} \
https://github.com/grpc/grpc \
&& cd grpc \
&& mkdir -p cmake/build \
&& cd cmake/build \
&& cmake \
-DgRPC_INSTALL=ON \
-DgRPC_BUILD_TESTS=OFF \
-DCMAKE_INSTALL_PREFIX=/install \
-DCMAKE_BUILD_TYPE=Release \
-DgRPC_BUILD_GRPC_NODE_PLUGIN=OFF \
-DgRPC_BUILD_GRPC_OBJECTIVE_C_PLUGIN=OFF \
-DgRPC_BUILD_GRPC_PHP_PLUGIN=OFF \
-DgRPC_BUILD_GRPC_PHP_PLUGIN=OFF \
-DgRPC_BUILD_GRPC_PYTHON_PLUGIN=OFF \
-DgRPC_BUILD_GRPC_RUBY_PLUGIN=OFF \
../.. \
&& make -j2 \
&& make install
# 依存関係にある opentelemetry-cpp のビルド
ENV OPENTELEMETRY_VERSION v1.3.0
RUN git clone --shallow-submodules --depth 1 --recurse-submodules -b ${OPENTELEMETRY_VERSION} \
https://github.com/open-telemetry/opentelemetry-cpp.git \
&& cd opentelemetry-cpp \
&& mkdir build \
&& cd build \
&& cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/install \
-DCMAKE_PREFIX_PATH=/install \
-DWITH_ZIPKIN=OFF \
-DWITH_JAEGER=OFF \
-DWITH_OTLP=ON \
-DWITH_OTLP_GRPC=ON \
-DWITH_OTLP_HTTP=OFF \
-DBUILD_TESTING=OFF \
-DWITH_EXAMPLES=OFF \
-DWITH_ABSEIL=ON \
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
.. \
&& make -j2 \
&& make install
# otel_ngx_module.so のビルド
RUN git clone https://github.com/open-telemetry/opentelemetry-cpp-contrib.git \
&& cd opentelemetry-cpp-contrib/instrumentation/nginx \
&& mkdir build \
&& cd build \
&& cmake -DCMAKE_BUILD_TYPE=Release \
-DNGINX_BIN=/usr/sbin/nginx \
-DCMAKE_PREFIX_PATH=/install \
-DCMAKE_INSTALL_PREFIX=/usr/lib/nginx/modules \
-DCURL_LIBRARY=/usr/lib/libcurl.so.4 \
.. \
&& make -j2 \
&& make install
FROM nginx:1.23.1-alpine
RUN apk update \
&& apk add --update \
grpc protobuf c-ares
# ビルドしたモジュールを実行環境へコピー
COPY --from=builder /usr/lib/nginx/modules/otel_ngx_module.so /usr/lib/nginx/modules/
# NGINXの設定ファイルを所定の場所へコピー
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
建议您在构建与 gRPC 和 opentelemetry-cpp 相依赖的模块后,再构建 otel_ngx_module.so。由于构建时间较长,建议您准备一个用于构建的 Docker 环境,并从中提取模块以供使用。
nginx和模块的设置
通过更改nginx的配置文件来加载otel_ngx_module.so。在nginx.dockerfile中将otel_ngx_module.so放置在/usr/lib/nginx/modules/otel_ngx_module.so路径下,然后在nginx.conf中加载这个文件。同时,定义otel_ngx_module.so的配置文件。
user nginx;
worker_processes 1;
+# otel_ngx_module.soをロード
+load_module /usr/lib/nginx/modules/otel_ngx_module.so;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
+ # otel_ngx_module.soの設定ファイル
+ opentelemetry_config /conf/otel-nginx.toml;
log_format json escape=json '{"time": "$time_iso8601",'
'"host": "$remote_addr",'
'"vhost": "$host",'
'"user": "$remote_user",'
'"status": "$status",'
'"protocol": "$server_protocol",'
'"method": "$request_method",'
'"path": "$request_uri",'
'"req": "$request",'
'"size": "$body_bytes_sent",'
'"reqtime": "$request_time",'
'"apptime": "$upstream_response_time",'
'"user_agent": "$http_user_agent",'
'"forwardedfor": "$http_x_forwarded_for",'
'"forwardedproto": "$http_x_forwarded_proto",'
'"referrer": "$http_referer"}';
access_log /var/log/nginx/access.log json;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
}
下面是创建otel-nginx.toml文件的otel_ngx_module.so配置文件的步骤。这个配置文件可以设置数据协作和在屏幕上显示时的资源名称以及跟踪采样率。
exporter = "otlp"
processor = "batch"
[exporters.otlp]
# Alternatively the OTEL_EXPORTER_OTLP_ENDPOINT environment variable can also be used.
# OpenTelemetry Collectorを指定する
host = "otel-collector"
port = 4317
[processors.batch]
max_queue_size = 2048
schedule_delay_millis = 5000
max_export_batch_size = 512
[service]
# Opentelemetry resource name
name = "nginx-php-proxy"
[sampler]
name = "AlwaysOn" # Also: AlwaysOff, TraceIdRatioBased
ratio = 0.1
parent_based = false
将NGINX的Dockerfile配置更改,以便可以使用创建的配置文件。
# ビルドしたモジュールを実行環境へコピー
COPY --from=builder /usr/lib/nginx/modules/otel_ngx_module.so /usr/lib/nginx/modules/
+ # otel_ngx_module.soの設定ファイル所定の場所へコピー
+ COPY ./otel-nginx.toml /conf/otel-nginx.toml
# NGINXの設定ファイルを所定の場所へコピー
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
现在可以收集NGINX的遥测数据了。在启动Docker后,访问网站以创建数据。
docker-compose up --build
在New Relic平台上查看数据
启用分散追踪
我们将使用分散追踪来配置Nginx和PHP应用程序的连接。请在此文档中查看OpenTelemetry Nginx模块的配置选项。
opentelemetry_operation_name でトランザクション名を設定できます。
opentelemetry_propagate でW3C形式の TraceParent を後続のアプリケーションへ受け渡すことができるようになります。
设置去中心化溯源
在nginx的配置文件中添加OpenTelemetry nginx模块的两个配置项。这些配置需要在每个location中进行。
server {
index index.php index.html;
server_name localhost;
root /var/www/html;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
+ # W3C形式のTraceParentを後続のサービスへ引き継ぐ
+ opentelemetry_propagate;
+ # トランザクション名を設定
+ opentelemetry_operation_name $request_uri;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
我們將 Request URI 設置為交易名,在這樣做之後,交易名和分散追蹤的設定就完成了。接下來我們將重新啟動容器並進行操作確認。
docker-compose up --build
在New Relic上查看数据_分布式追踪
在New Relic上查看数据_服务地图
参考资料
概括
在本文中,详细解释了如何使用OpenTelemetry来收集nginx的遥测数据,并在New Relic中将这些数据可视化。具体而言,我们执行了以下步骤。
-
- 使用 OpenTelemetry nginx 模块进行安装和设置
-
- 使用 Docker Compose 构建验证环境
-
- 设置和配置 OpenTelemetry Collector
-
- 配置 NGINX 和 OpenTelemetry nginx 模块
-
- 设置和确认分布式追踪
- 在 New Relic 上确认数据
使用这个步骤,我们能够有效收集nginx的遥测数据并在New Relic中实现可视化。特别是通过启用分布式追踪,我们能够清楚地了解应用程序之间的相关性和性能瓶颈。
收集和可视化遥测数据是维护系统健康并帮助及早发现和解决问题的重要工作。通过结合OpenTelemetry和New Relic,我们能够高效地执行这些任务。此外,New Relic的基础设施代理包含了nginx集成功能,我们可以从nginx的状态页面收集信息,并在New Relic平台上查看连接数等。
在本次讲解中,我们介绍了如何使用OpenTelemetry从前端到后端一体化地对nginx等进行仪表化。除此之外,只要是OpenTelemetry或Zipkin等所支持的Apache或Envoy等,也可以按照同样的方式进行仪表化。
关于如何将Envoy的追踪信息与New Relic集成的方法,请参阅这篇博客,希望能对您有所帮助。
如果您想尝试,请务必从此处获取和测试OpenTelemetry与New Relic的集成,即使您使用永久免费许可证也可以。请尽情试用永久免费许可证。
下一步
这篇文章介绍了如何利用OpenTelemetry收集nginx的遥测数据。但是由于该遥测数据主要关注追踪,因此没有提及与系统调查密不可分的日志。New Relic拥有一个强大的功能,称为Logs in context,可以将追踪和日志关联显示。关于如何将nginx的日志与追踪信息关联显示的方法,可以在另一篇文章中找到介绍。