New announcements from Dash: Incident Management, Continuous Profiler, and more! New announcements from Dash!


Support for Datadog APM is available for NGINX using a combination of plugins and configurations. The instructions below use NGINX from the official Linux repositories and pre-built binaries for the plugins.

NGINX Open Source

Plugin Installation

Note: this plugin does not work on Linux distributions that use older versions of libstdc++. This includes RHEL/Centos 7 and AmazonLinux 1. A workaround for this is to run NGINX from a Docker container. An example Dockerfile is available here.

The following plugins must be installed:

Commands to download and install these modules:

# Gets the latest release version number from Github.
get_latest_release() {
  wget -qO- "$1/releases/latest" |
    grep '"tag_name":' |
    sed -E 's/.*"([^"]+)".*/\1/';
OPENTRACING_NGINX_VERSION="$(get_latest_release opentracing-contrib/nginx-opentracing)"
DD_OPENTRACING_CPP_VERSION="$(get_latest_release DataDog/dd-opentracing-cpp)"
# Install NGINX plugin for OpenTracing
tar zxf linux-amd64-nginx-${NGINX_VERSION} -C /usr/lib/nginx/modules
# Install Datadog Opentracing C++ Plugin
gunzip -c > /usr/local/lib/

NGINX Configuration

The NGINX configuration must load the OpenTracing module.

# Load OpenTracing module
load_module modules/;

The http block enables the OpenTracing module and loads the Datadog tracer:

    opentracing on; # Enable OpenTracing
    opentracing_tag http_user_agent $http_user_agent; # Add a tag to each trace!
    opentracing_trace_locations off; # Emit only one span per request.

    # Load the Datadog tracing implementation, and the given config file.
    opentracing_load_tracer /usr/local/lib/ /etc/nginx/dd-config.json;

The location block within the server where tracing is desired should add the following:

            opentracing_operation_name "$request_method $uri";

A config file for the Datadog tracing implementation is also required:

  "environment": "prod",
  "service": "nginx",
  "operation_name_override": "nginx.handle",
  "agent_host": "localhost",
  "agent_port": 8126

The service value can be modified to a meaningful value for your usage of NGINX. The agent_host value may need to be changed if NGINX is running in a container or orchestrated environment.

Complete examples:

After completing this configuration, HTTP requests to NGINX will initiate and propagate Datadog traces, and will appear in the APM UI.


When the location is serving a FastCGI backend instead of HTTP, the location block should use opentracing_fastcgi_propagate_context instead of opentracing_propagate_context.

NGINX Ingress Controller for Kubernetes

The Kubernetes ingress-nginx controller versions 0.23.0+ include the NGINX plugin for OpenTracing.

To enable this plugin, create or edit a ConfigMap to set enable-opentracing: "true" and the datadog-collector-host to which traces should be sent. The name of the ConfigMap will be cited explicitly by the nginx-ingress controller container’s command line argument, defaulting to --configmap=$(POD_NAMESPACE)/nginx-configuration. If ingress-nginx was installed via helm chart, this ConfigMap will be named like Release-Name-nginx-ingress-controller.

The ingress controller manages both the nginx.conf and /etc/nginx/opentracing.json files. Tracing is enabled for all location blocks.

kind: ConfigMap
apiVersion: v1
  name: nginx-configuration
  namespace: ingress-nginx
  labels: ingress-nginx ingress-nginx
  enable-opentracing: "true"
  datadog-collector-host: $HOST_IP
  # Defaults
  # datadog-service-name: "nginx"
  # datadog-collector-port: "8126"
  # datadog-operation-name-override: "nginx.handle"

Additionally, ensure that your nginx-ingress controller’s pod spec has the HOST_IP environment variable set. Add this entry to the env: block that contains the environment variables POD_NAME and POD_NAMESPACE.

- name: HOST_IP
      fieldPath: status.hostIP

To set a different service name per Ingress using annotations: |
      opentracing_tag "" "custom-service-name";

The above overrides the default nginx-ingress-controller.ingress-nginx service name.

Further Reading