CubeAPM
CubeAPM CubeAPM

SAP Application Performance Monitoring: Setup with OpenTelemetry

SAP Application Performance Monitoring: Setup with OpenTelemetry

Table of Contents

SAP applications generate enormous volumes of telemetry data across ABAP stacks, Java workloads, HANA databases, and cloud native services. According to the CNCF Annual Survey 2024, 67% of organizations now use OpenTelemetry to standardize observability across diverse application stacks, including legacy enterprise platforms like SAP.

Without structured APM, issues like slow RFC calls, memory leaks in custom ABAP code, or HANA query bottlenecks can degrade business processes for hours before teams notice. With OpenTelemetry based SAP monitoring, the same problems trigger contextual alerts, surface root causes, and give teams the exact transaction or service causing the slowdown.

This guide shows how to instrument SAP workloads with OpenTelemetry, configure collectors to export SAP telemetry, and visualize traces, metrics, and logs in a unified observability platform. The setup works for on premises SAP systems, SAP Cloud Platform, and hybrid deployments.

Prerequisites

Before starting this setup, ensure you have:

  • SAP system access with administrative privileges to modify JVM parameters (for Java-based SAP components) or ABAP transport requests (for custom instrumentation)
  • OpenTelemetry Collector binary or Docker image (version 0.90.0 or later recommended)
  • Network connectivity between SAP application servers and the OpenTelemetry Collector endpoint
  • Access to an observability backend (CubeAPM, SAP Cloud ALM, Grafana, or another OTLP-compatible platform)
  • Basic familiarity with SAP architecture, including application servers, HANA database layer, and SAP NetWeaver components
  • OAuth2 credentials if sending telemetry to SAP Cloud ALM or another OAuth-protected backend
  • At least 4 GB RAM and 2 CPU cores on the host running the OpenTelemetry Collector for production workloads

Step 1: Understand SAP Observability Signal Types

SAP environments generate three primary signal types that OpenTelemetry can capture and export: traces, metrics, and logs. Each serves a different diagnostic purpose.

Traces track request flows across SAP services, from user interactions in Fiori apps through ABAP function modules to HANA database queries. A trace shows latency at each hop, making it possible to pinpoint slow RFC calls, expensive SELECT statements, or bottlenecks in custom business logic. OpenTelemetry traces use the W3C Trace Context standard, meaning they propagate seamlessly across SAP and non-SAP services in hybrid architectures.

Metrics measure resource utilization and application health over time. For SAP, this includes ABAP work process utilization, HANA memory consumption, JVM heap usage, database connection pool saturation, and custom business metrics like order processing throughput. OpenTelemetry metrics support gauges, counters, and histograms, allowing teams to track both instantaneous values and rate of change.

Logs capture discrete events like user logins, ABAP short dumps, failed RFC connections, and HANA out of memory errors. OpenTelemetry structured logs correlate with traces via trace IDs, making it possible to view all logs generated during a specific transaction without manually searching log files.

SAP Cloud ALM and other SAP-native observability tools support OpenTelemetry signals via inbound raw APIs. For teams running self hosted observability platforms, OpenTelemetry’s OTLP (OpenTelemetry Protocol) export format ensures compatibility with infrastructure monitoring platforms that support OTLP receivers.

Step 2: Install and Configure the OpenTelemetry Collector

The OpenTelemetry Collector acts as a central proxy that receives telemetry from SAP components, processes it, and exports it to one or more observability backends. It runs as a standalone service, either on a dedicated host or as a sidecar container in Kubernetes deployments.

Download the OpenTelemetry Collector binary from the official GitHub releases page or use the Docker image. For production SAP environments, the Collector should run on a dedicated host with sufficient resources to handle peak telemetry volume. A mid-sized SAP system generating 10,000 spans per second typically requires 4 GB RAM and 2 CPU cores for the Collector.

Create a configuration file named otel-collector-config.yaml. This file defines three sections: receivers (how telemetry enters the Collector), processors (how telemetry is transformed or filtered), and exporters (where telemetry is sent).

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

processors:
  batch:
    timeout: 10s
    send_batch_size: 1024

exporters:
  otlp:
    endpoint: your-backend-endpoint:4317
    tls:
      insecure: false
    headers:
      authorization: Bearer ${env:OTEL_AUTH_TOKEN}

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp]
    metrics:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp]
    logs:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp]

The OTLP receiver listens on port 4317 for gRPC and 4318 for HTTP. SAP Java agents and custom ABAP instrumentation send telemetry to these endpoints. The batch processor groups signals before export, reducing network overhead. The OTLP exporter forwards all signals to your observability backend.

If exporting to SAP Cloud ALM, add an OAuth2 client credentials extension to authenticate API calls:

extensions:
  oauth2client:
    client_id: ${env:SAP_CLIENT_ID}
    client_secret: ${env:SAP_CLIENT_SECRET}
    token_url: https://your-alm-subdomain.authentication.sap.hana.ondemand.com/oauth/token
    scopes: ["alm.api.write"]

exporters:
  otlphttp:
    endpoint: https://your-alm-subdomain.alm.cloud.sap/api/v1/observe/otlp
    auth:
      authenticator: oauth2client

Store sensitive credentials like client secrets in environment variables, not directly in the config file. Start the Collector with:

export SAP_CLIENT_ID=your_client_id
export SAP_CLIENT_SECRET=your_client_secret
export OTEL_AUTH_TOKEN=your_backend_token
./otelcol-contrib --config=otel-collector-config.yaml

For Docker deployments, mount the config file and pass environment variables:

docker run -d \
  -v $(pwd)/otel-collector-config.yaml:/etc/otel/config.yaml \
  -p 4317:4317 -p 4318:4318 \
  -e SAP_CLIENT_ID=$SAP_CLIENT_ID \
  -e SAP_CLIENT_SECRET=$SAP_CLIENT_SECRET \
  otel/opentelemetry-collector-contrib:latest \
  --config=/etc/otel/config.yaml

Verify the Collector is running by checking the logs for startup messages and confirming the OTLP receivers are listening on the expected ports.

Step 3: Instrument SAP Java Applications

SAP NetWeaver Java stacks, SAP Cloud Platform applications, and custom Java services can be auto-instrumented using the OpenTelemetry Java agent. This agent attaches to the JVM at startup and automatically creates spans for common frameworks like servlets, JDBC, HTTP clients, and JMS without code changes.

Download the OpenTelemetry Java agent JAR from the official releases. Place it in a directory accessible by the SAP application server, such as /usr/sap/shared/otel/.

Modify the JVM startup parameters to attach the agent. For SAP NetWeaver, this is done via the Config Tool or by editing the instance profile. Add the -javaagent parameter and environment variables to configure the agent:

-javaagent:/usr/sap/shared/otel/opentelemetry-javaagent.jar
-Dotel.service.name=SAP-J2EE-Engine
-Dotel.exporter.otlp.protocol=grpc
-Dotel.exporter.otlp.endpoint=http://otel-collector-host:4317
-Dotel.traces.exporter=otlp
-Dotel.metrics.exporter=otlp
-Dotel.logs.exporter=otlp
-Dotel.resource.attributes=deployment.environment=production,sap.system.id=PRD

The otel.service.name identifies this service in traces. The otel.exporter.otlp.endpoint points to the Collector configured in Step 2. The otel.resource.attributes adds custom tags to all telemetry, making it easier to filter by SAP system ID or environment.

For Tomcat-based SAP applications like SAP Cloud Platform Java apps, add the agent configuration to the CATALINA_OPTS environment variable in setenv.sh:

export CATALINA_OPTS="$CATALINA_OPTS \
  -javaagent:/opt/otel/opentelemetry-javaagent.jar \
  -Dotel.service.name=SAP-Cloud-App \
  -Dotel.exporter.otlp.endpoint=http://otel-collector:4317 \
  -Dotel.resource.attributes=app.name=myapp,env=prod"

Restart the Java application server. The agent will begin capturing traces for HTTP requests, database queries, and remote procedure calls. Check the Collector logs to confirm spans are being received. A successful setup shows log entries like:

2026-01-15T10:30:42.123Z info TracesExporter {"kind": "exporter", "data_type": "traces", "name": "otlp", "spans": 127}

For SAP Java applications that make RFC calls to ABAP systems, the Java agent automatically propagates trace context via HTTP headers. To capture the ABAP side of the call, custom instrumentation is required.

Step 4: Add Custom Instrumentation to ABAP Code

ABAP applications require manual instrumentation because OpenTelemetry does not provide an auto-instrumentation agent for ABAP. The approach is to create reusable ABAP classes that wrap OpenTelemetry span creation and export logic, then call these classes at key points in business logic.

Create a global class ZCL_OTEL_TRACER in transaction SE24. This class should expose methods like START_SPAN, END_SPAN, and ADD_EVENT. Internally, it builds OTLP-formatted JSON and sends it to the Collector via HTTP POST using class CL_HTTP_CLIENT.

Here is a simplified example of starting a span in ABAP:

DATA: lv_trace_id TYPE string,
      lv_span_id TYPE string,
      lv_start_time TYPE timestamp.

lv_trace_id = zcl_otel_tracer=>generate_trace_id( ).
lv_span_id = zcl_otel_tracer=>generate_span_id( ).
GET TIME STAMP FIELD lv_start_time.

zcl_otel_tracer=>start_span(
  EXPORTING
    iv_trace_id = lv_trace_id
    iv_span_id = lv_span_id
    iv_span_name = 'PROCESS_SALES_ORDER'
    iv_start_time = lv_start_time
).

* Your business logic here
PERFORM process_sales_order.

zcl_otel_tracer=>end_span(
  EXPORTING
    iv_trace_id = lv_trace_id
    iv_span_id = lv_span_id
    iv_end_time = lv_start_time + 500 "milliseconds
).

The START_SPAN method constructs a JSON payload following the OTLP trace format and buffers it. The END_SPAN method calculates duration, finalizes the span, and sends it to the Collector endpoint via HTTP.

To correlate ABAP spans with incoming Java spans, extract the trace context from HTTP headers when an RFC or HTTP request enters the ABAP system. SAP Gateway and OData services expose headers via importing parameters, making trace context propagation straightforward.

For production use, consider creating a central instrumentation framework class that handles trace context propagation, span lifecycle, and error handling. This avoids duplicating instrumentation code across hundreds of function modules.

SAP NetWeaver versions 7.5 and later support CL_HTTP_CLIENT for outbound HTTP calls. For older systems, use RFC destination type HTTP or wrap instrumentation logic in a custom HTTP client.

Step 5: Configure SAP HANA Database Monitoring

SAP HANA exposes performance metrics through SQL system views and the HANA statistics server. OpenTelemetry can collect these metrics using the SQL Receiver in the OpenTelemetry Collector or via a custom exporter script.

Add the SQL Receiver to the Collector configuration:

receivers:
  sqlquery:
    driver: hdb
    datasource: "hdb://hanauser:password@hana-host:30015?encrypt=true"
    queries:
      - sql: "SELECT HOST, USED_PHYSICAL_MEMORY, FREE_PHYSICAL_MEMORY FROM M_HOST_RESOURCE_UTILIZATION"
        metrics:
          - metric_name: sap.hana.memory.used
            value_column: "USED_PHYSICAL_MEMORY"
            attribute_columns: ["HOST"]
            unit: bytes
            data_type: gauge

processors:
  batch:
    timeout: 10s

exporters:
  otlp:
    endpoint: your-backend:4317

