If you have an application that is monitored with AppDynamics Java, .NET, or Node.js Agents, you can instrument AppDynamics agents in your application to report both OpenTelemetry span data and Application Performance Monitoring (APM) data. When instrumented, the agents will generate OpenTelemetry span data from HTTP entry and exit requests. The AppDynamics correlation header is injected inside the OpenTelemetry baggage header, which results in the correlation with Business Transactions through intersecting OpenTelemetry nodes.

For example, the diagram above demonstrates how OpenTelemetry data is reported when an AppDynamics Java Agent is enabled for OpenTelemetry. The Java Agent sends APM data to the AppDynamics Controller and OpenTelemetry spans to the OpenTelemetry Collector. The Collector then sends the received spans to the AppDynamics OpenTelemetry Service via OTLP/HTTP(s). The AppDynamics OpenTelemetry Service consolidates the spans into traces and maps traces to Business Transactions that are registered with the Controller. The Controller UI displays both the APM data from the AppDynamics Agent and the OpenTelemetry data from the AppDynamics OpenTelemetry Service. 

Before You Begin

Make sure you have deployed and configured the OpenTelemetry™ Collector and configured the resource attributes.

Enable OpenTelemetry in the Java Agent 

To enable the Java Agent for OpenTelemetry, you need Java Agent version >= 21.11.4 (we recommend using Java Agent version >= 22.3.0). For a list of Java frameworks supported for OpenTelemetry, see Supported Java Agent Frameworks for OpenTelemetry.

Add the following system properties in your JVM system properties:

  1. Enable OpenTelemetry: 

    -Dappdynamics.opentelemetry.enabled=true
    CODE
  2. Set the traces exporter to OTLP (the OpenTelemetry-enabled Java Agent will send OpenTelemetry spans in the OTLP format):

    -Dotel.traces.exporter=otlp
    CODE
  3. Set the tier name (in service.name) and application name (in service.namespace) for the JVM: 

    If you do not set the tier name in service.name, the value defaults to the tier name originally registered by the .NET Agent (when the tier was first instrumented by AppDynamics).

    -Dotel.resource.attributes="service.name=myServiceName,service.namespace=myServiceNameSpace"
    CODE

    You also have the option to set tier and application names in your OpenTelemetry otel-config.yml file or in the OTEL_RESOURCE_ATTRIBUTES environment variable. See Set service.name and service.namespace to Your Application and Tier Names

(Optional) Configure the Collector Endpoint

By default, the collector endpoint points to http://localhost:4317 but can be optionally configured in property Dotel.exporter.otlp.traces.endpoint:

-Dotel.exporter.otlp.traces.endpoint=http://localhost:8080
CODE

(Optional) Configure the Batching Timing

The default exporter span batching schedule is 5000 milliseconds. The batching schedule can be configured with the OpenTelemetry environment variable OTEL_BSP_SCHEDULE_DELAY:

-Dotel.bsp.schedule.delay=90000
CODE

Java Instrumentation Sample

-Dotel.traces.exporter=otlp
-Dotel.resource.attributes="service.name=myServiceName,service.namespace=myServiceNameSpace"
-Dappdynamics.opentelemetry.enabled=true
-Dappdynamics.controller.hostName=sample-controller.e2e.appd-test.com
-Dappdynamics.controller.port=443
-Dappdynamics.agent.accountName=OTEL-account
-Dappdynamics.agent.accountAccessKey=3ea55405-61b2-43bb-a8e0-58aff761a028
-Dappdynamics.controller.ssl.enabled=true
-Dappdynamics.agent.applicationName=ecommerce_OT
-Dappdynamics.agent.uniqueHostId=ecommerce_OT_1
-Dappdynamics.agent.tierName=DownTier
-Dappdynamics.agent.nodeName=DownNode
-javaagent:/<Java Agent Jar Path>/javaagent.jar
CODE

Enable OpenTelemetry in the .NET Agent

To enable the .NET Agent for OpenTelemetry, you need:

