11 changed files with 241 additions and 261 deletions
@ -1,21 +0,0 @@
@@ -1,21 +0,0 @@
|
||||
package org.springframework.data.mongodb.observability; |
||||
|
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
|
||||
import io.micrometer.observation.ObservationRegistry; |
||||
|
||||
/** |
||||
* Class to configure needed beans for MongoDB + Micrometer. |
||||
* |
||||
* @since 3.0 |
||||
*/ |
||||
@Configuration |
||||
public class MongoMetricsConfiguration { |
||||
|
||||
@Bean |
||||
public MongoObservationCommandListener mongoObservationCommandListener(ObservationRegistry registry) { |
||||
return new MongoObservationCommandListener(registry); |
||||
} |
||||
|
||||
} |
||||
@ -1,152 +0,0 @@
@@ -1,152 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2022 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.data.mongodb.observability; |
||||
|
||||
import org.bson.BsonDocument; |
||||
import org.bson.BsonString; |
||||
import org.jetbrains.annotations.NotNull; |
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.springframework.data.mongodb.observability.MongoObservation.HighCardinalityCommandKeyNames; |
||||
import org.springframework.data.mongodb.observability.MongoObservation.LowCardinalityCommandKeyNames; |
||||
|
||||
import com.mongodb.RequestContext; |
||||
import com.mongodb.ServerAddress; |
||||
import com.mongodb.client.SynchronousContextProvider; |
||||
import com.mongodb.connection.ClusterId; |
||||
import com.mongodb.connection.ConnectionDescription; |
||||
import com.mongodb.connection.ServerId; |
||||
import com.mongodb.event.CommandFailedEvent; |
||||
import com.mongodb.event.CommandStartedEvent; |
||||
import com.mongodb.event.CommandSucceededEvent; |
||||
|
||||
import io.micrometer.core.instrument.MeterRegistry; |
||||
import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; |
||||
import io.micrometer.core.instrument.simple.SimpleMeterRegistry; |
||||
import io.micrometer.observation.Observation; |
||||
import io.micrometer.observation.ObservationRegistry; |
||||
import io.micrometer.tracing.Span; |
||||
import io.micrometer.tracing.test.simple.SimpleTracer; |
||||
import io.micrometer.tracing.test.simple.SpanAssert; |
||||
import io.micrometer.tracing.test.simple.TracerAssert; |
||||
|
||||
/** |
||||
* Series of test cases exercising {@link MongoObservationCommandListener} to ensure proper creation of {@link Span}s. |
||||
* |
||||
* @author Marcin Grzejszczak |
||||
* @author Greg Turnquist |
||||
*/ |
||||
class MongoObservationCommandListenerForTracingTests { |
||||
|
||||
SimpleTracer simpleTracer; |
||||
|
||||
MeterRegistry meterRegistry; |
||||
ObservationRegistry observationRegistry; |
||||
|
||||
MongoObservationCommandListener listener; |
||||
|
||||
@BeforeEach |
||||
void setup() { |
||||
|
||||
this.simpleTracer = new SimpleTracer(); |
||||
|
||||
this.meterRegistry = new SimpleMeterRegistry(); |
||||
this.observationRegistry = ObservationRegistry.create(); |
||||
this.observationRegistry.observationConfig().observationHandler(new DefaultMeterObservationHandler(meterRegistry)); |
||||
|
||||
this.listener = new MongoObservationCommandListener(observationRegistry); |
||||
} |
||||
|
||||
@Test |
||||
void successfullyCompletedCommandShouldCreateSpanWhenParentSampleInRequestContext() { |
||||
|
||||
// given
|
||||
RequestContext traceRequestContext = createTestRequestContextWithParentObservationAndStartIt(); |
||||
|
||||
// when
|
||||
commandStartedAndSucceeded(traceRequestContext); |
||||
|
||||
// then
|
||||
assertThatMongoSpanIsClientWithTags().hasIpThatIsBlank().hasPortThatIsNotSet(); |
||||
} |
||||
|
||||
|
||||
@Test |
||||
void commandWithErrorShouldCreateTimerWhenParentSampleInRequestContext() { |
||||
|
||||
// given
|
||||
RequestContext traceRequestContext = createTestRequestContextWithParentObservationAndStartIt(); |
||||
|
||||
// when
|
||||
listener.commandStarted(new CommandStartedEvent(traceRequestContext, 0, //
|
||||
new ConnectionDescription( //
|
||||
new ServerId( //
|
||||
new ClusterId("description"), //
|
||||
new ServerAddress("localhost", 1234))), //
|
||||
"database", "insert", //
|
||||
new BsonDocument("collection", new BsonString("user")))); |
||||
listener.commandFailed( //
|
||||
new CommandFailedEvent(traceRequestContext, 0, null, "insert", 0, new IllegalAccessException())); |
||||
|
||||
// then
|
||||
assertThatMongoSpanIsClientWithTags().assertThatThrowable().isInstanceOf(IllegalAccessException.class); |
||||
} |
||||
|
||||
/** |
||||
* Create a parent {@link Observation} then wrap it inside a {@link MapRequestContext}. |
||||
*/ |
||||
@NotNull |
||||
private RequestContext createTestRequestContextWithParentObservationAndStartIt() { |
||||
return ((SynchronousContextProvider) ContextProviderFactory.create(observationRegistry)).getContext(); |
||||
} |
||||
|
||||
/** |
||||
* Execute MongoDB's {@link com.mongodb.event.CommandListener#commandStarted(CommandStartedEvent)} and |
||||
* {@link com.mongodb.event.CommandListener#commandSucceeded(CommandSucceededEvent)} operations against the |
||||
* {@link MapRequestContext} in order to inject some test data. |
||||
* |
||||
* @param traceRequestContext |
||||
*/ |
||||
private void commandStartedAndSucceeded(RequestContext traceRequestContext) { |
||||
|
||||
listener.commandStarted(new CommandStartedEvent(traceRequestContext, 0, //
|
||||
new ConnectionDescription( //
|
||||
new ServerId( //
|
||||
new ClusterId("description"), //
|
||||
new ServerAddress("localhost", 1234))), //
|
||||
"database", "insert", //
|
||||
new BsonDocument("collection", new BsonString("user")))); |
||||
|
||||
listener.commandSucceeded(new CommandSucceededEvent(traceRequestContext, 0, null, "insert", null, 0)); |
||||
} |
||||
|
||||
/** |
||||
* Create a base MongoDB-based {@link SpanAssert} using Micrometer Tracing's fluent API. Other test methods can apply |
||||
* additional assertions. |
||||
* |
||||
* @return |
||||
*/ |
||||
private SpanAssert assertThatMongoSpanIsClientWithTags() { |
||||
|
||||
return TracerAssert.assertThat(simpleTracer).onlySpan() //
|
||||
.hasNameEqualTo("insert user") //
|
||||
.hasKindEqualTo(Span.Kind.CLIENT) //
|
||||
.hasRemoteServiceNameEqualTo("mongodb-database") //
|
||||
.hasTag(HighCardinalityCommandKeyNames.MONGODB_COMMAND.asString(), "insert") //
|
||||
.hasTag(LowCardinalityCommandKeyNames.MONGODB_COLLECTION.asString(), "user") //
|
||||
.hasTagWithKey(LowCardinalityCommandKeyNames.MONGODB_CLUSTER_ID.asString()); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue