-
Notifications
You must be signed in to change notification settings - Fork 3
feat(examples): add Docker Compose setup with trace correlation #30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
| # CLAUDE.md | ||
|
|
||
| This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. | ||
|
|
||
| ## Project Overview | ||
|
|
||
| This is a Docker Compose-based demonstration project for testing distributed tracing with Apache httpd-datadog module. The project consists of three main services: | ||
|
|
||
| - **apache**: Reverse proxy with Datadog tracing module, proxies requests to the HTTP service | ||
| - **httpjs**: Simple Node.js HTTP server with Datadog APM tracing | ||
| - **datadog**: Datadog Agent for collecting traces and logs | ||
|
|
||
| ## Architecture | ||
|
|
||
| ``` | ||
| Client → apache (port 8888) → httpjs (port 8080) → Datadog Agent (port 8126) | ||
| ``` | ||
|
|
||
| The Apache service loads the `mod_datadog.so` to enable APM tracing for proxy requests. The Node.js HTTP service uses the dd-trace library to instrument HTTP handlers. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| Before running any commands, ensure the Datadog API key is set. You can either: | ||
|
|
||
| **Option 1: Export environment variable** | ||
| ```bash | ||
| export DD_API_KEY=<your_api_key> | ||
| ``` | ||
|
|
||
| **Option 2: Use envchain (recommended for security)** | ||
| ```bash | ||
| # Store API key in keychain (run once) | ||
| envchain --set datadog DD_API_KEY | ||
|
|
||
| # Use envchain when running docker-compose commands | ||
| envchain datadog docker-compose up -d | ||
| ``` | ||
|
|
||
| The runtime environment must be linux/amd64 for the Datadog Apache module to work properly. | ||
|
|
||
| ## Common Commands | ||
|
|
||
| ### Start the application | ||
| ```bash | ||
| # With exported environment variable | ||
| docker-compose up -d | ||
|
|
||
| # Or with envchain | ||
| envchain datadog docker-compose up -d | ||
| ``` | ||
|
|
||
| ### Make a test request (generates traces) | ||
| ```bash | ||
| curl localhost:8888 | ||
| ``` | ||
|
|
||
| ### Load testing | ||
| ```bash | ||
| make stress | ||
| ``` | ||
| This uses vegeta to send 1000 req/s for 60 seconds to test the tracing under load. | ||
|
|
||
| ### View logs | ||
| ```bash | ||
| docker-compose logs -f [service_name] | ||
| ``` | ||
|
|
||
| ### Rebuild and restart services (required after config changes) | ||
| ```bash | ||
| # With exported environment variable | ||
| docker-compose down && docker-compose build && docker-compose up -d | ||
|
|
||
| # Or with envchain | ||
| envchain datadog docker-compose down && envchain datadog docker-compose build && envchain datadog docker-compose up -d | ||
| ``` | ||
|
|
||
| ### Stop and clean up | ||
| ```bash | ||
| docker-compose down | ||
| ``` | ||
|
|
||
| ## Service Details | ||
|
|
||
| ### apache (Port 8888) | ||
| - Uses httpd:2.4 base image with mod_datadog module | ||
| - Dynamically downloads latest mod_datadog module from GitHub releases | ||
| - Proxies all requests to the `api` service | ||
| - **Enhanced logging**: Includes Datadog trace and span IDs for correlation | ||
| - Log format: `dd.trace_id="%{datadog_trace_id}e" dd.span_id="%{datadog_span_id}e"` | ||
| - Exposes Apache server-status endpoint on port 81 for Datadog monitoring | ||
| - Configuration: `apache/httpd.conf` | ||
|
|
||
| ### httpjs (Port 8080) | ||
| - Simple Node.js HTTP server with Datadog APM tracing via dd-trace | ||
| - Returns JSON response with service name and request headers | ||
| - Uses Alpine Linux base image with Node.js and npm | ||
| - Automatically instruments HTTP requests with dd-trace/init | ||
| - Listens on port 8080 and handles SIGTERM gracefully | ||
|
|
||
| ### datadog | ||
| - Official Datadog Agent 7 image | ||
| - Configured for APM, logs, and metrics collection | ||
| - Connects to containers via Docker socket for autodiscovery | ||
|
|
||
| ## File Structure | ||
|
|
||
| - `docker-compose.yml`: Main orchestration configuration | ||
| - `apache/`: Apache configuration and Dockerfile | ||
| - `httpjs/`: Node.js HTTP service with Dockerfile and http.js server | ||
| - `Makefile`: Contains stress testing command | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto |
||
| - `doc/`: Documentation and trace sample images | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| # httpd-datadog Examples | ||
|
|
||
| This directory contains a Docker Compose example demonstrating distributed tracing with the Apache httpd-datadog module. | ||
|
|
||
| ## Overview | ||
|
|
||
| The example consists of three services: | ||
|
|
||
| - **Apache HTTP Server** - Reverse proxy with mod_datadog module for tracing | ||
| - **Node.js HTTP Service** - Simple HTTP server with dd-trace instrumentation | ||
| - **Datadog Agent** - Collects and forwards traces to Datadog | ||
|
|
||
| ## Architecture | ||
|
|
||
| ``` | ||
| Client → Apache (port 8888) → Node.js (port 8080) → Datadog Agent (port 8126) | ||
| ``` | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| Set your Datadog API key: | ||
| ```bash | ||
| export DD_API_KEY=<your_api_key> | ||
| ``` | ||
|
|
||
| ## Quick Start | ||
|
|
||
| 1. Build and start services: | ||
| ```bash | ||
| docker-compose up -d | ||
| ``` | ||
|
|
||
| 2. Test the setup: | ||
| ```bash | ||
| curl localhost:8888 | ||
| ``` | ||
|
|
||
| 3. View logs: | ||
| ```bash | ||
| docker-compose logs -f | ||
| ``` | ||
|
|
||
| 4. Stop services: | ||
| ```bash | ||
| docker-compose down | ||
| ``` | ||
|
|
||
| ## What You'll See | ||
|
|
||
| The Node.js service returns a JSON response showing the request headers, including Datadog tracing headers added by the Apache module: | ||
|
|
||
|  | ||
|
|
||
| The above screenshot shows the distributed trace in Datadog's APM interface, demonstrating how requests flow from Apache through to the Node.js service with full trace correlation. | ||
|
|
||
| ```json | ||
| { | ||
| "service": "http", | ||
| "headers": { | ||
| "x-datadog-trace-id": "...", | ||
| "x-datadog-parent-id": "...", | ||
| "traceparent": "...", | ||
| "tracestate": "..." | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| These headers demonstrate that distributed tracing is working correctly across the Apache proxy and Node.js backend. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| FROM debian:stable-slim | ||
|
|
||
| # Install dependencies (only baseline system tools) | ||
| RUN apt-get update && \ | ||
| apt-get install -y apache2 curl unzip && \ | ||
| apt-get clean && \ | ||
| rm -rf /var/lib/apt/lists/* | ||
|
|
||
| # Enable required Apache modules | ||
| RUN a2enmod rewrite proxy proxy_http | ||
|
|
||
| # Download and install mod_datadog directly | ||
| RUN cd /tmp && \ | ||
| # Get latest release info using curl and basic text processing | ||
| RELEASE_DATA=$(curl -s https://api.github.com/repos/DataDog/httpd-datadog/releases/latest) && \ | ||
| # Extract download URL for the zip file using grep and cut | ||
| DOWNLOAD_URL=$(echo "$RELEASE_DATA" | grep -o '"browser_download_url": *"[^"]*mod_datadog_artifact.zip"' | cut -d '"' -f 4) && \ | ||
| # Download and install | ||
| curl -Lf -o mod_datadog_artifact.zip "$DOWNLOAD_URL" && \ | ||
| unzip -j mod_datadog_artifact.zip -d /usr/lib/apache2/modules/ && \ | ||
| rm mod_datadog_artifact.zip | ||
|
|
||
| # Enable datadog module | ||
| RUN echo "LoadModule datadog_module /usr/lib/apache2/modules/mod_datadog.so" > /etc/apache2/mods-available/datadog.load && \ | ||
| a2enmod datadog | ||
|
|
||
| # Copy Apache configuration | ||
| COPY apache-config.conf /etc/apache2/sites-available/000-default.conf | ||
|
|
||
| # Update ports configuration to listen on 8888 and 81 | ||
| RUN sed -i 's/Listen 80/Listen 8888\nListen 81/' /etc/apache2/ports.conf | ||
|
|
||
| # Create app directory | ||
| RUN mkdir -p /app | ||
|
|
||
| # Create startup script | ||
| RUN echo '#!/bin/bash\napachectl -D FOREGROUND' > /app/start.sh && \ | ||
| chmod +x /app/start.sh | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| EXPOSE 8888 81 | ||
|
|
||
| CMD ["./start.sh"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| <VirtualHost *:8888> | ||
| ServerName localhost | ||
|
|
||
| # Proxy configuration to the Node.js HTTP service | ||
| ProxyPreserveHost On | ||
| ProxyPass /healthcheck ! | ||
| ProxyPass / http://httpjs:8080/ | ||
| ProxyPassReverse / http://httpjs:8080/ | ||
|
|
||
| # Create healthcheck endpoint | ||
| Alias /healthcheck /app/healthcheck.json | ||
|
|
||
| # Log configuration with Datadog trace correlation | ||
| LogFormat "%h %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\" \"%{X-Forwarded-For}i\" dd.trace_id=\"%{Datadog-Trace-ID}e\" dd.span_id=\"%{Datadog-Span-ID}e\"" datadog_combined | ||
| CustomLog /proc/self/fd/1 datadog_combined | ||
| ErrorLog /proc/self/fd/2 | ||
|
|
||
| # MIME types | ||
| AddType text/html .html | ||
| AddType text/plain .txt .log .conf | ||
| AddType application/json .json | ||
|
|
||
| ErrorDocument 404 "Not Found" | ||
| </VirtualHost> | ||
|
|
||
| # Extended status for more metrics (must be outside VirtualHost) | ||
| ExtendedStatus On | ||
|
|
||
| # Additional VirtualHost for Apache status monitoring (port 81) | ||
| <VirtualHost *:81> | ||
| ServerName _ | ||
|
|
||
| <Location "/server-status"> | ||
| SetHandler server-status | ||
| Require all granted | ||
| </Location> | ||
| </VirtualHost> |
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| # Load mod_datadog module for enabling Datadog APM Traces for proxy | ||
| LoadModule datadog_module modules/mod_datadog.so | ||
|
|
||
| # Basic Apache configuration | ||
| ServerRoot "/usr/local/apache2" | ||
| Listen 80 | ||
| Listen 81 | ||
|
|
||
| # Modules | ||
| LoadModule mpm_event_module modules/mod_mpm_event.so | ||
| LoadModule authz_core_module modules/mod_authz_core.so | ||
| LoadModule dir_module modules/mod_dir.so | ||
| LoadModule mime_module modules/mod_mime.so | ||
| LoadModule rewrite_module modules/mod_rewrite.so | ||
| LoadModule proxy_module modules/mod_proxy.so | ||
| LoadModule proxy_http_module modules/mod_proxy_http.so | ||
| LoadModule status_module modules/mod_status.so | ||
| LoadModule log_config_module modules/mod_log_config.so | ||
| LoadModule setenvif_module modules/mod_setenvif.so | ||
|
|
||
| # Basic settings | ||
| ServerName localhost:80 | ||
| DirectoryIndex index.html | ||
|
|
||
| # MIME types | ||
| TypesConfig conf/mime.types | ||
|
|
||
| # Log configuration with Datadog trace correlation | ||
| # ref. https://docs.datadoghq.com/integrations/apache/?tab=host#log-collection | ||
| LogFormat "%h %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\" \"%{X-Forwarded-For}i\" dd.trace_id=\"%{datadog_trace_id}e\" dd.span_id=\"%{datadog_span_id}e\"" datadog_combined | ||
|
|
||
| # Keep original format as backup | ||
| LogFormat "%h %l %u %t \"%r\" %>s %b %D \"%{Referer}i\" \"%{User-Agent}i\" \"%{X-Forwarded-For}i\"" combined | ||
|
|
||
| CustomLog "logs/access_log" datadog_combined | ||
| ErrorLog "logs/error_log" | ||
| LogLevel warn | ||
|
|
||
| # Security | ||
| <Directory /> | ||
| AllowOverride none | ||
| Require all denied | ||
| </Directory> | ||
|
|
||
| # Document root | ||
| DocumentRoot "/usr/local/apache2/htdocs" | ||
| <Directory "/usr/local/apache2/htdocs"> | ||
| AllowOverride None | ||
| Require all granted | ||
| </Directory> | ||
|
|
||
| # Main server - reverse proxy to API | ||
| <VirtualHost *:80> | ||
| ServerName localhost | ||
|
|
||
| # Enable proxy | ||
| ProxyPreserveHost On | ||
| ProxyPass / http://api:8080/ | ||
| ProxyPassReverse / http://api:8080/ | ||
|
|
||
| # Add headers for tracing | ||
| ProxyPassReverse / http://api:8080/ | ||
| ProxyPreserveHost On | ||
| </VirtualHost> | ||
|
|
||
| # Extended status for more metrics | ||
| ExtendedStatus On | ||
|
|
||
| # Status server for Datadog monitoring | ||
| <VirtualHost *:81> | ||
| ServerName _ | ||
|
|
||
| # Disable access logging for status endpoint | ||
| CustomLog "logs/access_log" combined env=!dontlog | ||
| SetEnvIf Request_URI "^/server-status" dontlog | ||
|
|
||
| <Location "/server-status"> | ||
| SetHandler server-status | ||
| Require all granted | ||
| </Location> | ||
| </VirtualHost> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see any Makefile. I would suggest to remove this section