Skip to content

Commit

Permalink
Adding OpenTelemetry tracing
Browse files Browse the repository at this point in the history
  • Loading branch information
edeandrea committed Mar 27, 2024
1 parent b888f13 commit ebc37f6
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.jdbc.datasource.JdbcTelemetry;

/**
* This class is needed to allow tracing down to the JDBC level.
* Taken from https://opentelemetry.io/docs/languages/java/automatic/spring-boot/#jdbc-instrumentation
*/
@Configuration
public class OtelDataSourceConfig {
@Bean
Expand Down
73 changes: 73 additions & 0 deletions src/main/java/com/redhat/springmusic/config/SpanAspectConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.redhat.springmusic.config;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.SimpleEvaluationContext;

import io.micrometer.common.annotation.NoOpValueResolver;
import io.micrometer.common.annotation.ValueExpressionResolver;
import io.micrometer.common.annotation.ValueResolver;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.annotation.DefaultNewSpanParser;
import io.micrometer.tracing.annotation.ImperativeMethodInvocationProcessor;
import io.micrometer.tracing.annotation.MethodInvocationProcessor;
import io.micrometer.tracing.annotation.NewSpanParser;
import io.micrometer.tracing.annotation.SpanAspect;

/**
* This class is needed in order for @NewSpan and @SpanTag annotations to work
* See https://docs.micrometer.io/tracing/reference/api.html
*/
@Configuration
public class SpanAspectConfig {
@Bean
NewSpanParser newSpanParser() {
return new DefaultNewSpanParser();
}

@Bean
ValueResolver valueResolver() {
return new NoOpValueResolver();
}

@Bean
ValueExpressionResolver valueExpressionResolver() {
return new SpelTagValueExpressionResolver();
}

@Bean
MethodInvocationProcessor methodInvocationProcessor(NewSpanParser newSpanParser, Tracer tracer, BeanFactory beanFactory) {
return new ImperativeMethodInvocationProcessor(newSpanParser, tracer, beanFactory::getBean, beanFactory::getBean);
}

@Bean
SpanAspect spanAspect(MethodInvocationProcessor methodInvocationProcessor) {
return new SpanAspect(methodInvocationProcessor);
}

// Example of using SpEL to resolve expressions in @SpanTag
static class SpelTagValueExpressionResolver implements ValueExpressionResolver {
private static final Log log = LogFactory.getLog(SpelTagValueExpressionResolver.class);

@Override
public String resolve(String expression, Object parameter) {
try {
var context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
var expressionParser = new SpelExpressionParser();
var expressionToEvaluate = expressionParser.parseExpression(expression);

return expressionToEvaluate.getValue(context, parameter, String.class);
}
catch (Exception ex) {
log.error("Exception occurred while tying to evaluate the SpEL expression [" + expression + "]", ex);
}

return parameter.toString();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ protected AlbumEventListener(OutboxEventService outboxEventService) {
}

@EventListener
@NewSpan(name = "AlbumEventListener.handleAlbumEvent")
public void handleAlbumEvent(@SpanTag(key = "albumEvent") AlbumEvent albumEvent) {
@NewSpan("AlbumEventListener.handleAlbumEvent")
public void handleAlbumEvent(@SpanTag(key = "arg.albumEvent") AlbumEvent albumEvent) {
Assert.notNull(albumEvent, "albumEvent can not be null");
LOGGER.info("Handling AlbumEvent {}", albumEvent);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ public AlbumEventPublishingService(AlbumRepository albumRepository, ApplicationE
}

@Override
@NewSpan(name = "AlbumService.getAllAlbums")
@NewSpan("AlbumService.getAllAlbums")
public Iterable<Album> getAllAlbums() {
LOGGER.info("Getting all albums");
return this.albumRepository.findAll();
}

@Override
@Transactional
@NewSpan(name = "AlbumService.createAlbum")
@NewSpan("AlbumService.createAlbum")
public Album createAlbum(@SpanTag(key = "arg.album") Album album) {
LOGGER.info("Creating album {}", album);

Expand All @@ -50,7 +50,7 @@ public Album createAlbum(@SpanTag(key = "arg.album") Album album) {

@Override
@Transactional
@NewSpan(name = "AlbumService.updateAlbum")
@NewSpan("AlbumService.updateAlbum")
public void updateAlbum(@SpanTag(key = "arg.album") Album album) {
this.albumRepository.findById(album.getId())
.map(this.albumRepository::detach)
Expand All @@ -61,15 +61,15 @@ public void updateAlbum(@SpanTag(key = "arg.album") Album album) {
}

@Override
@NewSpan(name = "AlbumService.getAlbum")
@NewSpan("AlbumService.getAlbum")
public Optional<Album> getAlbum(@SpanTag(key = "arg.albumId") String albumId) {
LOGGER.info("Getting album {}", albumId);
return this.albumRepository.findById(albumId);
}

@Override
@Transactional
@NewSpan(name = "AlbumService.deleteAlbum")
@NewSpan("AlbumService.deleteAlbum")
public void deleteAlbum(@SpanTag(key = "arg.albumId") String albumId) {
this.albumRepository.findById(albumId)
.map(this.albumRepository::detach)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,32 +27,32 @@ public DefaultOutboxEventService(OutboxEventRepository outboxEventRepository) {
}

@Override
@NewSpan(name = "OutboxEventService.getAllEventsOrderedByTimestampDescending")
@NewSpan("OutboxEventService.getAllEventsOrderedByTimestampDescending")
public Iterable<OutboxEvent> getAllEventsOrderedByTimestampDescending() {
LOGGER.info("Getting all album events ordered by timestamp descending");
return this.outboxEventRepository.findAll(Sort.by("eventTimestamp").descending());
}

@Override
@NewSpan(name = "OutboxEventService.getById")
@NewSpan("OutboxEventService.getById")
public Optional<OutboxEvent> getById(@SpanTag(key = "arg.eventId") long eventId) {
return this.outboxEventRepository.findById(eventId);
}

@Override
@NewSpan(name = "OutboxEventService.getAllEventsForAlbumIdOrderedByTimestampDescending")
@NewSpan("OutboxEventService.getAllEventsForAlbumIdOrderedByTimestampDescending")
public Iterable<OutboxEvent> getAllEventsForAlbumIdOrderedByTimestampDescending(@SpanTag(key = "arg.albumId") String albumId) {
return this.outboxEventRepository.findAllByAggregateIdOrderByEventTimestampDesc(albumId);
}

@Override
@NewSpan(name = "OutboxEventService.deleteAllEvents")
@NewSpan("OutboxEventService.deleteAllEvents")
public void deleteAllEvents() {
this.outboxEventRepository.deleteAll();
}

@Override
@NewSpan(name = "OutboxEventService.persistEvent")
@NewSpan("OutboxEventService.persistEvent")
public OutboxEvent persistEvent(@SpanTag(key = "arg.event") AlbumEvent event) {
return this.outboxEventRepository.save(
OutboxEvent.builder()
Expand Down

0 comments on commit ebc37f6

Please sign in to comment.