How to instrument Apache web server with OTEL sdk?

How to instrument Apache web server with OTEL sdk?


Instrumenting Apache HTTP Server with OpenTelemetry C Agent

Overview

This article walks through instrumenting an existing Apache HTTP Server installation with the OpenTelemetry Webserver SDK (C agent). Once instrumented, Apache automatically generates distributed traces for every HTTP request and exports them via OTLP (gRPC).

Prerequisites

  • Apache HTTP Server installed and running (apache2
  • sudo / root access 
  • Internet access (to download the SDK) 

Step 1: Download the OpenTelemetry Webserver SDK

cd /tmp

wget https://github.com/open-telemetry/opentelemetry-cpp-contrib/releases/download/webserver%2Fv1.0.3/opentelemetry-webserver-sdk-x64-linux.tgz

Note: Check for the latest release at:
https://github.com/open-telemetry/opentelemetry-cpp-contrib/releases

Step 2: Install the SDK

sudo mkdir -p /opt/opentelemetry-webserver-sdk

sudo tar -xzf /tmp/opentelemetry-webserver-sdk-x64-linux.tgz \

   -C /opt/opentelemetry-webserver-sdk \

   --strip-components=1

Verify the key files are present:

ls /opt/opentelemetry-webserver-sdk/sdk_lib/lib/libopentelemetry_webserver_sdk.so

ls /opt/opentelemetry-webserver-sdk/WebServerModule/Apache/libmod_apache_otel.so

Step 3: Configure the Apache LD_LIBRARY_PATH

Apache needs to find the SDK shared libraries at startup. Add the library paths to /etc/apache2/envvars:

sudo tee -a /etc/apache2/envvars <<'EOF'


# OpenTelemetry Webserver SDK library paths

export LD_LIBRARY_PATH=/opt/opentelemetry-webserver-sdk/sdk_lib/lib:/opt/opentelemetry-webserver-sdk/WebServerModule/Apache:$LD_LIBRARY_PATH

EOF

Step 4: Create the Apache OTel Module Configuration

Create a new config file for the OTel module:

sudo tee /etc/apache2/conf-available/opentelemetry_module.conf <<'EOF'

# Load SDK shared libraries (order matters)

LoadFile /opt/opentelemetry-webserver-sdk/sdk_lib/lib/libopentelemetry_common.so

LoadFile /opt/opentelemetry-webserver-sdk/sdk_lib/lib/libopentelemetry_resources.so

LoadFile /opt/opentelemetry-webserver-sdk/sdk_lib/lib/libopentelemetry_trace.so

LoadFile /opt/opentelemetry-webserver-sdk/sdk_lib/lib/libopentelemetry_otlp_recordable.so

LoadFile /opt/opentelemetry-webserver-sdk/sdk_lib/lib/libopentelemetry_exporter_otlp_grpc.so

LoadFile /opt/opentelemetry-webserver-sdk/sdk_lib/lib/libopentelemetry_exporter_ostream_span.so


# Load the webserver SDK itself

LoadFile /opt/opentelemetry-webserver-sdk/sdk_lib/lib/libopentelemetry_webserver_sdk.so


# Load Apache OTel module

LoadModule otel_apache_module /opt/opentelemetry-webserver-sdk/WebServerModule/Apache/libmod_apache_otel.so


# OTel settings

ApacheModuleEnabled                  ON

ApacheModuleOtelSpanExporter         otlp

ApacheModuleOtelExporterEndpoint     http://localhost:4320

ApacheModuleOtelSpanProcessor        batch

ApacheModuleOtelSampler              AlwaysOn


# Service identity (customize these for your environment)

ApacheModuleServiceName              "MyApp-Apache"

ApacheModuleServiceNamespace         "Production"

ApacheModuleServiceInstanceId        "apache-node-1"


# Span naming: use first 2 URI segments

ApacheModuleSegmentType              FIRST

ApacheModuleSegmentParameter         2

EOF

Key points:

• ApacheModuleOtelExporterEndpoint points to the local OTel proxy (port 4320), not directly to the AppManager collector. See Configuring AppManager OTel Collector for details.

• The module exported symbol is otel_apache_module (not opentelemetry_module).

• LoadFile directives must appear in order before LoadModule.

Step 5: Enable the Configuration

sudo a2enconf opentelemetry_module

Step 6: Test the Apache Configuration

sudo apache2ctl configtest

Expected output: Syntax OK

Step 7: Restart Apache

sudo systemctl restart apache2

Step 8: Verify the Module is Loaded

sudo apache2ctl -M | grep otel

Expected output:

otel_apache_module (shared)

Step 9: Verify Traces are Being Generated

Send a few test requests:

curl http://localhost/

curl http://localhost/some-page/

Then check the OTel proxy logs (see Configuring AppManager OTel Collector) — you should see span data with http.methodhttp.target, and http.status_code attributes.

Troubleshooting

Apache fails to start after adding the module

Check the error log:

sudo journalctl -u apache2 --no-pager -n 30

sudo tail -30 /var/log/apache2/error.log

Error

Fix

cannot open shared object file: libopentelemetry_common.so

LD_LIBRARY_PATH not set — check /etc/apache2/envvars

undefined symbol: opentelemetry_module

Wrong module name — use otel_apache_module in LoadModule

LoadFile: file not found

Verify SDK was extracted to /opt/opentelemetry-webserver-sdk/

Confirm the SDK file locations

# Should be a file, not a directory

ls -la /opt/opentelemetry-webserver-sdk/sdk_lib/lib/libopentelemetry_webserver_sdk.so


# Verify exported module symbol

nm -D /opt/opentelemetry-webserver-sdk/WebServerModule/Apache/libmod_apache_otel.so | grep module

File Reference

File

Purpose

/opt/opentelemetry-webserver-sdk/

SDK installation directory

/etc/apache2/conf-available/opentelemetry_module.conf

Apache OTel module config

/etc/apache2/conf-enabled/opentelemetry_module.conf

Symlink created by a2enconf

/etc/apache2/envvars

LD_LIBRARY_PATH addition

Next Step

Once Apache is instrumented, follow Configuring AppManager OTel Collector for Apache Traces to set up the collector and proxy that receive and forward the traces to ManageEngine APM.