Monitor your self-hosted NGINX servers with OpenTelemetry using either the NRDOT collector (recommended) or OpenTelemetry Collector Contrib to send performance metrics and telemetry data to New Relic.
Before you begin
Ensure you have:
- Valid New Relic license key
- NGINX with the HTTP stub status module enabled
- One of the following collectors installed on a Linux host:
- Network access from the Linux host to:
- NGINX HTTP stub status endpoint
- New Relic's OTLP endpoint
Set up NGINX monitoring
Choose your preferred collector and follow the steps:
You can use the NRDOT collector to monitor your NGINX server. The NRDOT collector is a pre-configured distribution that includes New Relic-specific components.
To install & configure the NRDOT collector, follow these steps:
Dica
If any verification step fails, install the missing components before continuing. Need help installing the NRDOT collector? Check the installation section of the nrdot-collector-releases repository.
During installation use export collector_distro="nrdot-collector"
Configure the NRDOT collector to scrape metrics from your NGINX stub status endpoint and send them to New Relic.
Importante
Choose your monitoring approach:
- NGINX-only monitoring (this guide): Monitors just your NGINX web server performance and metrics
- Complete server monitoring: Monitors NGINX plus your entire server (CPU usage, memory, disk space, system logs)
If you want to monitor your whole server, not just NGINX, use the NRDOT collector's default configuration instead and add the NGINX receiver configuration to it.
Create the configuration file /etc/nrdot-collector/nginx-config.yaml:
receivers: nginx: endpoint: <YOUR_STUB_STATUS_ENDPOINT> # Replace with your stub status URL collection_interval: 30s # How often to collect metrics metrics: nginx.requests: enabled: true nginx.connections_accepted: enabled: true nginx.connections_handled: enabled: true nginx.connections_current: enabled: true
processors: # Detect system information resourcedetection: detectors: [system] system: resource_attributes: host.name: enabled: false host.id: enabled: true
# Add NGINX-specific identification resource/nginx: attributes: - key: nginx.server.endpoint value: "<YOUR_STUB_STATUS_ENDPOINT>" # Replace with your endpoint action: upsert - key: nginx.deployment.name value: "<DEPLOYMENT_NAME>" # Replace with your deployment name action: upsert # Batch metrics for efficient sending batch: timeout: 30s send_batch_size: 1024
# Transform metrics for better display in New Relic transform/nginx_metrics: metric_statements: - context: resource statements: # Customize the display name as needed for your New Relic dashboard - set(attributes["nginx.display.name"], Concat(["server", attributes["nginx.deployment.name"]], ":")) transform/metadata_nullify: metric_statements: - context: metric statements: - set(description, "") - set(unit, "")
exporters: otlp_http: endpoint: ${env:YOUR_NEWRELIC_OTLP_ENDPOINT} headers: api-key: ${env:YOUR_NEW_RELIC_LICENSE_KEY}
service: pipelines: metrics/nginx: receivers: [nginx] processors: [resourcedetection, resource/nginx, batch, transform/nginx_metrics, transform/metadata_nullify] exporters: [otlp_http]Configuration parameters
The following table describes the key configuration parameters:
Parameter | Description |
|---|---|
| Replace with the NGINX stub status endpoint (for example |
| Replace with a unique deployment name for this NGINX server (for example |
| Interval in seconds to collect metrics. The default value is set to |
| Timeout in seconds to wait before sending batched metrics. The default value is set to |
| Number of metrics to batch before sending. The default value is set to |
Update the NRDOT collector configuration to use your NGINX config file and set the OTLP endpoint.
Determine your OTLP endpoint based on your New Relic region. See Configure endpoint, port, and protocol for the complete list of endpoints and supported ports for your region.
Importante
Your license key is already configured in /etc/nrdot-collector/nrdot-collector.conf during installation. You only need to update the config file path and OTLP endpoint.
Update the collector configuration file:
$export collector_distro="nrdot-collector"$export otlp_endpoint="<YOUR_NEWRELIC_OTLP_ENDPOINT>" # Replace with your region's endpoint$
$# Update the config file path to point to nginx-config.yaml$sudo sed -i 's|OTELCOL_OPTIONS="--config=/etc/nrdot-collector/config.yaml"|OTELCOL_OPTIONS="--config=/etc/nrdot-collector/nginx-config.yaml"|' /etc/${collector_distro}/${collector_distro}.conf$
$# Add the OTLP endpoint$echo "OTEL_EXPORTER_OTLP_ENDPOINT=${otlp_endpoint}" | sudo tee -a /etc/${collector_distro}/${collector_distro}.conf > /dev/nullIn addition to metrics, you can send NGINX access and error logs to New Relic for comprehensive monitoring and troubleshooting. These logs complement the core NGINX metrics and provide detailed request-level insights.
Dica
Skip this step if you only need basic NGINX metrics and don't require detailed request logs.
To configure NGINX to output JSON-formatted logs, add this to your NGINX configuration (
/etc/nginx/nginx.conf):http {# JSON log format for better parsinglog_format json_combined escape=json'{''"time":"$time_local",''"remote_addr":"$remote_addr",''"request":"$request",''"status":$status,''"bytes_sent":$body_bytes_sent,''"request_time":$request_time,''"referer":"$http_referer",''"user_agent":"$http_user_agent"''}';# Use the JSON format for access logsaccess_log /var/log/nginx/access.log json_combined;error_log /var/log/nginx/error.log warn;# Your existing configuration...}Reload NGINX to apply the changes:
bash$sudo nginx -t && sudo nginx -s reloadTo configure the collector for log forwarding, add these sections to your
/etc/nrdot-collector/nginx-config.yaml:receivers:# Your existing nginx receiver...nginx:# existing configuration...# Add log receiversfilelog/nginx_access:include:- /var/log/nginx/access.logfilelog/nginx_error:include:- /var/log/nginx/error.logprocessors:# Your existing processors...# Add log processortransform/nginx_access_logs:log_statements:- context: resourcestatements:- set(attributes["nginx.display.name"], Concat(["server", attributes["nginx.deployment.name"]], ":"))- set(attributes["logtype"], "nginx")transform/nginx_error_logs:log_statements:- context: resourcestatements:- set(attributes["nginx.display.name"], Concat(["server", attributes["nginx.deployment.name"]], ":"))- set(attributes["logtype"], "nginx-error")service:pipelines:# Your existing metrics pipeline...# Add log pipelineslogs/nginx-access:receivers: [filelog/nginx_access]processors: [resource/nginx, batch, transform/nginx_access_logs]exporters: [otlp_http]logs/nginx-error:receivers: [filelog/nginx_error]processors: [resource/nginx, batch, transform/nginx_error_logs]exporters: [otlp_http]Set permissions and apply configuration. Allow the collector to read NGINX log files:
bash$# Add collector user to adm group (has read access to logs)$sudo usermod -a -G adm nrdot-collector$$# Ensure log files are readable$sudo chmod 644 /var/log/nginx/access.log$sudo chmod 644 /var/log/nginx/error.log
Now that everything is configured, start the NRDOT collector and verify that data is flowing to New Relic.
Start the collector:
Apply the configuration changes:
bash$sudo systemctl daemon-reload$sudo systemctl restart nrdot-collector.serviceVerify the service is running:
bash$sudo systemctl status nrdot-collector.serviceExpected output:
Active: active (running)with no recent errors
Verify data collection:
Check startup logs:
bash$sudo journalctl -u nrdot-collector.service -n 20Generate test traffic (to create metrics):
bash$# Make a few requests to your NGINX server$curl http://localhost
Allow time for initial data to appear in New Relic, then access your NGINX dashboard to verify data collection.
Dica
If any verification step fails, install the missing components before continuing. Need help installing the collector? Check the OpenTelemetry Collector installation guide.
Configure the OpenTelemetry Collector to scrape metrics from your NGINX stub status endpoint and send them to New Relic.
Importante
Before editing: Back up your existing configuration: sudo cp /etc/otelcol-contrib/config.yaml /etc/otelcol-contrib/config.yaml.backup
Edit your collector configuration file (typically /etc/otelcol-contrib/config.yaml) and add the following sections. If you already have receivers, processors, or exporters sections, merge these with your existing configuration:
Configure the NGINX receiver:
receivers:nginx:endpoint: <YOUR_STUB_STATUS_ENDPOINT> # Replace with your stub status URLcollection_interval: 30s # How often to collect metricsmetrics:nginx.requests:enabled: truenginx.connections_accepted:enabled: truenginx.connections_handled:enabled: truenginx.connections_current:enabled: trueConfigure processors for metadata and batching:
processors:# Detect system informationresourcedetection:detectors: [system]system:resource_attributes:host.name:enabled: falsehost.id:enabled: true# Add NGINX-specific identificationresource/nginx:attributes:- key: nginx.server.endpointvalue: "<YOUR_STUB_STATUS_ENDPOINT>" # Replace with your endpointaction: upsert- key: nginx.deployment.namevalue: "<DEPLOYMENT_NAME>" # Replace with your deployment nameaction: upsert# Batch metrics for efficient sendingbatch:timeout: 30ssend_batch_size: 1024# Transform metrics for better display in New Relictransform/nginx_metrics:metric_statements:- context: resourcestatements:# Customize the display name as needed for your New Relic dashboard- set(attributes["nginx.display.name"], Concat(["server", attributes["nginx.deployment.name"]], ":"))transform/metadata_nullify:metric_statements:- context: metricstatements:- set(description, "")- set(unit, "")Configure the New Relic exporter:
exporters:# Send metrics to New Relic via OTLPotlp_http:endpoint: ${env:YOUR_NEWRELIC_OTLP_ENDPOINT}headers:api-key: ${env:YOUR_NEW_RELIC_LICENSE_KEY}Connect everything with a pipeline:
service:pipelines:metrics/nginx:receivers: [nginx]processors: [resourcedetection, resource/nginx, batch, transform/nginx_metrics, transform/metadata_nullify]exporters: [otlp_http]
Configuration parameters
The following table describes the key configuration parameters:
Parameter | Description |
|---|---|
| Replace with the NGINX stub status endpoint (for example |
| Replace with a unique deployment name for this NGINX server (for example |
| Interval in seconds to collect metrics. The default value is set to |
| Timeout in seconds to wait before sending batched metrics. The default value is set to |
| Number of metrics to batch before sending. The default value is set to |
Configure secure authentication so the OpenTelemetry Collector can send data to your New Relic account. This step sets up environment variables to keep your credentials secure.
Get your New Relic credentials:
- License Key: Get your license key from the API Keys UI page
- OTLP Endpoint: Use your region's endpoint from New Relic OTLP endpoints
Configure the credentials:
Create a systemd override directory:
bash$sudo mkdir -p /etc/systemd/system/otelcol-contrib.service.dCreate the environment configuration file:
bash$cat <<EOF | sudo tee /etc/systemd/system/otelcol-contrib.service.d/environment.conf$[Service]$Environment="NEWRELIC_OTLP_ENDPOINT=<YOUR_NEWRELIC_OTLP_ENDPOINT>" # Replace with your region's endpoint$Environment="NEWRELIC_LICENSE_KEY=YOUR_NEW_RELIC_LICENSE_KEY"$EOF
In addition to metrics, you can send NGINX access and error logs to New Relic for comprehensive monitoring and troubleshooting. These logs complement the core NGINX metrics and provide detailed request-level insights.
Dica
Skip this step if you only need basic NGINX metrics and don't require detailed request logs.
To configure NGINX to output JSON-formatted logs, add this to your NGINX configuration (
/etc/nginx/nginx.conf):http {# JSON log format for better parsinglog_format json_combined escape=json'{''"time":"$time_local",''"remote_addr":"$remote_addr",''"request":"$request",''"status":$status,''"bytes_sent":$body_bytes_sent,''"request_time":$request_time,''"referer":"$http_referer",''"user_agent":"$http_user_agent"''}';# Use the JSON format for access logsaccess_log /var/log/nginx/access.log json_combined;error_log /var/log/nginx/error.log warn;# Your existing configuration...}Reload NGINX to apply the changes:
bash$sudo nginx -t && sudo nginx -s reloadTo configure the collector for log forwarding, add these sections to your
/etc/otelcol-contrib/config.yaml:receivers:# Your existing nginx receiver...nginx:# existing configuration...# Add log receiversfilelog/nginx_access:include:- /var/log/nginx/access.logfilelog/nginx_error:include:- /var/log/nginx/error.logprocessors:# Your existing processors...# Add log processortransform/nginx_access_logs:log_statements:- context: resourcestatements:- set(attributes["nginx.display.name"], Concat(["server", attributes["nginx.deployment.name"]], ":"))- set(attributes["logtype"], "nginx")transform/nginx_error_logs:log_statements:- context: resourcestatements:- set(attributes["nginx.display.name"], Concat(["server", attributes["nginx.deployment.name"]], ":"))- set(attributes["logtype"], "nginx-error")service:pipelines:# Your existing metrics pipeline...# Add log pipelineslogs/nginx-access:receivers: [filelog/nginx_access]processors: [resource/nginx, batch, transform/nginx_access_logs]exporters: [otlp_http]logs/nginx-error:receivers: [filelog/nginx_error]processors: [resource/nginx, batch, transform/nginx_error_logs]exporters: [otlp_http]Set permissions and apply configuration. Allow the collector to read NGINX log files:
bash$# Add collector user to adm group (has read access to logs)$sudo usermod -a -G adm otelcol-contrib$$# Ensure log files are readable$sudo chmod 644 /var/log/nginx/access.log$sudo chmod 644 /var/log/nginx/error.log
Now that everything is configured, start the OpenTelemetry Collector and verify that data is flowing to New Relic.
Start the collector:
Apply the configuration changes:
bash$sudo systemctl daemon-reload$sudo systemctl restart otelcol-contrib.serviceVerify the service is running:
bash$sudo systemctl status otelcol-contrib.serviceExpected output:
Active: active (running)with no recent errors
Verify data collection:
Check startup logs:
bash$sudo journalctl -u otelcol-contrib.service -n 20Generate test traffic (to create metrics):
bash$# Make a few requests to your NGINX server$curl http://localhost
Allow time for initial data to appear in New Relic, then access your NGINX dashboard to verify data collection.
View your data in New Relic
Once your setup is complete and data is flowing, you can access your NGINX metrics in New Relic dashboards and create custom alerts.
For complete instructions on accessing dashboards, querying data with NRQL, and creating alerts, see Find and query your NGINX data.
Troubleshooting
If you encounter issues during setup, use this troubleshooting guide to diagnose and resolve common problems.
Getting 404 Not Found:
$curl http://<NGINX_SERVER_IP>:<YOUR_LOCAL_PORT>/nginx_statusSolutions:
- Check that the location path matches your request URL
- Verify the configuration was added to the correct server block
- Run
sudo nginx -T | grep -A5 nginx_statusto confirm configuration is loaded
Getting 403 Forbidden:
- Ensure you're testing from the correct server IP
<NGINX_SERVER_IP> - Check your
allow/denydirectives in the NGINX configuration - Verify no other access restrictions are blocking the request
Connection refused:
- Check if NGINX is running:
sudo systemctl status nginx - Verify your configured port isn't blocked:
sudo netstat -tlnp | grep :<YOUR_LOCAL_PORT> - Check firewall rules if applicable
Check service status:
$sudo systemctl status ${collector_distro}.service$sudo journalctl -u ${collector_distro}.service -n 50Common causes and fixes:
- YAML syntax errors - Fix indentation and syntax issues
- Missing environment variables - Verify credentials are set in environment file
- File permission issues - Run
sudo chown ${collector_distro}:${collector_distro} /etc/${collector_distro}/config.yaml - Invalid endpoint URLs - Check NGINX endpoint and New Relic OTLP endpoint
- Missing component configurations - Ensure all receivers, processors, and exporters referenced in the service pipelines section are actually defined in their respective configuration sections above
Restart after fixes:
$sudo systemctl restart ${collector_distro}.serviceStep-by-step diagnosis:
Verify NGINX stub status works:
bash$curl http://<NGINX_SERVER_IP>:<YOUR_LOCAL_PORT>/nginx_statusShould return connection statistics.
Check Collector is running and healthy:
bash$sudo systemctl status ${collector_distro}.service$sudo journalctl -u ${collector_distro} -n 20The logs will provide detailed context if there are any configuration or runtime issues with the OpenTelemetry Collector.
Check for data with NRQL:
FROM Metric SELECT * WHERE nginx.deployment.name LIKE '%production%' LIMIT 1
No logs appearing in New Relic:
$# Check Collector logs for file errors$sudo journalctl -u ${collector_distro} -f | grep -i "filelog\|error"Common issues:
- File permission errors - Add collector to adm group:
sudo usermod -a -G adm ${collector_distro} - Wrong file paths - Verify log file locations in your config
Next steps
Learn more about your data:
- Find and query your NGINX data - Access dashboards, create custom queries, and set up alerts
- NGINX OpenTelemetry metrics and attributes reference - Complete metrics reference with descriptions and examples
- NGINX OpenTelemetry overview - Understand collected metrics, attributes, and use cases
Explore related monitoring:
- Monitor NGINX Plus with OpenTelemetry - For commercial NGINX Plus deployments
- Monitor NGINX on Kubernetes - For containerized environments