diff --git a/src/adservice/Dockerfile b/src/adservice/Dockerfile index 86c2864eb4..26b3288cc1 100644 --- a/src/adservice/Dockerfile +++ b/src/adservice/Dockerfile @@ -29,7 +29,8 @@ ARG version=1.19.1 WORKDIR /usr/src/app/ COPY --from=builder /usr/src/app/ ./ -ADD https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v$version/opentelemetry-javaagent.jar /app/opentelemetry-javaagent.jar +ADD https://search.maven.org/remotecontent?filepath=io/sentry/sentry-opentelemetry-agent/6.9.2/sentry-opentelemetry-agent-6.9.2.jar /app/opentelemetry-javaagent.jar + ENV JAVA_TOOL_OPTIONS=-javaagent:/app/opentelemetry-javaagent.jar EXPOSE ${AD_SERVICE_PORT} diff --git a/src/adservice/build.gradle b/src/adservice/build.gradle index 40bc08af59..0a43f693a5 100644 --- a/src/adservice/build.gradle +++ b/src/adservice/build.gradle @@ -14,8 +14,8 @@ description = 'Ad Service' group = "adservice" version = "0.1.0-SNAPSHOT" -def opentelemetryVersion = "1.19.0" -def opentelemetryInstrumentationAlphaVersion = "1.19.1-alpha" +def opentelemetryVersion = "1.20.1" +def opentelemetryInstrumentationAlphaVersion = "1.20.2-alpha" def grpcVersion = "1.45.1" def jacksonVersion = "2.13.2" def protocVersion = "3.20.0" @@ -46,7 +46,9 @@ dependencies { "io.opentelemetry:opentelemetry-api", "io.opentelemetry:opentelemetry-sdk", "io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations", - "org.apache.logging.log4j:log4j-core:2.17.2" + "org.apache.logging.log4j:log4j-core:2.17.2", + "io.sentry:sentry:6.9.2", + "io.sentry:sentry-opentelemetry-core:6.9.2" runtimeOnly "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}", "com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}", diff --git a/src/adservice/src/main/java/hipstershop/AdService.java b/src/adservice/src/main/java/hipstershop/AdService.java index a09ed9e580..602140a931 100644 --- a/src/adservice/src/main/java/hipstershop/AdService.java +++ b/src/adservice/src/main/java/hipstershop/AdService.java @@ -41,6 +41,10 @@ import java.util.Collection; import java.util.List; import java.util.Random; + +import io.sentry.Instrumenter; +import io.sentry.opentelemetry.OpenTelemetryLinkErrorEventProcessor; +import io.sentry.Sentry; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -131,6 +135,14 @@ public void getAds(AdRequest req, StreamObserver responseObserver) { span.setStatus(StatusCode.ERROR); logger.log(Level.WARN, "GetAds Failed with status {}", e.getStatus()); responseObserver.onError(e); + Sentry.captureException(e); + } catch (IllegalArgumentException e) { + span.addEvent( + "Error", Attributes.of(AttributeKey.stringKey("exception.message"), e.getMessage())); + span.setStatus(StatusCode.ERROR); + logger.log(Level.WARN, "GetAds Failed with message {}", e.getMessage()); + Sentry.captureException(e); + responseObserver.onError(e); } } } @@ -139,6 +151,9 @@ public void getAds(AdRequest req, StreamObserver responseObserver) { @WithSpan("getAdsByCategory") private Collection getAdsByCategory(@SpanAttribute("app.ads.category") String category) { + if ("telescopes".equals(category)) { + throw new IllegalArgumentException("Thrown on purpose for category " + category); + } Collection ads = adsMap.get(category); Span.current().setAttribute("app.ads.count", ads.size()); return ads; @@ -229,6 +244,23 @@ private static ImmutableListMultimap createAdsMap() { /** Main launches the server from the command line. */ public static void main(String[] args) throws IOException, InterruptedException { + logger.info("Initializing Sentry"); + Sentry.init(options -> { + // NOTE: SENTRY_DSN is injected as environment variable and this config setting picks it up + options.setEnableExternalConfiguration(true); + + // This is required for the Sentry Java Agent to actually perform instrumentation + options.setInstrumenter(Instrumenter.OTEL); + + options.addEventProcessor(new OpenTelemetryLinkErrorEventProcessor()); + + // Send all transactions to Sentry + options.setTracesSampleRate(1.0); + + // Enable this to see more logs + // options.setDebug(true); + }); + // Start the RPC server. You shouldn't see any output from gRPC before this. logger.info("AdService starting."); final AdService service = AdService.getInstance();