Observability

Spring for Apache Pulsar includes a way to manage observability through Micrometer.

Observability has not been added to the Reactive components yet

Micrometer Observations

The PulsarTemplate and PulsarListener are instrumented with the Micrometer observations API. When a Micrometer ObservationRegistry bean is provided, send and receive operations are traced and timed.

Custom tags

The default implementation adds the bean.name tag for template observations and listener.id tag for listener observations. To add other tags to timers and traces, configure a custom PulsarTemplateObservationConvention or PulsarListenerObservationConvention to the template or listener container, respectively.

You can subclass either DefaultPulsarTemplateObservationConvention or DefaultPulsarListenerObservationConvention or provide completely new implementations.

Observability - Metrics

Below you can find a list of all metrics declared by this project.

Listener Observation

Observation created when a Pulsar listener receives a message.

Metric name spring.pulsar.listener (defined by convention class org.springframework.pulsar.observation.DefaultPulsarListenerObservationConvention). Type timer.

Metric name spring.pulsar.listener.active (defined by convention class org.springframework.pulsar.observation.DefaultPulsarListenerObservationConvention). Type long task timer.

KeyValues that are added after starting the Observation might be missing from the *.active metrics.
Micrometer internally uses nanoseconds for the baseunit. However, each backend determines the actual baseunit. (i.e. Prometheus uses seconds)

Fully qualified name of the enclosing class org.springframework.pulsar.observation.PulsarListenerObservation.

All tags must be prefixed with spring.pulsar.listener prefix!
Table 1. Low cardinality Keys

Name

Description

spring.pulsar.listener.id (required)

Id of the listener container that received the message.

Template Observation

Observation created when a Pulsar template sends a message.

Metric name spring.pulsar.template (defined by convention class org.springframework.pulsar.observation.DefaultPulsarTemplateObservationConvention). Type timer.

Metric name spring.pulsar.template.active (defined by convention class org.springframework.pulsar.observation.DefaultPulsarTemplateObservationConvention). Type long task timer.

KeyValues that are added after starting the Observation might be missing from the *.active metrics.
Micrometer internally uses nanoseconds for the baseunit. However, each backend determines the actual baseunit. (i.e. Prometheus uses seconds)

Fully qualified name of the enclosing class org.springframework.pulsar.observation.PulsarTemplateObservation.

All tags must be prefixed with spring.pulsar.template prefix!
Table 2. Low cardinality Keys

Name

Description

spring.pulsar.template.name (required)

Bean name of the template that sent the message.

Observability - Spans

Below you can find a list of all spans declared by this project.

Listener Observation Span

Observation created when a Pulsar listener receives a message.

Span name spring.pulsar.listener (defined by convention class org.springframework.pulsar.observation.DefaultPulsarListenerObservationConvention).

Fully qualified name of the enclosing class org.springframework.pulsar.observation.PulsarListenerObservation.

All tags must be prefixed with spring.pulsar.listener prefix!
Table 3. Tag Keys

Name

Description

spring.pulsar.listener.id (required)

Id of the listener container that received the message.

Template Observation Span

Observation created when a Pulsar template sends a message.

Span name spring.pulsar.template (defined by convention class org.springframework.pulsar.observation.DefaultPulsarTemplateObservationConvention).

Fully qualified name of the enclosing class org.springframework.pulsar.observation.PulsarTemplateObservation.

All tags must be prefixed with spring.pulsar.template prefix!
Table 4. Tag Keys

Name

Description

spring.pulsar.template.name (required)

Bean name of the template that sent the message.

See Micrometer Tracing for more information.

Manual Configuration without Spring Boot

If you do not use Spring Boot, you need to configure and provide an ObservationRegistry as well as Micrometer Tracing. See Micrometer Tracing for more information.

Auto-Configuration with Spring Boot

If you use Spring Boot, the Spring Boot Actuator auto-configures an instance of ObservationRegistry for you. If micrometer-core is on the classpath, every stopped observation leads to a timer.

Spring Boot also auto-configures Micrometer Tracing for you. This includes support for Brave OpenTelemetry, Zipkin, and Wavefront. When using the Micrometer Observation API, finishing observations leads to spans reported to Zipkin or Wavefront. You can control tracing by setting properties under management.tracing. You can use Zipkin with management.zipkin.tracing, while Wavefront uses management.wavefront.

Example Configuration

The following example shows the steps to configure your Spring Boot application to use Zipkin with Brave.

  1. Add the required dependencies to your application (in Maven or Gradle, respectively):

    • Maven

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-tracing-bridge-brave</artifactId>
        </dependency>
        <dependency>
            <groupId>io.zipkin.reporter2</groupId>
            <artifactId>zipkin-reporter-brave</artifactId>
        </dependency>
        <dependency>
            <groupId>io.zipkin.reporter2</groupId>
            <artifactId>zipkin-sender-urlconnection</artifactId>
        </dependency>
    </dependencies>
    Gradle
    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter-actuator'
        implementation 'io.micrometer:micrometer-tracing-bridge-brave'
        implementation 'io.zipkin.reporter2:zipkin-reporter-brave'
        implementation 'io.zipkin.reporter2:zipkin-sender-urlconnection'
    }

    NOTE You need the 'io.zipkin.reporter2:zipkin-sender-urlconnection' dependency only if your application does not have a configured WebClient or RestTemplate.

  2. Add the required properties to your application:

    management:
      tracing.enabled: true
      zipkin:
        tracing.endpoint: "http://localhost:9411/api/v2/spans"

    The tracing.endpoint above expects Zipkin is running locally as described here.

At this point, your application should record traces when you send and receive Pulsar messages. You should be able to view them in the Zipkin UI (at localhost:9411, when running locally).

You can also see the preceding configuration on the Spring for Apache Pulsar Sample Apps.

The steps are very similar to configuring any of the other supported Tracing environments.