Java
  • 18 Aug 2022
  • 6 Minutes to read

Java


Traceable’s Java tracing agent or Java agent is based on OpenTelemetery and enhances the Spans within a Trace with security-focused attributes. Traceable’s agent can capture all the traffic that flows through your Java application including request and response headers along with the body of the request and response. You can either attach the Java agent to your application statically or dynamically. Traceable's Java agent uses Zipkin exporter.


Before you begin

The following prerequisites are required for installing Traceable's Java agent:

  • The Java agent requires Java 8 or above. 
  • Traceable Platform Agent - Make sure that the Traceable platform agent's address is available to the applications being instrumented

Supported frameworks

Library/FrameworkVersions
Apache HttpAsyncClient4.1+
Apache HttpClient4.0+
gRPC1.6+
JAX-RS Client2.0+
Micronaut (basic support via Netty)1.0+
Netty4.0+
OkHttp3.0+
Servlet2.3+
Spark Web Framework2.3+
Spring Webflux5.0+
Vert.x3.0+
Struts2.3+

Setup

You can attach the Java agent using dynamic or static attach.

Static attach

Complete the following steps to attach or load Traceable’s Java agent and do a static attach. In the static attach deployment method the Java application is started along with a Java agent. You can choose one of the following three methods to statically attach the Java agent:

Download using curl

Download and untar the Java agent by entering the following command:

curl -OL https://downloads.traceable.ai/agent/java/latest/javaagent-latest.tgz
tar -xzf javaagent-latest.tgz

 Run your application JAR with the traceable-agent from the command line:

export=HT_CONFIG_FILE=/<path_to_config_file>/example-config.yaml; java -javaagent:/<path_to_java_agent>/javaagent.jar -jar app.jar

Download from Maven Central and attach using Gradle

If you want to attach the Traceable agent to the runtask of a Gradle project leveraging the Application Plugin, complete the following steps:

  1. Define a custom Gradle configuration for javaagent
  2. Declare the Traceable Java agent as a dependency using the custom configuration to download it from Maven Central
  3. Set the -javaagent flag as the first element of the jvmArgs list for the run task. Use the custom configuration you defined to dynamically retrieve the path of the Java agent JAR on your system.
  4. gradle run will now run your application with the Traceable Java agent attached.
    ActionScript
    plugins {
        id 'application'
    }
    
    repositories {
        mavenCentral()
    }
    
    configurations {
        traceableAgent.extendsFrom runtimeOnly
    }
    
    dependencies {
        traceableAgent("ai.traceable.agent:javaagent:$traceableVersion")
    }
    
    application {
        // Define the main class for the application.
        mainClassName = 'com.example.Main'
    }
    
    run {
        jvmArgs = [
                "-javaagent:${configurations.traceableAgent.asPath}"
        ]
    }

Download from Maven Central and attach using Maven

If you want to attach the Traceable agent to the exec task of a Maven project leveraging the Exec Maven Plugin, complete the following steps:

  1. Use the Maven Dependency Plugin to download the agent from Maven Central and copy it to your projects build directory
  2. Add an <argument> to the Exec Maven Plugin configuration to set the -javaagent flag
  3. mvn compile exec:execwill now run your application with the Traceable Java agent attached
    ActionScript
    <build>
        <plugins>
          <plugin>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>3.1.2</version>
            <executions>
              <execution>
                <phase>compile</phase>
                <goals>
                  <goal>copy</goal>
                </goals>
                <configuration>
                  <artifactItems>
                    <artifactItem>
                      <groupId>ai.traceable</groupId>
                      <artifactId>javaagent</artifactId>
                      <version>${traceable.version}</version>
                      <classifier>all</classifier>
                    </artifactItem>
                  </artifactItems>
                  <outputDirectory>${project.build.directory}</outputDirectory>
                </configuration>
              </execution>
            </executions>
          </plugin>
    
          <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>3.0.0</version>
            <configuration>
              <executable>java</executable>
              <arguments>
                <argument>-javaagent:${project.build.directory}/javaagent-${hypertrace.version}-all.jar</argument>
                <argument>-classpath</argument>
                <classpath/>
                // Define the main class for the application
                <mainClass>com.example.Main</mainClass>
              </arguments>
            </configuration>
          </plugin>
        </plugins>
      </build>

    Dynamic attach

    You can dynamically attach the Java agent to your application only if your Java application is running in a Kubernetes environment. Traceable’s Kubernetes sidecar installation installs the agent-attacher. For more information on sidecar installation, see Traceable in Kubernetes with sidecar.


Configure

You can configure the Java agent using one of the following three methods:

Method 1 - Configure a YAML file

You can use the following sample YAML file, for example ,example-config.yaml to configure Traceable’s Java agent. If you do not provide the configuration file, the Java agent takes the inbuilt default values which you can see in the output of the command on the console. Run the above command separately for each Java application that you want to instrument with Traceable’s Java agent.

serviceName: service_name
reporting:
  endpoint: http://hostname:4317 
opa:
  endpoint: http://hostname:8181/

 The following table explains the various configuration options.

OptionDescription
serviceNameThe name of the service that you want it to be identified with on Traceable’s dashboard
propagationFormats

