33import io .sentry .*;
44import io .sentry .clientreport .DiscardReason ;
55import io .sentry .jcache .SentryJCacheWrapper ;
6+ import io .sentry .kafka .SentryKafkaConsumerInterceptor ;
67import io .sentry .kafka .SentryKafkaProducerInterceptor ;
78import io .sentry .protocol .Message ;
89import io .sentry .protocol .User ;
10+ import java .time .Duration ;
911import java .util .Collections ;
1012import java .util .Properties ;
13+ import java .util .UUID ;
14+ import java .util .concurrent .CountDownLatch ;
15+ import java .util .concurrent .TimeUnit ;
1116import javax .cache .Cache ;
1217import javax .cache .CacheManager ;
1318import javax .cache .Caching ;
1419import javax .cache .configuration .MutableConfiguration ;
20+ import org .apache .kafka .clients .consumer .ConsumerConfig ;
21+ import org .apache .kafka .clients .consumer .ConsumerRecords ;
22+ import org .apache .kafka .clients .consumer .KafkaConsumer ;
1523import org .apache .kafka .clients .producer .KafkaProducer ;
1624import org .apache .kafka .clients .producer .ProducerConfig ;
1725import org .apache .kafka .clients .producer .ProducerRecord ;
26+ import org .apache .kafka .common .serialization .StringDeserializer ;
1827import org .apache .kafka .common .serialization .StringSerializer ;
1928
2029public class Main {
@@ -261,6 +270,10 @@ private static void captureMetrics() {
261270 }
262271
263272 private static void demonstrateKafkaTracing () {
273+ final String topic = "sentry-topic-console-sample" ;
274+ final CountDownLatch consumedLatch = new CountDownLatch (1 );
275+ final Thread consumerThread = startKafkaConsumerThread (topic , consumedLatch );
276+
264277 final Properties producerProperties = new Properties ();
265278 producerProperties .put (ProducerConfig .BOOTSTRAP_SERVERS_CONFIG , "localhost:9092" );
266279 producerProperties .put (
@@ -273,17 +286,70 @@ private static void demonstrateKafkaTracing() {
273286 final ITransaction transaction = Sentry .startTransaction ("kafka-demo" , "demo" );
274287 try (ISentryLifecycleToken ignored = transaction .makeCurrent ()) {
275288 try (KafkaProducer <String , String > producer = new KafkaProducer <>(producerProperties )) {
276- producer .send (new ProducerRecord <>("sentry-topic" , "sentry-kafka sample message" )).get ();
289+ Thread .sleep (500 );
290+ producer .send (new ProducerRecord <>(topic , "sentry-kafka sample message" )).get ();
277291 } catch (InterruptedException e ) {
278292 Thread .currentThread ().interrupt ();
279293 } catch (Exception ignoredException ) {
280294 // local broker may not be available when running the sample
281295 }
296+
297+ try {
298+ consumedLatch .await (5 , TimeUnit .SECONDS );
299+ } catch (InterruptedException e ) {
300+ Thread .currentThread ().interrupt ();
301+ }
282302 } finally {
303+ consumerThread .interrupt ();
304+ try {
305+ consumerThread .join (1000 );
306+ } catch (InterruptedException e ) {
307+ Thread .currentThread ().interrupt ();
308+ }
283309 transaction .finish ();
284310 }
285311 }
286312
313+ private static Thread startKafkaConsumerThread (
314+ final String topic , final CountDownLatch consumedLatch ) {
315+ final Thread consumerThread =
316+ new Thread (
317+ () -> {
318+ final Properties consumerProperties = new Properties ();
319+ consumerProperties .put (ConsumerConfig .BOOTSTRAP_SERVERS_CONFIG , "localhost:9092" );
320+ consumerProperties .put (
321+ ConsumerConfig .GROUP_ID_CONFIG , "sentry-console-sample-" + UUID .randomUUID ());
322+ consumerProperties .put (ConsumerConfig .AUTO_OFFSET_RESET_CONFIG , "earliest" );
323+ consumerProperties .put (
324+ ConsumerConfig .KEY_DESERIALIZER_CLASS_CONFIG , StringDeserializer .class .getName ());
325+ consumerProperties .put (
326+ ConsumerConfig .VALUE_DESERIALIZER_CLASS_CONFIG ,
327+ StringDeserializer .class .getName ());
328+ consumerProperties .put (
329+ ConsumerConfig .INTERCEPTOR_CLASSES_CONFIG ,
330+ SentryKafkaConsumerInterceptor .class .getName ());
331+
332+ try (KafkaConsumer <String , String > consumer =
333+ new KafkaConsumer <>(consumerProperties )) {
334+ consumer .subscribe (Collections .singletonList (topic ));
335+
336+ while (!Thread .currentThread ().isInterrupted () && consumedLatch .getCount () > 0 ) {
337+ final ConsumerRecords <String , String > records =
338+ consumer .poll (Duration .ofMillis (500 ));
339+ if (!records .isEmpty ()) {
340+ consumedLatch .countDown ();
341+ break ;
342+ }
343+ }
344+ } catch (Exception ignored ) {
345+ // local broker may not be available when running the sample
346+ }
347+ },
348+ "sentry-kafka-sample-consumer" );
349+ consumerThread .start ();
350+ return consumerThread ;
351+ }
352+
287353 private static class SomeEventProcessor implements EventProcessor {
288354 @ Override
289355 public SentryEvent process (SentryEvent event , Hint hint ) {
0 commit comments