Add the following environment variable in the process that executes your .NET application:

  1. Enable OpenTelemetry:

    APPDYNAMICS_OPENTELEMETRY_ENABLED=true
    CODE


  2. Set the trace exporter to OTLP (the OpenTelemetry-enabled .NET Agent will send OpenTelemetry spans in the OTLP format):

    OTEL_TRACES_EXPORTER=otlp
    CODE
  3. Set the tier name (in service.name) and application name (in service.namespace) for the application:

    If you do not set the tier name in service.name, the value defaults to the tier name originally registered by the .NET Agent (when the tier was first instrumented by AppDynamics).

    OTEL_RESOURCE_ATTRIBUTES=service.name=myServiceName,service.namespace=myServiceNameSpace
    CODE

    You also have the option to set tier and application names in your OpenTelemetry otel-config.yml file. See Set service.name and service.namespace to Your Application and Tier Names.

(Optional) Configure the Collector Endpoint

By default, the collector endpoint is set to http://localhost:4318 and sends metrics via HTTP using OTLP format. The .NET Agent for OpenTelemetry does not support sending metrics via gRPC.

The endpoint can be configured with the environment variable OTEL_EXPORTER_OTLP_ENDPOINT:

OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:8080
CODE

(Optional) Configure Batching timing

The default exporter span batching schedule is 5000 milliseconds. The batching schedule can be configured with the environment variable OTEL_BSP_SCHEDULE_DELAY:

OTEL_BSP_SCHEDULE_DELAY=90000
CODE

.NET Instrumentation Sample

...
APPDYNAMICS_OPENTELEMETRY_ENABLED=true
OTEL_TRACES_EXPORTER=otlp
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
OTEL_RESOURCE_ATTRIBUTES=service.name=myServiceName,service.namespace=myServiceNameSpace
...
CODE

Enable OpenTelemetry in the Node.js Agent 

To enable OpenTelemetry in the Node.js Agent, you need Node.js Agent version >= 22.3.0.

Add the following OpenTelemetry configurations in your Node.js application code:

  1. Enable OpenTelemetry in the require statement:

    For Node.js applications, OpenTelemetry AppName and TierName is derived from the AppName and TierName in the Node.js require statement. If your AppDynamics application/tier is named MY_APP/MY_TIER, your OpenTelemetry application/tier will be MY_APP_OTEL/MY_TIER_OTEL.

    require("appdynamics").profile(
    {
      ...   
      openTelemetry: {
        enabled: <True:False> // openTelemetry is enabled or disabled
      }
      ... 
    }
    )
    JS
  2. Allow additional logging of span data: 

    require("appdynamics").profile(
    {
      ...   
      openTelemetry: {
        debug: <True:False> // Additional logging, console dump of span data
        ... 
      }
      ...
    }
    )
    JS
  3. Add the OpenTelemetry Collector URL: 

    require("appdynamics").profile(
    {     
      ...
      openTelemetry: {      
    	collector: {
    		url: <url> <http://host:port/v1/traces> // The default value is http://localhost:55680/v1/traces     
    	}
      ... 
     }
    )
    JS

(Optional) Configure the Batching Timing

require("appdynamics").profile(
{
  ...   
  openTelemetry: {
    exporter: {
      maxQueueSize: size_in_byte  the maximum queue size. After the size is reached spans are dropped. The default value is 2048. 
      scheduledDelayMillis: time_in_ms the delay interval in milliseconds between two consecutive exports. The default value is 5000. 
	}
 	...
  }
}
)
JS


Node.js Instrumentation Sample

require("appdynamics").profile(
{
  ...
  openTelemetry: {
    enabled: <True:False> // OpenTelemetry enabled or disabled
    debug: <True:False> // Additional logging, console dump of span data  
    collector: {
       url: <url> <http://host:port/v1/traces> // The default value is http://localhost:55680/v1/traces
     }
  }
  ... 
}
)
JS

Next Steps

Once you have instrumented your applications with AppDynamics for OpenTelemetry, you can view OpenTelemetry data in the Controller.

OpenTelemetry™ is a trademark of The Linux Foundation®.