Interface Span

  • All Known Subinterfaces:
    Transaction
    All Known Implementing Classes:
    AbstractSpanImpl

    public interface Span
    A span contains information about a specific code path, executed as part of a Transaction.

    If for example a database query happens within a recorded transaction, a span representing this database query may be created. In such a case the name of the span will contain information about the query itself, and the type will hold information about the database type.

    Call ElasticApm.currentSpan() to get a reference of the current span.

    Note: Calling any methods after end() has been called is illegal. You may only interact with spans when you have control over its lifecycle. For example, if a span is ended on another thread you must not add labels if there is a chance for a race between the end() and the addLabel(String, String) method.

    • Method Detail

      • setName

        @Nonnull
        Span setName​(String name)
        The name of the span.
        Parameters:
        name - the name of the span
      • addLabel

        @Nonnull
        Span addLabel​(String key,
                      String value)

        Labels are used to add indexed information to transactions, spans, and errors. Indexed means the data is searchable and aggregatable in Elasticsearch. Multiple labels can be defined with different key-value pairs.

        • Indexed: Yes
        • Elasticsearch type: object
        • Elasticsearch field: labels (previously context.tags in stack version < 7.0)

        Label values can be a string, boolean, or number. Because labels for a given key are stored in the same place in Elasticsearch, all label values of a given key must have the same data type. Multiple data types per key will throw an exception, e.g. {foo: bar} and {foo: 42}

        Important: Avoid defining too many user-specified labels. Defining too many unique fields in an index is a condition that can lead to a mapping explosion.

        Parameters:
        key - The label key.
        value - The label value.
        Since:
        1.5.0
      • addLabel

        @Nonnull
        Span addLabel​(String key,
                      Number value)

        Labels are used to add indexed information to transactions, spans, and errors. Indexed means the data is searchable and aggregatable in Elasticsearch. Multiple labels can be defined with different key-value pairs.

        • Indexed: Yes
        • Elasticsearch type: object
        • Elasticsearch field: labels (previously context.tags in stack version < 7.0)

        Label values can be a string, boolean, or number. Because labels for a given key are stored in the same place in Elasticsearch, all label values of a given key must have the same data type. Multiple data types per key will throw an exception, e.g. {foo: bar} and {foo: 42}

        Note: Number and boolean labels were only introduced in APM Server 6.7+. Using this API in combination with an older APM Server versions leads to validation errors.

        Important: Avoid defining too many user-specified labels. Defining too many unique fields in an index is a condition that can lead to a mapping explosion.

        Parameters:
        key - The label key.
        value - The label value.
        Since:
        1.5.0, APM Server 6.7
      • addLabel

        @Nonnull
        Span addLabel​(String key,
                      boolean value)

        Labels are used to add indexed information to transactions, spans, and errors. Indexed means the data is searchable and aggregatable in Elasticsearch. Multiple labels can be defined with different key-value pairs.

        • Indexed: Yes
        • Elasticsearch type: object
        • Elasticsearch field: labels (previously context.tags in stack version < 7.0)

        Label values can be a string, boolean, or number. Because labels for a given key are stored in the same place in Elasticsearch, all label values of a given key must have the same data type. Multiple data types per key will throw an exception, e.g. {foo: bar} and {foo: 42}

        Note: Number and boolean labels were only introduced in APM Server 6.7+. Using this API in combination with an older APM Server versions leads to validation errors.

        Important: Avoid defining too many user-specified labels. Defining too many unique fields in an index is a condition that can lead to a mapping explosion.

        Parameters:
        key - The label key.
        value - The label value.
        Since:
        1.5.0, APM Server 6.7
      • setStartTimestamp

        Span setStartTimestamp​(long epochMicros)
        Sets the start timestamp of this event.
        Parameters:
        epochMicros - the timestamp of when this event happened, in microseconds (µs) since epoch
        Returns:
        this for chaining
        Since:
        1.5.0
      • startSpan

        @Nonnull
        Span startSpan​(String type,
                       @Nullable
                       String subtype,
                       @Nullable
                       String action)
        Start and return a new typed custom span as a child of this span.

        It is important to call end() when the span has ended. A best practice is to use the span in a try-catch-finally block. Example:

         Span span = parent.startSpan("db", "mysql", "query");
         try {
             span.setName("SELECT FROM customer");
             // do your thing...
         } catch (Exception e) {
             span.captureException(e);
             throw e;
         } finally {
             span.end();
         }
         

        NOTE: Spans created via this method can not be retrieved by calling ElasticApm.currentSpan(). See activate() on how to achieve that.

        The type, subtype and action strings are used to group similar spans together, with increasing resolution. For instance, all DB spans are given the type `db`; all spans of MySQL queries are given the subtype `mysql` and all spans describing queries are given the action `query`.

        In the above example `db` is considered the general type. Though there are no naming restrictions for the general types, the following are standardized across all Elastic APM agents: `app`, `db`, `cache`, `template`, and `ext`.

        NOTE: '.' (dot) character is not allowed within type, subtype and action. Any such character will be replaced with a '_' (underscore) character.

        Parameters:
        type - The general type of the new span
        subtype - The subtype of the new span
        action - The action related to the new span
        Returns:
        the started span, never null
      • startSpan

        @Nonnull
        Span startSpan()
        Start and return a new custom span with no type, as a child of this span.

        It is important to call end() when the span has ended. A best practice is to use the span in a try-catch-finally block. Example:

         Span span = parent.startSpan();
         try {
             span.setName("SELECT FROM customer");
             // do your thing...
         } catch (Exception e) {
             span.captureException(e);
             throw e;
         } finally {
             span.end();
         }
         

        NOTE: Spans created via this method can not be retrieved by calling ElasticApm.currentSpan(). See activate() on how to achieve that.

        Returns:
        the started span, never null
      • end

        void end()
        Ends the span and schedules it to be reported to the APM Server. It is illegal to call any methods on a span instance which has already ended. This also includes this method and startSpan().
      • end

        void end​(long epochMicros)
        Ends the span and schedules it to be reported to the APM Server. It is illegal to call any methods on a span instance which has already ended. This also includes this method and startSpan().
        Parameters:
        epochMicros - the timestamp of when this event ended, in microseconds (µs) since epoch
      • captureException

        void captureException​(Throwable throwable)
        Captures an exception and reports it to the APM server.
        Parameters:
        throwable - the exception to report
      • getId

        @Nonnull
        String getId()
        Returns the id of this span (never null)

        If this span represents a noop, this method returns an empty string.

        Returns:
        the id of this span (never null)
      • getTraceId

        @Nonnull
        String getTraceId()
        Returns the id of this trace (never null)

        The trace-ID is consistent across all transactions and spans which belong to the same logical trace, even for spans which happened in another service (given this service is also monitored by Elastic APM).

        If this span represents a noop, this method returns an empty string.

        Returns:
        the id of this span (never null)
      • activate

        Scope activate()
        Makes this span the active span on the current thread until Scope.close() has been called.

        Scopes should only be used in try-with-resource statements in order to make sure the Scope.close() method is called in all circumstances. Failing to close a scope can lead to memory leaks and corrupts the parent-child relationships.

        This method should always be used within a try-with-resources statement:

         Span span = parent.startSpan();
         // within the try block the span is available on the current thread via ElasticApm.currentSpan()
         // this is also true for methods called within the try block
         try (final Scope scope = span.activate()) {
             span.setName("SELECT FROM customer");
             span.setType("db.mysql.query");
             // do your thing...
         } catch (Exception e) {
             span.captureException(e);
             throw e;
         } finally {
             span.end();
         }
         

        Note: activate() and Scope.close() have to be called on the same thread.

        Returns:
        a scope which has to be Scope.close()d
      • isSampled

        boolean isSampled()
        Returns true if this span is recorded and sent to the APM Server
        Returns:
        true if this span is recorded and sent to the APM Server
      • injectTraceHeaders

        void injectTraceHeaders​(HeaderInjector headerInjector)
        Allows for manual propagation of the tracing headers.

        If you want to manually instrument an RPC framework which is not already supported by the auto-instrumentation capabilities of the agent, you can use this method to inject the required tracing headers into the header section of that framework's request object.

        Example:

         // Hook into a callback provided by the RPC framework that is called on outgoing requests
         public Response onOutgoingRequest(Request request) throws Exception {
             // creates a span representing the external call
             Span span = ElasticApm.currentSpan()
                     .startSpan("external", "http", null)
                     .setName(request.getMethod() + " " + request.getHost());
             try (final Scope scope = transaction.activate()) {
                 span.injectTraceHeaders((name, value) -> request.addHeader(name, value));
                 return request.execute();
             } catch (Exception e) {
                 span.captureException(e);
                 throw e;
             } finally {
                 span.end();
             }
         }
         
        Parameters:
        headerInjector - tells the agent how to inject a header into the request object
        Since:
        1.3.0