Defines the propagation format. Default is set as TRACECONTEXT. Options are TRACECONTEXT and B3

endpoint

Traceable agent's URL along with the port number.

  • http://hostname:9411/api/v2/spans - Zipkin reporter
secureSet it to true if you want to connect to the endpoint over TLS. The default value is true
opa: endpointURL of Traceable agent where it is running on port number 8181.
pollPeriodSecondsThe time in seconds to poll the OPA service to fetch the blocking rules.

dataCapture:

  • httpHeaders (request and response)
  • httpBody (request and response)
  • rpcMetadata (request and response)
  • rpcBody (request and response)
  • httpHeaders - Enable or disable capturing of request and response headers in HTTP
  • httpBody - Enable or disable capturing of request and response body in HTTP
  • rpcMetadata - Enable or disable capturing of request and response metadata in RPC
  • rpcBody - Enable or disable capturing of request and response body in RPC
Other Tracing vendors are likely to use the TRACECONTEXT propagation format as well. If you already have an existing Tracing solution and would like to use Traceable along side it, then you must reconfigure Traceable to use the B3 propagation format. This will ensure Traceable is not competing for the Traceparent and will avoid broken correlations from service to service.

Load the Java agent

After you have completed the configuration file, run the following command to instrument your Java application with Traceable’s Java agent:

HT_CONFIG_FILE=/<path_to_config_file>/example-config.yaml java -javaagent:/<path_to_java_agent>/javaagent-1.0.8 -jar app.jar

Method 2 - Provide configuration values as an environment variable

You can configure the Java agent by providing the configuration as an environment variable to the java command. When you provide configuration through an environment variable, it overwrites the configuration values set using Method 1. Following is an example of providing the configuration as an environment variable.

export HT_SERVICE_NAME=my_service_name HT_CONFIG_FILE=/<path_to_config_file>/example-config.yaml java -javaagent:/<path_to_java_agent>/javaagent.jar -jar app.jar
Environment variableDescription
HT_SERVICE_NAMEIdentifies the service or process on Traceable’s dashboard.
HT_REPORTING_ENDPOINT

The address of the Traceable agent where traces are reported, for example:

  • http://hostname:9411/api/v2/spans - ZIPKIN reporter
The hostname is the host where the Traceable agent is deployed.
HT_REPORTING_SECUREWhen true, connect to endpoints over TLS.
TA_OPA_ENDPOINTThe address of the Traceable agent with a reporting node 8181, for example, http://hostname:8181/. OPA endpoint is required to fetch Web application firewall configurations.
TA_OPA_POLL_PERIOD_SECONDSThe poll period in seconds to query the OPA service.
HT_REPORTING_TRACE_REPORTER_TYPEThis is an optional environmental variable.
HT_DATA_CAPTURE_HTTP_BODY_REQUESTWhen set to true, capture the body of the HTTP request
HT_DATA_CAPTURE_HTTP_BODY_RESPONSEWhen set to true, captures the body of the HTTP response
HT_DATA_CAPTURE_HTTP_HEADERS_REQUESTWhen set to true, captures the header of the HTTP request
HT_DATA_CAPTURE_HTTP_HEADERS_RESPONSEWhen set to true, captures the header of the HTTP response
HT_DATA_CAPTURE_RPC_METADATA_REQUESTWhen set to true, captures the RPC metadata of the request
HT_DATA_CAPTURE_RPC_METADATA_RESPONSEWhen set to true, captures the RPC metadata of the response
HT_DATA_CAPTURE_RPC_BODY_REQUESTWhen set to true, captures the RPC body of the request
HT_DATA_CAPTURE_RPC_BODY_RESPONSEWhen set to true, captures the RPC body of the response

Given Traceable is built on OpenTelemetry, you can also use the OTEL environment variables. Below is a small subset of what you can configure. The full list can be found here.

Method 3 - Provide configuration values as java system properties

You can also use Java’s -Dproperty=value method to set the configuration values. When you set the value using this method, it overwrites the values set using both Method 1 and 2. Following is an example of using Java’s -D flag:

java -Dht.service.name=my_service_name -javaagent:/<path_to_java_agent>/javaagent-1.0.8.jar -jar app.jar

Verify deployment

To verify the deployment of the Java agent, log into your Traceable Dashboard and click on Services. If the deployment was successful, you will see your service listed under the Name column.



Uninstalling Java agent

You can disable instrumentation by running the following command:

java -Dotel.instrumentation.<instrumentation-name>.enabled=false -javaagent:/<path_to_java_agent>/hypertrace-agent-all.jar -jar app.jar

 The following instrumentation names disable only Hypertrace instrumentation, not the core OpenTelemetery:

  • ht - All Hypertrace instrumentation
  • servlet-ht - Servlet, Spark Web
  • okhttp-ht - Okhttp
  • grpc-ht - Okhttp 

 The Hypertrace instrumentations also use the core OpenTelemetry instrumentation names. For example -Dotel.instrumentation.servlet.enabled=false disables all the servlet instrumentations including core OpenTelemetry and Hypertrace.


Was this article helpful?

What's Next