Skip to content

Commit

Permalink
Add datadog tracing example (#97)
Browse files Browse the repository at this point in the history
Signed-off-by: Damien Mehala <damien.mehala@datadoghq.com>
  • Loading branch information
dmehala authored Aug 26, 2024
1 parent e8c2eea commit 1255d01
Show file tree
Hide file tree
Showing 10 changed files with 299 additions and 0 deletions.
3 changes: 3 additions & 0 deletions datadog-tracing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
To learn about this sandbox and for instructions on how to run it please head over
to the [envoy docs](https://www.envoyproxy.io/docs/envoy/latest/start/sandboxes/datadog_tracing)

Binary file added datadog-tracing/_static/datadog-ui-landing.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added datadog-tracing/_static/datadog-ui-map.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added datadog-tracing/_static/datadog-ui-trace.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 43 additions & 0 deletions datadog-tracing/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
services:
envoy:
build:
context: .
dockerfile: ../shared/envoy/Dockerfile
depends_on:
- dd-agent
- http
ports:
- "${PORT_PROXY:-10000}:1337"

# `agent` is the Datadog Agent to which traces are sent.
# `agent` needs an API key set in the environment as the
# `DD_API_KEY` environment variable.
dd-agent:
volumes:
- '/var/run/docker.sock:/var/run/docker.sock:ro'
- '/run/user:/run/user:ro'
- '/proc/:/host/proc/:ro'
- '/sys/fs/cgroup/:/host/sys/fs/cgroup:ro'
environment:
- DOCKER_HOST
- DD_API_KEY
- DD_SITE
- DD_APM_ENABLED=true
- DD_LOG_LEVEL=ERROR
ports:
- 8126:8126
image: 'datadog/agent@sha256:1d9b8e28704b207626cdeca5386019f673d9f3a9baf817f5094b8e08b1f99fca'

# `http` is an HTTP server that is reverse proxied by `nginx`.
http:
build:
context: .
dockerfile: ./http.dockerfile
environment:
- DD_ENV=prod
- DD_AGENT_HOST=dd-agent
- DD_SERVICE=envoy-demo-http
ports:
- 8080:8080
depends_on:
- dd-agent
87 changes: 87 additions & 0 deletions datadog-tracing/envoy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
static_resources:
listeners:
- address:
socket_address:
address: 0.0.0.0
port_value: 1337
traffic_direction: OUTBOUND
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
generate_request_id: true
tracing:
provider:
name: envoy.tracers.datadog
typed_config:
"@type": type.googleapis.com/envoy.config.trace.v3.DatadogConfig
collector_cluster: datadog_agent
service_name: envoy-demo
access_log:
- name: envoy.access_loggers.stdout
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
log_format:
text_format_source:
inline_string: "[%START_TIME%] \"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH):256% \
%PROTOCOL%\" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% \
%DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% \"%REQ(X-FORWARDED-FOR)%\" \
\"%REQ(USER-AGENT)%\" \"%REQ(X-REQUEST-ID)%\" \"%REQ(:AUTHORITY)%\" \"%UPSTREAM_HOST%\" \
\"%RESP(X-AMZN-RequestId)%\" \"%REQ(X-DATADOG-TRACE-ID)%\" \"%REQ(X-DATADOG-PARENT-ID)%\"\n"
codec_type: AUTO
stat_prefix: ingress_http
route_config:
request_headers_to_add:
- header:
key: X-Foobar-Banana
value: " "
name: local_route
virtual_hosts:
- name: backend
domains:
- "*"
routes:
- match:
prefix: "/"
route:
cluster: service1
http_filters:
- name: envoy.filters.http.health_check
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck
pass_through_mode: false
headers:
- exact_match: /healthcheck
name: :path
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
use_remote_address: true
clusters:
- name: service1
connect_timeout: 0.250s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: service1
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: http
port_value: 8080
- name: datadog_agent
connect_timeout: 1s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: datadog_agent
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: dd-agent
port_value: 8126
107 changes: 107 additions & 0 deletions datadog-tracing/example.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
.. _install_sandboxes_datadog:

Datadog tracing
===============

.. sidebar:: Requirements

.. include:: _include/docker-env-setup-link.rst

.. note:: Before proceeding, please ensure you have a Datadog account set up. If you don't already have one, you can `sign up for Datadog here <https://app.datadoghq.eu/signup>`_.

:ref:`curl <start_sandboxes_setup_curl>`
Used to make HTTP requests.

The Datadog tracing sandbox demonstrates Envoy's :ref:`request tracing <arch_overview_tracing>`
capabilities using `Datadog <https://datadoghq.com/>`_ as the tracing provider.

This example includes a Datadog Agent which will forward to Datadog's backend traces sent from Envoy and the upstream HTTP service.

The ``envoy`` service is exposed on port ``10000`` and the request flow is as follow:

User -> ``envoy`` -> ``http``

The Envoy proxy is configured (:download:`envoy.yaml <_include/datadog-tracing/envoy.yaml>`) to generate and propagate tracing context to upstream services and also to
report tracing data to the Datadog Agent through an Envoy cluster named ``datadog_agent``.

Each span records the latency of upstream API calls as well as information needed to correlate the span with other related spans (e.g., the trace ID).

Step 1: Build the sandbox
*************************

Change directory to ``examples/datadog-tracing`` in the Envoy repository.

To build this sandbox example, and start the example services run the following commands:

.. code-block:: console
$ pwd
envoy/examples/datadog-tracing
$ export DD_API_KEY=<YOUR_API_KEY>
$ docker compose pull
$ docker compose up --build -d
$ docker compose ps
Name Command State Ports
-----------------------------------------------------------------------------------------------------------
datadog-tracing-dd-agent-1 "/bin/entrypoint.sh" running 8125/udp, 0.0.0.0:8126->8126/tcp
datadog-tracing-envoy-1 "/docker-entrypoint.…" running 10000/tcp, 0.0.0.0:10000->1337/tcp
datadog-tracing-http-1 "node --require dd-t…" running 0.0.0.0:8080->8080/tcp
Step 2: Make a request to ``http``
**********************************

Now send a request to the HTTP service, by calling http://localhost:10000.

.. code-block:: console
$ curl localhost:10000
{
"service": "http",
"headers": {
"host": "localhost:10000",
"user-agent": "curl/7.81.0",
"accept": "*/*",
"x-forwarded-for": "172.16.14.142",
"x-forwarded-proto": "http",
"x-envoy-internal": "true",
"x-request-id": "cfa52b85-8660-9532-b347-bd484da76166",
"x-envoy-expected-rq-timeout-ms": "15000",
"x-foobar-banana": "",
"x-datadog-trace-id": "13944358220549386131",
"x-datadog-parent-id": "13944358220549386131",
"x-datadog-sampling-priority": "1",
"x-datadog-tags": "_dd.p.tid=663fe98600000000,_dd.p.dm=-0",
"traceparent": "00-663fe98600000000c1844febd4a4ef93-c1844febd4a4ef93-01",
"tracestate": "dd=s:1;t.dm:-0"
}
}
Step 3: View the traces in Datadog UI
*************************************

Log in your Datadog account and navigate to APM tracing page.

.. image:: /start/sandboxes/_include/datadog-tracing/_static/datadog-ui-landing.png

Click on any of the trace with the service name ``envoy``. From here you can explore the paths taken by the requests, as well as the latency incurred at each hop,
and other contextual information.

.. image:: /start/sandboxes/_include/datadog-tracing/_static/datadog-ui-trace.png

Note the Datadog tracer identifies the Envoy proxies by the name provided in the ``tracing.provider.typed_config.service_name`` configuration.

You can also explore the map graph to view relationships between nodes and the path of traces.

.. image:: /start/sandboxes/_include/datadog-tracing/_static/datadog-ui-map.png

.. seealso::

:ref:`Request tracing <arch_overview_tracing>`
Learn more about using Envoy's request tracing.

`Datadog <https://datadoghq.com/>`_
Datadog website.

`OpenTelemetry tracing <https://opentelemetry.io/>`_
OpenTelemetry tracing sandbox.
14 changes: 14 additions & 0 deletions datadog-tracing/http.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM alpine:3.16@sha256:e4cdb7d47b06ba0a062ad2a97a7d154967c8f83934594d9f2bd3efa89292996b

RUN mkdir /opt/app
WORKDIR /opt/app

# Note: WORKDIR must already be set (as it is above) before installing npm.
# If WORKDIR is not set, then npm is installed at the container root,
# which then causes `npm install` to fail later.
RUN apk update && apk add nodejs npm
RUN npm install dd-trace@v4

COPY ./http.js /opt/app/http.js

CMD ["node", "--require", "dd-trace/init", "http.js"]
33 changes: 33 additions & 0 deletions datadog-tracing/http.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// This is an HTTP server that listens on port 8080 and responds to all
// requests with some text, including the request headers as JSON.

const http = require('http');
const process = require('process');

// In order for the span(s) associated with an HTTP request to be considered
// finished, the body of the response corresponding to the request must have
// ended.
function ignoreRequestBody(request) {
function ignore() {}
request.on('data', ignore);
request.on('end', ignore);
}

function requestListener (request, response) {
ignoreRequestBody(request);
const responseBody = JSON.stringify({
"service": "http",
"headers": request.headers
}, null, 2);
console.log(responseBody);
response.end(responseBody);
}

console.log('http node.js web server is running');
const server = http.createServer(requestListener);
server.listen(8080);

process.on('SIGTERM', function () {
console.log('Received SIGTERM');
server.close(function () { process.exit(0); });
});
12 changes: 12 additions & 0 deletions datadog-tracing/verify.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash -e

export NAME=datadog-tracing
export PORT_PROXY="${DATADOG_PORT_PROXY:-10400}"

# shellcheck source=verify-common.sh
. "$(dirname "${BASH_SOURCE[0]}")/../verify-common.sh"

run_log "Make a request to http service"
responds_with_header \
"x-datadog-trace-id" \
"http://localhost:${PORT_PROXY}"

0 comments on commit 1255d01

Please sign in to comment.