diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/observation/TimerObservationHandler.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/observation/DefaultMeterObservationHandler.java similarity index 86% rename from micrometer-core/src/main/java/io/micrometer/core/instrument/observation/TimerObservationHandler.java rename to micrometer-core/src/main/java/io/micrometer/core/instrument/observation/DefaultMeterObservationHandler.java index 8b342e9154..2b75664740 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/instrument/observation/TimerObservationHandler.java +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/observation/DefaultMeterObservationHandler.java @@ -21,7 +21,7 @@ import java.util.stream.Collectors; /** - * Handler for {@link Timer.Sample}. + * Handler for {@link Timer.Sample} and {@link Counter} * * WARNING: Since the {@link LongTaskTimer} needs to be created in the {@code onStart} * method, it can only contain tags that are available by that time. This means that if @@ -36,11 +36,11 @@ * @author Jonatan Ivanov * @since 1.10.0 */ -public class TimerObservationHandler implements MeterObservationHandler { +public class DefaultMeterObservationHandler implements MeterObservationHandler { private final MeterRegistry meterRegistry; - public TimerObservationHandler(MeterRegistry meterRegistry) { + public DefaultMeterObservationHandler(MeterRegistry meterRegistry) { this.meterRegistry = meterRegistry; } @@ -65,8 +65,9 @@ public void onStop(Observation.Context context) { } @Override - public boolean supportsContext(Observation.Context context) { - return true; + public void onEvent(Observation.Event event, Observation.Context context) { + Counter.builder(context.getName() + "." + event.getName()).tags(createTags(context)).register(meterRegistry) + .increment(); } private Tags createErrorTags(Observation.Context context) { diff --git a/micrometer-core/src/main/java/io/micrometer/core/instrument/observation/MeterObservationHandler.java b/micrometer-core/src/main/java/io/micrometer/core/instrument/observation/MeterObservationHandler.java index 1af0b96839..6f7f1250c7 100644 --- a/micrometer-core/src/main/java/io/micrometer/core/instrument/observation/MeterObservationHandler.java +++ b/micrometer-core/src/main/java/io/micrometer/core/instrument/observation/MeterObservationHandler.java @@ -27,4 +27,9 @@ */ public interface MeterObservationHandler extends ObservationHandler { + @Override + default boolean supportsContext(Observation.Context context) { + return true; + } + } diff --git a/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/okhttp3/OkHttpObservationInterceptorTest.java b/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/okhttp3/OkHttpObservationInterceptorTest.java index 9877600c9c..e05dee5561 100644 --- a/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/okhttp3/OkHttpObservationInterceptorTest.java +++ b/micrometer-core/src/test/java/io/micrometer/core/instrument/binder/okhttp3/OkHttpObservationInterceptorTest.java @@ -21,7 +21,7 @@ import io.micrometer.common.KeyValues; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.MockClock; -import io.micrometer.core.instrument.observation.TimerObservationHandler; +import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; import io.micrometer.core.instrument.simple.SimpleConfig; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.micrometer.observation.Observation; @@ -76,7 +76,7 @@ private OkHttpObservationInterceptor.Builder defaultInterceptorBuilder() { @BeforeEach void setup() { observationRegistry.observationConfig().observationHandler(testHandler); - observationRegistry.observationConfig().observationHandler(new TimerObservationHandler(registry)); + observationRegistry.observationConfig().observationHandler(new DefaultMeterObservationHandler(registry)); observationRegistry.observationConfig().observationHandler(new PropagatingHandler()); } diff --git a/micrometer-observation-test/src/main/java/io/micrometer/observation/tck/AnyContextObservationHandlerCompatibilityKit.java b/micrometer-observation-test/src/main/java/io/micrometer/observation/tck/AnyContextObservationHandlerCompatibilityKit.java index 55c9f03652..ce02ed0395 100644 --- a/micrometer-observation-test/src/main/java/io/micrometer/observation/tck/AnyContextObservationHandlerCompatibilityKit.java +++ b/micrometer-observation-test/src/main/java/io/micrometer/observation/tck/AnyContextObservationHandlerCompatibilityKit.java @@ -41,6 +41,8 @@ void handlerSupportsAnyContext() { assertThatCode(() -> handler.onStart(testContext)).doesNotThrowAnyException(); assertThatCode(() -> handler.onStop(testContext)).doesNotThrowAnyException(); assertThatCode(() -> handler.onError(testContext)).doesNotThrowAnyException(); + assertThatCode(() -> handler.onEvent(new Observation.Event("testEvent"), testContext)) + .doesNotThrowAnyException(); assertThatCode(() -> handler.onScopeOpened(testContext)).doesNotThrowAnyException(); assertThatCode(() -> handler.supportsContext(testContext)).doesNotThrowAnyException(); assertThat(handler.supportsContext(testContext)).as("Handler supports any context").isTrue(); diff --git a/micrometer-observation-test/src/main/java/io/micrometer/observation/tck/ConcreteContextObservationHandlerCompatibilityKit.java b/micrometer-observation-test/src/main/java/io/micrometer/observation/tck/ConcreteContextObservationHandlerCompatibilityKit.java index 73dee680a2..597190873c 100644 --- a/micrometer-observation-test/src/main/java/io/micrometer/observation/tck/ConcreteContextObservationHandlerCompatibilityKit.java +++ b/micrometer-observation-test/src/main/java/io/micrometer/observation/tck/ConcreteContextObservationHandlerCompatibilityKit.java @@ -58,6 +58,7 @@ void handlerSupportsConcreteContextForHandlerMethods() { assertThatCode(() -> handler.onStart(context())).doesNotThrowAnyException(); assertThatCode(() -> handler.onStop(context())).doesNotThrowAnyException(); assertThatCode(() -> handler.onError(context())).doesNotThrowAnyException(); + assertThatCode(() -> handler.onEvent(new Observation.Event("testEvent"), context())).doesNotThrowAnyException(); assertThatCode(() -> handler.onScopeOpened(context())).doesNotThrowAnyException(); } diff --git a/micrometer-observation-test/src/main/java/io/micrometer/observation/tck/NullContextObservationHandlerCompatibilityKit.java b/micrometer-observation-test/src/main/java/io/micrometer/observation/tck/NullContextObservationHandlerCompatibilityKit.java index 44e47c28f2..395d7c3eda 100644 --- a/micrometer-observation-test/src/main/java/io/micrometer/observation/tck/NullContextObservationHandlerCompatibilityKit.java +++ b/micrometer-observation-test/src/main/java/io/micrometer/observation/tck/NullContextObservationHandlerCompatibilityKit.java @@ -56,6 +56,7 @@ void handlerSupportsNullContext() { assertThatCode(() -> handler.onStart(null)).doesNotThrowAnyException(); assertThatCode(() -> handler.onStop(null)).doesNotThrowAnyException(); assertThatCode(() -> handler.onError(null)).doesNotThrowAnyException(); + assertThatCode(() -> handler.onEvent(null, null)).doesNotThrowAnyException(); assertThatCode(() -> handler.onScopeOpened(null)).doesNotThrowAnyException(); assertThatCode(() -> handler.supportsContext(null)).doesNotThrowAnyException(); assertThat(handler.supportsContext(null)).as("Handler supports null context").isTrue(); diff --git a/micrometer-observation-test/src/main/java/io/micrometer/observation/tck/ObservationRegistryCompatibilityKit.java b/micrometer-observation-test/src/main/java/io/micrometer/observation/tck/ObservationRegistryCompatibilityKit.java index 9051a14fe7..1b50d13707 100644 --- a/micrometer-observation-test/src/main/java/io/micrometer/observation/tck/ObservationRegistryCompatibilityKit.java +++ b/micrometer-observation-test/src/main/java/io/micrometer/observation/tck/ObservationRegistryCompatibilityKit.java @@ -17,6 +17,7 @@ import io.micrometer.common.KeyValue; import io.micrometer.common.KeyValues; +import io.micrometer.common.lang.Nullable; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationHandler; import io.micrometer.observation.ObservationRegistry; @@ -80,6 +81,10 @@ void observeWithHandlers() { inOrder.verify(handler).onScopeOpened(isA(Observation.Context.class)); assertThat(scope.getCurrentObservation()).isSameAs(observation); + Observation.Event event = new Observation.Event("testEvent", "event for testing"); + observation.event(event); + inOrder.verify(handler).onEvent(same(event), isA(Observation.Context.class)); + Throwable exception = new IOException("simulated"); observation.error(exception); inOrder.verify(handler).onError(isA(Observation.Context.class)); @@ -455,10 +460,6 @@ public boolean supportsContext(Observation.Context context) { return context instanceof TestContext; } - public String getId() { - return this.id; - } - } static class UnsupportedKeyValuesProvider implements Observation.GlobalKeyValuesProvider { @@ -490,6 +491,7 @@ static class AssertingHandler implements ObservationHandler private boolean stopped = false; + @Nullable private Observation.Context context = null; @Override diff --git a/micrometer-observation-test/src/test/java/io/micrometer/observation/tck/AnyContextObservationHandlerCompatibilityKitTests.java b/micrometer-observation-test/src/test/java/io/micrometer/observation/tck/AnyContextObservationHandlerCompatibilityKitTests.java index c8cef509a8..b10ad79dc0 100644 --- a/micrometer-observation-test/src/test/java/io/micrometer/observation/tck/AnyContextObservationHandlerCompatibilityKitTests.java +++ b/micrometer-observation-test/src/test/java/io/micrometer/observation/tck/AnyContextObservationHandlerCompatibilityKitTests.java @@ -31,6 +31,10 @@ public void onStart(Observation.Context context) { public void onError(Observation.Context context) { } + @Override + public void onEvent(Observation.Event event, Observation.Context context) { + } + @Override public void onScopeOpened(Observation.Context context) { } diff --git a/micrometer-observation-test/src/test/java/io/micrometer/observation/tck/ConcreteContextObservationHandlerCompatibilityKitTests.java b/micrometer-observation-test/src/test/java/io/micrometer/observation/tck/ConcreteContextObservationHandlerCompatibilityKitTests.java index a7331ed54e..b4c6ab2d74 100644 --- a/micrometer-observation-test/src/test/java/io/micrometer/observation/tck/ConcreteContextObservationHandlerCompatibilityKitTests.java +++ b/micrometer-observation-test/src/test/java/io/micrometer/observation/tck/ConcreteContextObservationHandlerCompatibilityKitTests.java @@ -32,6 +32,10 @@ public void onStart(Observation.Context context) { public void onError(Observation.Context context) { } + @Override + public void onEvent(Observation.Event event, Observation.Context context) { + } + @Override public void onScopeOpened(Observation.Context context) { diff --git a/micrometer-observation-test/src/test/java/io/micrometer/observation/tck/NullContextObservationHandlerCompatibilityKitTests.java b/micrometer-observation-test/src/test/java/io/micrometer/observation/tck/NullContextObservationHandlerCompatibilityKitTests.java index 046f22a028..f00b3d8923 100644 --- a/micrometer-observation-test/src/test/java/io/micrometer/observation/tck/NullContextObservationHandlerCompatibilityKitTests.java +++ b/micrometer-observation-test/src/test/java/io/micrometer/observation/tck/NullContextObservationHandlerCompatibilityKitTests.java @@ -31,6 +31,10 @@ public void onStart(Observation.Context context) { public void onError(Observation.Context context) { } + @Override + public void onEvent(Observation.Event event, Observation.Context context) { + } + @Override public void onScopeOpened(Observation.Context context) { } diff --git a/micrometer-observation/src/main/java/io/micrometer/observation/NoopObservation.java b/micrometer-observation/src/main/java/io/micrometer/observation/NoopObservation.java index 29f42d987f..7b8f30bdb4 100644 --- a/micrometer-observation/src/main/java/io/micrometer/observation/NoopObservation.java +++ b/micrometer-observation/src/main/java/io/micrometer/observation/NoopObservation.java @@ -78,6 +78,11 @@ public Observation error(Throwable error) { return this; } + @Override + public Observation event(Event event) { + return this; + } + @Override public Observation start() { return this; diff --git a/micrometer-observation/src/main/java/io/micrometer/observation/Observation.java b/micrometer-observation/src/main/java/io/micrometer/observation/Observation.java index e32a0ed616..90ef6405d5 100644 --- a/micrometer-observation/src/main/java/io/micrometer/observation/Observation.java +++ b/micrometer-observation/src/main/java/io/micrometer/observation/Observation.java @@ -59,7 +59,7 @@ public interface Observation { * @param registry observation registry * @return started observation */ - static Observation start(String name, @Nullable ObservationRegistry registry) { + static Observation start(String name, ObservationRegistry registry) { return start(name, null, registry); } @@ -322,12 +322,19 @@ default boolean isNoop() { Observation keyValuesProvider(KeyValuesProvider keyValuesProvider); /** - * Sets an error. + * Signals an error. * @param error error * @return this */ Observation error(Throwable error); + /** + * Signals an arbitrary {@link Event}. + * @param event event + * @return this + */ + Observation event(Event event); + /** * Starts the observation. Remember to call this method, otherwise timing calculations * will not take place. @@ -576,6 +583,7 @@ class Context implements ContextView { private String name; + @Nullable private String contextualName; @Nullable @@ -826,6 +834,58 @@ private String toString(Map map) { } + /** + * An arbitrary event that you can extend and signal during an {@link Observation}. + * This helps you to tell to the {@link ObservationHandler} that something happened. + * If you want to signal an exception/error, please use + * {@link Observation#error(Throwable)} instead. + */ + class Event { + + private final String name; + + private final String contextualName; + + /** + * @param name The name of the event. + */ + public Event(String name) { + this(name, name); + } + + /** + * @param name The name of the event (should have low cardinality). + * @param contextualName The contextual name of the event (can have high + * cardinality). + */ + public Event(String name, String contextualName) { + this.name = name; + this.contextualName = contextualName; + } + + /** + * Returns the name of the event. + * @return the name of the event. + */ + public String getName() { + return this.name; + } + + /** + * Returns the contextual name of the event. + * @return the contextual name of the event. + */ + public String getContextualName() { + return this.contextualName; + } + + @Override + public String toString() { + return "event.name='" + this.name + "', event.contextualName='" + this.contextualName + '\''; + } + + } + /** * Read only view on the {@link Context}. */ @@ -842,6 +902,7 @@ interface ContextView { * context (e.g. name derived from HTTP request). * @return contextual name */ + @Nullable String getContextualName(); /** diff --git a/micrometer-observation/src/main/java/io/micrometer/observation/ObservationHandler.java b/micrometer-observation/src/main/java/io/micrometer/observation/ObservationHandler.java index cde6f7ccd2..410dab6749 100644 --- a/micrometer-observation/src/main/java/io/micrometer/observation/ObservationHandler.java +++ b/micrometer-observation/src/main/java/io/micrometer/observation/ObservationHandler.java @@ -47,6 +47,14 @@ default void onStart(T context) { default void onError(T context) { } + /** + * Reacts to arbitrary {@link Observation.Event}. + * @param event the {@link Observation.Event} that was signaled + * @param context a {@link Observation.Context} + */ + default void onEvent(Observation.Event event, T context) { + } + /** * Reacts to opening of an {@link Observation.Scope}. * @param context an {@link Observation.Context} @@ -131,6 +139,11 @@ public void onError(Observation.Context context) { getFirstApplicableHandler(context).ifPresent(handler -> handler.onError(context)); } + @Override + public void onEvent(Observation.Event event, Observation.Context context) { + getFirstApplicableHandler(context).ifPresent(handler -> handler.onEvent(event, context)); + } + @Override public void onScopeOpened(Observation.Context context) { getFirstApplicableHandler(context).ifPresent(handler -> handler.onScopeOpened(context)); @@ -200,6 +213,11 @@ public void onError(Observation.Context context) { getAllApplicableHandlers(context).forEach(handler -> handler.onError(context)); } + @Override + public void onEvent(Observation.Event event, Observation.Context context) { + getAllApplicableHandlers(context).forEach(handler -> handler.onEvent(event, context)); + } + @Override public void onScopeOpened(Observation.Context context) { getAllApplicableHandlers(context).forEach(handler -> handler.onScopeOpened(context)); diff --git a/micrometer-observation/src/main/java/io/micrometer/observation/ObservationTextPublisher.java b/micrometer-observation/src/main/java/io/micrometer/observation/ObservationTextPublisher.java index 08512f5ab7..d09be4ecb5 100644 --- a/micrometer-observation/src/main/java/io/micrometer/observation/ObservationTextPublisher.java +++ b/micrometer-observation/src/main/java/io/micrometer/observation/ObservationTextPublisher.java @@ -88,6 +88,11 @@ public void onError(Observation.Context context) { publish("ERROR", context); } + @Override + public void onEvent(Observation.Event event, Observation.Context context) { + publishUnformatted(String.format("%5s - %s, %s", "EVENT", event, converter.apply(context))); + } + @Override public void onScopeOpened(Observation.Context context) { publish("OPEN", context); @@ -109,7 +114,11 @@ public boolean supportsContext(Observation.Context context) { } private void publish(String event, Observation.Context context) { - this.consumer.accept(String.format("%5s - %s", event, converter.apply(context))); + publishUnformatted(String.format("%5s - %s", event, converter.apply(context))); + } + + private void publishUnformatted(String event) { + this.consumer.accept(event); } } diff --git a/micrometer-observation/src/main/java/io/micrometer/observation/SimpleObservation.java b/micrometer-observation/src/main/java/io/micrometer/observation/SimpleObservation.java index db72cbf11e..a9cb7db897 100644 --- a/micrometer-observation/src/main/java/io/micrometer/observation/SimpleObservation.java +++ b/micrometer-observation/src/main/java/io/micrometer/observation/SimpleObservation.java @@ -129,6 +129,12 @@ public Observation error(Throwable error) { return this; } + @Override + public Observation event(Event event) { + this.notifyOnEvent(event); + return this; + } + @Override public Observation start() { this.notifyOnObservationStarted(); @@ -177,6 +183,11 @@ private void notifyOnError() { this.handlers.forEach(handler -> handler.onError(this.context)); } + @SuppressWarnings("unchecked") + private void notifyOnEvent(Event event) { + this.handlers.forEach(handler -> handler.onEvent(event, this.context)); + } + @SuppressWarnings("unchecked") private void notifyOnScopeOpened() { this.handlers.forEach(handler -> handler.onScopeOpened(this.context)); diff --git a/micrometer-observation/src/test/java/io/micrometer/observation/AllMatchingCompositeObservationHandlerTests.java b/micrometer-observation/src/test/java/io/micrometer/observation/AllMatchingCompositeObservationHandlerTests.java index 5825f11c8c..d02f94e141 100644 --- a/micrometer-observation/src/test/java/io/micrometer/observation/AllMatchingCompositeObservationHandlerTests.java +++ b/micrometer-observation/src/test/java/io/micrometer/observation/AllMatchingCompositeObservationHandlerTests.java @@ -62,6 +62,17 @@ void should_run_on_error_for_all_matching_handlers() { assertThat(this.matchingHandler2.errored).isTrue(); } + @Test + void should_run_on_event_for_all_matching_handlers() { + AllMatchingCompositeObservationHandler allMatchingHandler = new AllMatchingCompositeObservationHandler( + new NotMatchingHandler(), this.matchingHandler, new NotMatchingHandler(), this.matchingHandler2); + + allMatchingHandler.onEvent(new Observation.Event("testEvent"), null); + + assertThat(this.matchingHandler.eventDetected).isTrue(); + assertThat(this.matchingHandler2.eventDetected).isTrue(); + } + @Test void should_run_on_scope_opened_for_all_matching_handlers() { AllMatchingCompositeObservationHandler allMatchingHandler = new AllMatchingCompositeObservationHandler( @@ -121,6 +132,8 @@ static class MatchingHandler implements ObservationHandler boolean errored; + boolean eventDetected; + boolean scopeOpened; boolean scopeClosed; @@ -135,6 +148,11 @@ public void onError(Observation.Context context) { this.errored = true; } + @Override + public void onEvent(Observation.Event event, Observation.Context context) { + this.eventDetected = true; + } + @Override public void onScopeOpened(Observation.Context context) { this.scopeOpened = true; diff --git a/micrometer-observation/src/test/java/io/micrometer/observation/FirstMatchingCompositeObservationHandlerTests.java b/micrometer-observation/src/test/java/io/micrometer/observation/FirstMatchingCompositeObservationHandlerTests.java index 868833f142..228a1be7f3 100644 --- a/micrometer-observation/src/test/java/io/micrometer/observation/FirstMatchingCompositeObservationHandlerTests.java +++ b/micrometer-observation/src/test/java/io/micrometer/observation/FirstMatchingCompositeObservationHandlerTests.java @@ -57,6 +57,16 @@ void should_run_on_error_only_for_first_matching_handler() { assertThat(this.matchingHandler.errored).isTrue(); } + @Test + void should_run_on_event_only_for_first_matching_handler() { + FirstMatchingCompositeObservationHandler firstMatchingHandler = new FirstMatchingCompositeObservationHandler( + new NotMatchingHandler(), this.matchingHandler, new NotMatchingHandler()); + + firstMatchingHandler.onEvent(new Observation.Event("testEvent"), null); + + assertThat(this.matchingHandler.eventDetected).isTrue(); + } + @Test void should_run_on_scope_opened_only_for_first_matching_handler() { FirstMatchingCompositeObservationHandler firstMatchingHandler = new FirstMatchingCompositeObservationHandler( @@ -113,6 +123,8 @@ static class MatchingHandler implements ObservationHandler boolean errored; + boolean eventDetected; + boolean scopeOpened; boolean scopeClosed; @@ -127,6 +139,11 @@ public void onError(Observation.Context context) { this.errored = true; } + @Override + public void onEvent(Observation.Event event, Observation.Context context) { + this.eventDetected = true; + } + @Override public void onScopeOpened(Observation.Context context) { this.scopeOpened = true; diff --git a/micrometer-test/src/main/java/io/micrometer/core/tck/MeterRegistryCompatibilityKit.java b/micrometer-test/src/main/java/io/micrometer/core/tck/MeterRegistryCompatibilityKit.java index 0e51b966c9..98b320ba87 100644 --- a/micrometer-test/src/main/java/io/micrometer/core/tck/MeterRegistryCompatibilityKit.java +++ b/micrometer-test/src/main/java/io/micrometer/core/tck/MeterRegistryCompatibilityKit.java @@ -23,7 +23,7 @@ import io.micrometer.core.instrument.distribution.DistributionStatisticConfig; import io.micrometer.core.instrument.distribution.ValueAtPercentile; import io.micrometer.core.instrument.internal.CumulativeHistogramLongTaskTimer; -import io.micrometer.core.instrument.observation.TimerObservationHandler; +import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; import io.micrometer.core.instrument.util.TimeUtils; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationRegistry; @@ -78,7 +78,7 @@ void setup() { // assigned here rather than at initialization so subclasses can use fields in // their registry() implementation registry = registry(); - observationRegistry.observationConfig().observationHandler(new TimerObservationHandler(registry)); + observationRegistry.observationConfig().observationHandler(new DefaultMeterObservationHandler(registry)); } @Test @@ -642,8 +642,11 @@ void recordWithObservation() { observation.lowCardinalityKeyValue("dynamicTag", "24"); clock(registry).add(1, TimeUnit.SECONDS); + observation.event(new Observation.Event("testEvent", "event for testing")); + LongTaskTimer longTaskTimer = registry.more().longTaskTimer("myObservation.active", "staticTag", "42"); assertThat(longTaskTimer.activeTasks()).isEqualTo(1); + observation.stop(); clock(registry).add(step()); @@ -652,6 +655,9 @@ void recordWithObservation() { Timer timer = registry.timer("myObservation", "error", "none", "staticTag", "42", "dynamicTag", "24"); assertAll(() -> assertEquals(1L, timer.count()), () -> assertEquals(1, timer.totalTime(TimeUnit.SECONDS), 1.0e-12)); + + Counter counter = registry.counter("myObservation.testEvent", "staticTag", "42", "dynamicTag", "24"); + assertThat(counter.count()).isEqualTo(1.0); } @Test @@ -661,6 +667,7 @@ void recordWithObservationAndScope() { try (Observation.Scope scope = observation.openScope()) { assertThat(scope.getCurrentObservation()).isSameAs(observation); clock(registry).add(10, TimeUnit.NANOSECONDS); + observation.event(new Observation.Event("testEvent", "event for testing")); } observation.stop(); clock(registry).add(step()); @@ -668,6 +675,9 @@ void recordWithObservationAndScope() { Timer timer = registry.timer("myObservation", "error", "none"); assertAll(() -> assertEquals(1L, timer.count()), () -> assertEquals(10, timer.totalTime(TimeUnit.NANOSECONDS), 1.0e-12)); + + Counter counter = registry.counter("myObservation.testEvent"); + assertThat(counter.count()).isEqualTo(1.0); } @Test diff --git a/samples/micrometer-samples-core/src/main/java/io/micrometer/core/samples/ObservationHandlerSample.java b/samples/micrometer-samples-core/src/main/java/io/micrometer/core/samples/ObservationHandlerSample.java index 23c5619f4e..caade43bbe 100644 --- a/samples/micrometer-samples-core/src/main/java/io/micrometer/core/samples/ObservationHandlerSample.java +++ b/samples/micrometer-samples-core/src/main/java/io/micrometer/core/samples/ObservationHandlerSample.java @@ -16,7 +16,7 @@ package io.micrometer.core.samples; import io.micrometer.common.KeyValues; -import io.micrometer.core.instrument.observation.TimerObservationHandler; +import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationPredicate; @@ -35,17 +35,19 @@ public class ObservationHandlerSample { public static void main(String[] args) throws InterruptedException { observationRegistry.observationConfig().observationHandler(new ObservationTextPublisher()) - .observationHandler(new TimerObservationHandler(registry)); + .observationHandler(new DefaultMeterObservationHandler(registry)); observationRegistry.observationConfig().keyValuesProvider(new CustomKeyValuesProvider()) .observationPredicate(new IgnoringObservationPredicate()); Observation observation = Observation .createNotStarted("sample.operation", new CustomContext(), observationRegistry) - .contextualName("CALL sampleOperation").keyValuesProvider(new CustomLocalKeyValuesProvider()) - .lowCardinalityKeyValue("a", "1").highCardinalityKeyValue("time", Instant.now().toString()).start(); + .contextualName("CALL sampleOperation").lowCardinalityKeyValue("a", "1") + .highCardinalityKeyValue("time", Instant.now().toString()) + .keyValuesProvider(new CustomLocalKeyValuesProvider()).start(); try (Observation.Scope scope = observation.openScope()) { Thread.sleep(1_000); + observation.event(new Observation.Event("custom.event", "Custom " + UUID.randomUUID())); observation.error(new IOException("simulated")); }