Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions examples/CLAUDE.md
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.
Comment on lines +57 to +61
Copy link
Copy Markdown
Contributor

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


### 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
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

- `doc/`: Documentation and trace sample images
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

68 changes: 68 additions & 0 deletions examples/README.md
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:

![Apache Tracing Example](img/apache-tracing-example.png)

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.
44 changes: 44 additions & 0 deletions examples/apache/Dockerfile
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"]
37 changes: 37 additions & 0 deletions examples/apache/apache-config.conf
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>
81 changes: 81 additions & 0 deletions examples/apache/httpd.conf
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this httpd.conf file used anywhere? I don't see it being copied into the image

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>
Loading