service:
  pipelines:
    metrics:
      receivers: [sqlquery]
      processors: [batch]
      exporters: [otlp]

This configuration queries the HANA system view every collection interval and exports memory utilization as OpenTelemetry metrics. The attribute_columns field tags each metric with the HANA host name, enabling per-node analysis in dashboards.

Common HANA metrics to track include memory usage (M_HOST_RESOURCE_UTILIZATION), active SQL statements (M_SQL_PLAN_CACHE), blocked transactions (M_BLOCKED_TRANSACTIONS), and replication lag for HANA System Replication setups (M_SERVICE_REPLICATION).

For teams using PHP application monitoring tools, HANA query performance can be correlated with application layer traces by matching transaction IDs captured in both layers.

Step 6: Set Up Alerts and Dashboards

Once telemetry flows from SAP systems to your observability backend, create dashboards and alerts to detect performance degradation early.

For CubeAPM, create a dashboard that visualizes key SAP metrics:

  • ABAP work process utilization (alert if above 80% for 5 minutes)
  • HANA memory consumption (alert if free memory drops below 10%)
  • Average transaction response time (alert if p95 latency exceeds 2 seconds)
  • Error rate for critical business transactions (alert if error count > 10 in 1 minute)

Configure alerts to route to Slack, PagerDuty, or email based on severity. For example, a critical alert for HANA out of memory should page on-call engineers immediately, while a warning for high work process utilization might only send a Slack notification.

Trace-based alerts are particularly effective for SAP monitoring. Set an alert that fires when a specific ABAP transaction (e.g., VA01 for sales order creation) exceeds its baseline latency by 50%. This catches performance regressions before they affect business KPIs.

Dashboard layouts should separate infrastructure metrics (CPU, memory, disk) from application metrics (transaction counts, error rates, latency percentiles) and business metrics (orders processed per hour, failed payment transactions). This layered approach helps teams quickly isolate whether a problem is infrastructure, application logic, or business process related.

Step 7: Validate End to End Observability

After completing the setup, validate that traces, metrics, and logs are flowing correctly and that they correlate across SAP layers.

Trigger a test transaction that spans multiple SAP components. For example, create a sales order in SAP GUI, which triggers an ABAP function module, an RFC call to a Java service, and a SELECT query on HANA. In your observability platform, search for the trace by transaction ID or service name. You should see:

  • A root span representing the entire sales order creation
  • Child spans for each ABAP function module execution
  • A child span for the RFC call to the Java service
  • A child span for the HANA database query, showing query duration and rows returned

If any span is missing, check the Collector logs for export errors. Common issues include incorrect endpoint URLs, OAuth token expiration, or network firewall rules blocking OTLP traffic.

For log correlation, trigger an error condition in ABAP (e.g., a failed goods issue transaction) and verify that the ABAP short dump log entry includes the trace ID. This makes it possible to view all logs generated during a specific failed transaction without searching through gigabytes of log files.

Performance validation: measure the overhead introduced by OpenTelemetry instrumentation. In Java applications, the agent typically adds less than 5% latency and 2% CPU utilization. For ABAP, custom instrumentation overhead depends on how frequently spans are created. Instrumenting every function module adds measurable overhead, while instrumenting only critical business transactions keeps impact minimal.

Troubleshooting Common Issues

Spans not appearing in observability backend

Check that the OpenTelemetry Collector is running and the OTLP receiver is listening on the expected port. Use telnet or curl to verify connectivity:

telnet otel-collector-host 4317

If the connection fails, check firewall rules and network routing. Verify the Collector configuration file does not contain syntax errors by running the Collector with the --dry-run flag.

ABAP custom instrumentation not sending traces

Confirm that the ABAP HTTP client has network access to the Collector endpoint. Test the connection using transaction SM59 by creating an RFC destination of type HTTP and performing a connection test. If the test succeeds but traces are not appearing, check the JSON payload format. OTLP requires specific field names and timestamp formats, any deviation causes the Collector to reject the payload.

