Tagging ADK for Java

Use the Tagging ADK for Java for protocol tagging only. In contrast to the Native ADK, the tagging ADK provides no means for instrumenting code, because instrumentation is provided by the various Java Sensors.

The Tagging ADK for Java is part of and is delivered with the Agent Development Kit (ADK).

Linking client & server paths

The following diagram illustrates how tagging links the Client-side path of a transaction to the Server-side path to create one PurePath for the entire transaction.

Linking Client-side to Server-side Path
Linking Client-side to Server-side Path

Using the ADK

Prerequisite

Include the library com.dynatrace.adk.jar from the ADK package into your project's classpath.

Initialize the Tagging ADK

Coding the initialization is illustrated by the figure below. The initialization step is required on both the client side and the server-side, once per process.

Initializing DynaTraceADKFactory
Initializing DynaTraceADKFactory

After successful initialization, DynaTraceADKFactory lets you create a Tagging object, which serves as the interface to the Agent.

Initialize DynaTraceADKFactory before creating a TaggingADK object:

DynaTraceADKFactory.initialize();

Use the following code to retrieve a TaggingADK object:

Tagging tagging = DynaTraceADKFactory.createTagging();

To free up resources allocated by the DynaTraceADKFactory, uninitialize the factory before your application quits:

DynaTraceADKFactory.uninitialize();

Uninitializing the DynaTraceADKFactory is necessary to disconnect properly from the AppMon Server and Collector, and to free up allocated resources.

Tag a request

Client-Side (Caller)

  1. Retrieve the current AppMon TraceTag.
  2. Specify where to include the server-side path (insert a link).
  3. Send the AppMon TraceTag along with the request to the server side.

Server-Side (Callee)

  1. Read the remote AppMon TraceTag.
  2. Place this tag on the server side.
  3. Start the server-side PurePath and continue processing.
  4. After the request is processed, mark the end of the server-side PurePath.
Tagging a Request
Tagging a Request

Retrieve the AppMon tag

You can retrieve the AppMon TraceTag either as a byte array or as a string. You can also use a predefined custom tag.

Retrieve the TraceTag as a byte array
byte[] dtTag = tagging.getTag();

Retrieve the TraceTag as a string
String tagAsString = tagging.getTagAsString();

Use a custom tag to retrieve the TraceTag
// assume that some kind of unique id exists
byte[] requestId = protocolData.getRequestId();
CustomTag customTag = tagging.createCustomTag(requestId);

You must call getTag each time before issuing a remote call to the server, even if it is in the same transaction to the same server. The tag that is retrieved by getTag identifies just one call. It cannot be reused.

When you use custom tags, any request or message ID that is used to identify the remote call must be unique. Another call requires a new, unique identifier.

In the client side, specify the location in the PurePath to include the server-side path, and specify whether the invocation is synchonous or asynchronous.

You may or may not specify the AppMon tag. If you omit the tag parameter, the ADK uses the current parameter, which is identical to the recently retrieved trace tag. This is why calling any ADK functions between getTag* and linkClientPurePath is not allowed. If you must have any other calls or other instrumented methods between getTag* and linkClientPurePath, it is required to specify the AppMon TraceTag explicitly.

This synchronous use case uses the current TraceTag.

tagging.linkClientPurePath(false);

This asynchronous use case specifies the TraceTag explicitly:

tagging.linkClientPurePath(true, dtTag);

This asynchronous use case uses a custom tag. In this case, the tag must be specified explicitly.

tagging.linkClientPurePath(true, customTag);

Note

Make sure linkClientPath() is invoked before startServerPurePath(). You must call linkClientPurePath before actually transmitting the tag data to the server.

Calling any ADK functions between getTag (or getTagAsString) and linkClientPurePath such as logging or other getTag calls is not permitted unless you specify the AppMon TraceTag explicitly in the tagging.linkClientPurePath() call.

Place a TraceTag on the server side

You can set the TraceTag either as a byte array or as a string. Use the same type you used to retrieve the tag on the client side.

The TraceTag was transferred as a byte array:

byte[] tag = [read trace tag];
tagging.setTag(tag);

The TraceTag was transferred as a string:

String tagAsString = [read trace tag];
tagging.setTagFromString(tagAsString);

A custom tag is always handled as a byte array:

byte[] customTag = [get the id from the request];
tagging.setCustomTag(customTag);

Note

Make sure you set the tag before you start or end the server-side sub-path.

