How to Setup Astra Traffic Observability for Nginx, ft: Nginx Not Present

Last updated: August 18, 2025

Overview

This guide describes how to configure Nginx with the OpenTelemetry (OTel) module to monitor HTTP traffic in cloud Virtual Machine environments (AWS, GCP, Azure, DigitalOcean, etc.).

It provides:

  • Step-by-step setup instructions to install Nginx and instrument it

  • Troubleshooting guidance for common operational issues

  • Verification tips to ensure data is flowing to Astra Traffic Collector

image.png

Illustration: High-level integration flow between Ingress Nginx and Astra Traffic Collector


Prerequisites

Before beginning, ensure you have:


Quick Installation

Step 1: Prepare working directory

mkdir ~/astra-obs && cd ~/astra-obs

Step 2: Create nginx.conf

Copy paste the following configuration template to nginx.conf file. After that, be sure to replace the following placeholder values with actual values in nginx.conf

variable

description

example value

sensorID

IntegrationID displayed during the creation of Nginx Integration

mySensorID

http.otel_exporter.endpoint

Public IP address of the machine where Astra Traffic Collector is listening on port 4317

localhost

load_module modules/ngx_http_js_module.so;
load_module modules/ngx_otel_module.so;

user nginx;
worker_processes auto;

pid /var/run/nginx.pid;
error_log /var/log/nginx/error.log;

events {
      worker_connections 1024;
      # multi_accept on;
}

http {
      # Basic Settings
      sendfile on;
      tcp_nopush on;
      types_hash_max_size 2048;

      include /etc/nginx/mime.types;
      default_type application/octet-stream;

      # SSL Settings
      ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
      ssl_prefer_server_ciphers on;

      # Logging Settings
      access_log /var/log/nginx/access.log;

      # Gzip Settings
      gzip on;

      # Virtual Host Configs
      include /etc/nginx/conf.d/*.conf;
      include /etc/nginx/sites-enabled/*;

      js_import ga_nginx_script.js;
      js_set $req_headers ga_nginx_script.req_headers_json;
      js_set $resp_headers ga_nginx_script.resp_headers_json;
      otel_exporter {
          endpoint  localhost:4317; # OTEL collector's gRPC endpoint

          interval    5s;
          batch_size  512;
          batch_count 4;
      }
          
      server {
          listen 19443 ssl;
          server_name nginx;
          ssl_certificate     /etc/nginx/server.crt;
          ssl_certificate_key /etc/nginx/server.key;

          location / {
            #...
            otel_trace on;
            otel_trace_context propagate;
            otel_span_attr sensor.version $nginx_version;

            #replace mySensorID with actual sensorID
            otel_span_attr sensor.id mySensorID;

            otel_span_attr http.host $host;
            otel_span_attr http.request.headers $req_headers;
            otel_span_attr http.response.headers $resp_headers;
            otel_span_attr http.request.body $request_body;
            
            #...
            #proxy_pass http://backend;
            #...
        }
      }
}

Step 3: Configure the reverse proxy if needed

Edit the nginx.conf to configure reverse proxy to serve backend requests

Click here to know how to configure HTTP reverse proxy

Click here to know how to configure HTTPS reverse proxy

Step 4: Create ga_nginx_script.js file with following content

This will he a helper javascript file to access request and response headers

function req_headers_json(r) {
     return JSON.stringify(r.headersIn);
}

function resp_headers_json(r) {
     return JSON.stringify(r.headersOut);
}

export default { req_headers_json, resp_headers_json };

Step 5: Create docker-compose.yaml file with following content

We control the start/stop of nginx server via a docker compose file

  • Replace /path/to/server.crt and /path/to/server.key with the absolute path to your certificate and key.

  • Replace ~/astra-obs/nginx.conf and ~/astra-obs/ga_nginx_script.js with absolute path to nginx.conf and ga_nginx_script.js respectively.

version: '3.7'

services:

 otel-collector:
   image: nginx:otel
   volumes:
     - /path/to/server.crt:/etc/nginx/server.crt
     - /path/to/server.key:/etc/nginx/server.key
     - ~/astra-obs/nginx.conf:/etc/nginx/nginx.conf
     - ~/astra-obs/ga_nginx_script.js:/etc/nginx/ga_nginx_script.js
   network_mode: host
   restart: always

Step 6: Start Nginx container

sudo docker compose up -d
sudo docker ps -a

Expect the following output when you exec:

CONTAINER ID   IMAGE        COMMAND                   CREATED              STATUS              NAMES
29f430a5ac1f   nginx:otel   "/docker-entrypoint.…"    About a minute ago   Up About a minute   nginx-lb-container


Troubleshooting

Unable to send trace from nginx to traffic collector

Symptoms

  • No entries in inventory/ inventory not getting updated

  • Following or similar error seen in nginx log

    [Error] File: /tmp/build/opentelemetry-cpp/exporters/otlp/src/otlp_grpc_exporter.cc:66 [OTLP TRACE GRPC Exporter] Export() failed with status_code: "UNAVAILABLE" error_message: "DNS resolution failed for ...

Cause

  • Nginx is unable to resolve traffic-collector address

Solution

  • If Address of the traffic collector given in nginx.conf is incorrect, locate the http block in nginx.conf file, find the otel_exporter {...} block, update IPAddressOfTrafficCollector as shown below

    otel_exporter {
      endpoint IPAddressOfTrafficCollector:4317
      ...
    }
  • IPAddressOfTrafficCollector should be the your publicIP of the Astra Traffic Collector server instance

  • Restart nginx by running nginx -s reload


FAQ (Frequently Asked Questions)

  1. Can I see what trace are sent from my environment?

    📄 Verifying Traces in Astra Traffic Collector

  2. How to get IP Address Of Traffic Collector in Non Kubernetes environment?

    As container network is the same network as host network, the IP of the container would be the same as the Virtual Machine IP.