Java agent not capturing traces

Verify the -javaagent parameter was added correctly by checking the JVM startup logs. The agent prints initialization messages like:

[otel.javaagent 2026-01-15 10:30:00:123] OpenTelemetry Javaagent installed

If the message is missing, the agent did not load. Common causes include incorrect file path, insufficient file permissions, or JVM version incompatibility (the agent requires Java 8 or later).

High memory usage in OpenTelemetry Collector

The Collector buffers telemetry in memory before export. For high volume SAP systems generating 50,000+ spans per second, increase the batch processor size and reduce the timeout to prevent memory buildup:

processors:
  batch:
    timeout: 5s
    send_batch_size: 2048

Also consider adding a memory limiter processor to prevent out of memory crashes:

processors:
  memory_limiter:
    check_interval: 1s
    limit_mib: 4096

OAuth authentication failures with SAP Cloud ALM

Verify the OAuth2 client credentials are correct and the token URL is reachable. Test the token endpoint manually using curl:

curl -X POST https://your-subdomain.authentication.sap.hana.ondemand.com/oauth/token \
  -d "grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_SECRET"

If the test succeeds but the Collector still fails, check that the OAuth2 extension is listed in the service.extensions section of the Collector config.

Disclaimer: The information in this article reflects the latest details available at the time of publication and may change as technologies and products evolve. Features, pricing, and plan limits can change over time. Always verify the latest information directly with the vendor before making purchasing or deployment decisions.

Frequently Asked Questions

What is the difference between SAP Cloud ALM and OpenTelemetry for SAP monitoring?

SAP Cloud ALM is a managed observability platform built specifically for SAP environments, offering pre-built dashboards and health checks for SAP solutions. OpenTelemetry is an open standard for collecting and exporting telemetry data from any application, including SAP. Teams can use OpenTelemetry to send SAP telemetry to Cloud ALM or to alternative platforms like CubeAPM, Grafana, or Datadog.

Does OpenTelemetry support automatic instrumentation for ABAP?

No, OpenTelemetry does not provide an auto-instrumentation agent for ABAP. Teams must add custom instrumentation by creating ABAP classes that wrap OpenTelemetry span creation and HTTP export logic, then call these classes at key points in business logic.

Can I use OpenTelemetry to monitor SAP BTP applications?

Yes, SAP Business Technology Platform applications running on Cloud Foundry or Kyma can be instrumented with OpenTelemetry using language specific agents for Java, Node.js, Python, or Go. The agents export telemetry to the OpenTelemetry Collector, which forwards it to your observability backend.

How much overhead does OpenTelemetry add to SAP applications?

The Java agent typically adds less than 5% latency and 2% CPU utilization. ABAP custom instrumentation overhead depends on how frequently spans are created. Instrumenting only critical business transactions keeps performance impact minimal.

What is the best observability platform for self hosted SAP environments?

CubeAPM is designed for self hosted SAP observability, offering full stack monitoring for ABAP, Java, and HANA with unlimited retention and predictable pricing at $0.15/GB. It runs inside your own cloud or data center, ensuring SAP telemetry never leaves your infrastructure.

Can OpenTelemetry correlate SAP traces with non-SAP services?

Yes, OpenTelemetry uses W3C Trace Context propagation, which works across SAP and non-SAP services. A trace that starts in a React frontend can flow through an SAP Gateway OData service, into an ABAP function module, and then to a Python microservice, with all spans linked by a shared trace ID.

How do I monitor SAP HANA query performance with OpenTelemetry?

Use the SQL Receiver in the OpenTelemetry Collector to query HANA system views like M_SQL_PLAN_CACHE and M_EXPENSIVE_STATEMENTS. Export these metrics to your observability platform and create dashboards that show query duration, execution count, and resource consumption per SQL statement.

×
×