Tutorial: Instrumenting a custom intermediate function with the Instana Tracing SDK

You can use the Instana Tracing SDK to instrument custom intermediate functions and gain visibility into application logic that is not automatically instrumented by Instana.

Example code

For an example code for the custom-intermediate-span-samplee tutorial, see Custom Intermediate Span Sample. It demonstrates how to use the Instana Java SDK to create custom intermediate spans in a Spring Boot application with MongoDB.

Instrumenting a custom intermediate function

Follow these steps to enable the Instana Java Tracer SDK and instrument a custom intermediate function:

  1. Add the Java Trace SDK as a dependency. If you are using Maven, add the following dependency to your .xml file:
    <dependency>
        <groupId>com.instana</groupId>
        <artifactId>instana-java-sdk</artifactId>
        <version>1.2.0</version>
    </dependency>
  2. To enable detection of SDK annotations, specify Java package names with SDK annotations in the configuration.yaml file.

    # Java Tracing
    com.instana.plugin.javatrace:
      instrumentation:
        # By default no packages are scanned for SDK annotations.
        sdk:
          packages:
              - 'com.instana.sample.application'
    Note: The specified packages are scanned recursively, so specifying only the most common package name is enough.
  3. Add a span annotation to a function to capture it in a trace.

    With the Instana Java Tracer SDK, you can assign one of three span types to a method to define its role in a trace. To capture a specific function, add the appropriate span annotation to the function definition.

    @Span(type = Type.INTERMEDIATE, value = "custom-instana-java-sdk")

    Example code:

    @Span(type = Span.Type.INTERMEDIATE, value = SPAN_NAME)
    public List<Profile> all(Boolean error) {
        try {
            if (error) {
                throw new Exception();
            }
            SpanSupport.annotate(Span.Type.INTERMEDIATE, SPAN_NAME, "tags.instana.java.sdk", "Success");
            return getAll();
        } catch (Exception e) {
            SpanSupport.annotate(Span.Type.INTERMEDIATE, SPAN_NAME, "tags.error", "true");
            SpanSupport.annotate(Span.Type.INTERMEDIATE, SPAN_NAME, "tags.instana.java.sdk", "Fail");
        }
        return Collections.emptyList();
    }
    
    private List<Profile> getAll() {
        return profileRepository.findAll();
    }
  4. Optional: Annotate the span with additional information.

    In certain situations, adding relevant information to SDK spans can better represent their origin. To add span attributes, incorporate conversion tags into the spans. These tags can be set by using the SpanSupport.annotate(type, name, key, value) method.

    SpanSupport.annotate(Span.Type.INTERMEDIATE, SPAN_NAME, "tags.instana.java.sdk","Success");
    Figure 1. Successful span details
    Successful span details
  5. Optional: Mark a span as erroneous.

    To designate a call as erroneous, incorporate the error tag:

    SpanSupport.annotate(Span.Type.INTERMEDIATE, SPAN_NAME, "tags.error","true");
  6. To view the complete trace, including the custom intermediate span and its annotations, in the Instana UI, run the following commands.

    To view a successful trace, run:

    curl -X 'GET' 'http://localhost:8081/v1/instana/profile?error=false' -H 'accept: application/json'
    Figure 2. Successful span
    Successful span

    To view an error trace, run:

    curl -X 'GET' 'http://localhost:8081/v1/instana/profile?error=true' -H 'accept: application/json'
    Figure 3. Error span
    Error span
    Figure 4. Error span details
    Error span details

Summary and outlook

This tutorial creates a new trace context for a custom intermediate function, thus enabling the execution of this function to be recognized as an intermediate span in Instana.

The span concept enhances observation granularity, categorizing calls into incoming, outgoing, and internal, offering detailed insights. The SDK's straightforward integration process, illustrated by Maven dependencies and configuration files, facilitates its seamless incorporation into applications.

For a full reference on the Instana Java SDK, see Java Trace SDK. For example, the @SpanParam and @SpanReturn annotations make it easier to capture parameters or return values as additional information far spans, which might be more convenient than explicitly calling SpanSupport.annotate() in some scenarios.