1717package org .fireflyframework .eda .error .impl ;
1818
1919import org .fireflyframework .eda .error .CustomErrorHandler ;
20- import io . micrometer . core . instrument . Counter ;
20+ import org . fireflyframework . observability . metrics . FireflyMetricsSupport ;
2121import io .micrometer .core .instrument .MeterRegistry ;
22- import io .micrometer .core .instrument .Timer ;
23- import lombok .RequiredArgsConstructor ;
2422import lombok .extern .slf4j .Slf4j ;
2523import org .springframework .boot .autoconfigure .condition .ConditionalOnClass ;
2624import org .springframework .boot .autoconfigure .condition .ConditionalOnProperty ;
2725import org .springframework .stereotype .Component ;
2826import reactor .core .publisher .Mono ;
2927
3028import java .util .Map ;
31- import java .util .concurrent .ConcurrentHashMap ;
29+ import java .util .concurrent .TimeUnit ;
3230
3331/**
34- * Custom error handler that records error metrics.
35- * <p>
36- * This handler demonstrates how to integrate custom error handling
37- * with metrics collection for monitoring and observability.
32+ * Custom error handler that records error metrics via {@link FireflyMetricsSupport}.
3833 */
3934@ Component
4035@ ConditionalOnClass (MeterRegistry .class )
4136@ ConditionalOnProperty (prefix = "firefly.eda.error.metrics" , name = "enabled" , havingValue = "true" , matchIfMissing = true )
42- @ RequiredArgsConstructor
4337@ Slf4j
44- public class MetricsErrorHandler implements CustomErrorHandler {
38+ public class MetricsErrorHandler extends FireflyMetricsSupport implements CustomErrorHandler {
4539
46- private final MeterRegistry meterRegistry ;
47- private final Map < String , Counter > errorCounters = new ConcurrentHashMap <>( );
48- private final Map < String , Timer > errorTimers = new ConcurrentHashMap <>();
40+ public MetricsErrorHandler ( MeterRegistry meterRegistry ) {
41+ super ( meterRegistry , "eda" );
42+ }
4943
5044 @ Override
5145 public Mono <Void > handleError (Object event , Map <String , Object > headers ,
5246 Throwable error , String listenerMethod ) {
53- return Mono .fromRunnable (() -> {
54- recordErrorMetrics (event , headers , error , listenerMethod );
55- });
47+ return Mono .fromRunnable (() -> recordErrorMetrics (event , headers , error , listenerMethod ));
5648 }
5749
5850 @ Override
@@ -62,47 +54,29 @@ public String getHandlerName() {
6254
6355 @ Override
6456 public int getPriority () {
65- return 50 ; // Medium priority for metrics
57+ return 50 ;
6658 }
6759
6860 private void recordErrorMetrics (Object event , Map <String , Object > headers , Throwable error , String listenerMethod ) {
69- try {
70- // Record error count by type and listener method
71- String errorType = error .getClass ().getSimpleName ();
72- String eventType = event .getClass ().getSimpleName ();
73-
74- // Error counter by listener method and error type
75- String counterKey = String .format ("eda.listener.errors.%s.%s" , listenerMethod , errorType );
76- Counter counter = errorCounters .computeIfAbsent (counterKey , key ->
77- Counter .builder ("eda.listener.errors" )
78- .description ("Number of errors in event listeners" )
79- .tag ("listener.method" , listenerMethod )
80- .tag ("error.type" , errorType )
81- .tag ("event.type" , eventType )
82- .register (meterRegistry )
83- );
84- counter .increment ();
85-
86- // Record error timing (if available in headers)
87- Object startTime = headers .get ("processing.start.time" );
88- if (startTime instanceof Long ) {
89- long duration = System .currentTimeMillis () - (Long ) startTime ;
90- String timerKey = String .format ("eda.listener.error.duration.%s" , listenerMethod );
91- Timer timer = errorTimers .computeIfAbsent (timerKey , key ->
92- Timer .builder ("eda.listener.error.duration" )
93- .description ("Duration of failed event processing" )
94- .tag ("listener.method" , listenerMethod )
95- .tag ("error.type" , errorType )
96- .register (meterRegistry )
97- );
98- timer .record (duration , java .util .concurrent .TimeUnit .MILLISECONDS );
99- }
61+ String errorType = error .getClass ().getSimpleName ();
62+ String eventType = event .getClass ().getSimpleName ();
10063
101- log .debug ("Recorded error metrics for {} in {}: {}" ,
102- errorType , listenerMethod , error .getMessage ());
64+ counter ("listener.errors" ,
65+ "listener.method" , listenerMethod ,
66+ "error.type" , errorType ,
67+ "event.type" , eventType )
68+ .increment ();
10369
104- } catch (Exception e ) {
105- log .warn ("Failed to record error metrics" , e );
70+ Object startTime = headers .get ("processing.start.time" );
71+ if (startTime instanceof Long ) {
72+ long duration = System .currentTimeMillis () - (Long ) startTime ;
73+ timer ("listener.error.duration" ,
74+ "listener.method" , listenerMethod ,
75+ "error.type" , errorType )
76+ .record (duration , TimeUnit .MILLISECONDS );
10677 }
78+
79+ log .debug ("Recorded error metrics for {} in {}: {}" ,
80+ errorType , listenerMethod , error .getMessage ());
10781 }
10882}
0 commit comments