Mark the server-side path's start and end

On the server side, you must specify where your path starts and ends. Enclose the actual processing code by startServerPurePath() and endServerPurePath().

Specifying a PurePath Start and End
Specifying a PurePath Start and End

public void waitForRequest() {  }

public void execute(Request req) {  }

public void handleRequest(Request req) {
  tagging.setTag(req.getTag());
  tagging.startServerPurePath();
  execute(req);
  tagging.endServerPurePath();
}

public void run() {
  while(true) {
    Request req = waitForRequest();
    handleRequest(req);
  }
}

The tagging interface

The Tagging object provides all the methods an application needs to attach to or continue PurePaths.

/**
 * Tagging provides the user with everything needed for
 * implementing tagging for proprietary protocols.
 * Use DynaTraceADKFactory to acquire an instance.   
 */
public interface Tagging {
    /**
     * Gets the current dynaTrace tag on the client side represented
     * as byte array for serialization by the user.
     * @return a byte array representing the tag
     * Please instrument the calling method\!
     */
    byte[] getTag();

    /**
     * Gets the current dynaTrace tag on the client side represented
     * as String for serialization by the user.
     * @return a String representing the tag
     * Please instrument the calling method\!
     */
    String getTagAsString();

    /**
     * Sets the dynaTrace tag on the server side from a byte array as
     * deserialized by the user.
     * @param tag a byte array representing the tag
     */
    void setTag(byte[] tag);

    /**
     * Sets the dynaTrace tag on the server side from a String as
     * deserialized by the user.
     * @param tag a String representing the tag
     */
    void setTagFromString(String tag);

    /**
     * Verifies whether a given tag is valid or not
     * @param tag    dynaTrace tag either as byte array or string
     * @return    true, if tag is valid, false otherwise
     */
    boolean isTagValid(Object tag);

    /**
     * Inserts a synchronous or asynchronous link on the client side.
     * Note: There cannot be any instrumented calls between getTag()
     *       resp. getTagAsString() and this call.
     * @param asynchronous true if asynchronous, false if synchronous
     * Please instrument the calling method\!
    */
    void linkClientPurePath(boolean asynchronous);

    /**
     * Inserts a synchronous or asynchronous link on the client side.
     * @param asynchronous true if asynchronous, false if synchronous
     * @param tag specify a certain tag to be linked with (this allows
     *    having instrumented calls between getTag() and this call).
     *    The tag can be specified either as byte array or as string.
     * Please instrument the calling method\!
     */
    void linkClientPurePath(boolean asynchronous, Object tag);

    /**
     * Starts a server-side PurePath
     */
    void startServerPurePath();

    /**
     * Ends a server-side PurePath
     */
    void endServerPurePath();

    /**
     * Returns a wrapper for a given Runnable which tags the Runnable as a server-side sub
     * path. The sub path starts when the run method of the given Runnable is called.
     *
     * Important: To link the client side path with the new sub path,
     * linkClientPurePath(boolean) has to be called immediately before the returned
     * Runnable is scheduled for execution.
     *
     * @param runnable the runnable to tag
     * @return the runnable to use instead of the given runnable
     */
    Runnable createServerPathRunnable(Runnable runnable);

    /**
     * Convert the specified dynaTrace tag to its string format.
     * @param  tag    dynaTrace tag (byte array)
     * @return dynaTrace tag as string
     */
    public String convertTagToString(byte[] tag);

    /**
     * Convert the specified dynaTrace string tag to the tag's byte array representation
     * @param  tag    dynaTrace tag (string format)
     * @return dynaTrace tag as byte array
     */
    public byte[] convertStringToTag(String tag);

    /**
     * Custom tagging: wrapper class for custom tags
     */
    public interface CustomTag {
        /**
         * Get current custom tag as byte array
         * @return    custom tag if present, null otherwise
         */
        public byte[] getTag();

        /**
         * Get string representation of this custom tag in the format <currentTag>:<prevTag>
         * @return hex string representation of this tag
         */
        public String asString();
    }

    /**
     * Create a custom tag object
     * @param tagData	  byte array containing the custom tag
     * @return CustomTag object
     */
    CustomTag createCustomTag(byte[] tagData);

    /**
     * Set specified custom tag at server side. The function has the same
     * functionality as setTag(), but allows to continue a PurePath by using
     * the specified custom tag.
     */
    void setCustomTag(byte[] customTag);   
}