Skip to content

Commit 2d63d60

Browse files
committed
Align conventions with OpenTelemetry spec.
See: spring-projects#4216
1 parent 5007e68 commit 2d63d60

11 files changed

+241
-261
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/ContextProviderFactory.java

-4
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131

3232
import io.micrometer.observation.Observation;
3333
import io.micrometer.observation.ObservationRegistry;
34-
import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor;
3534
import reactor.core.CoreSubscriber;
3635

3736
/**
@@ -105,9 +104,6 @@ public RequestContext getContext(Subscriber<?> subscriber) {
105104

106105
Map<Object, Object> map = cs.currentContext().stream()
107106
.collect(Collectors.toConcurrentMap(Entry::getKey, Entry::getValue));
108-
if (map.containsKey(ObservationThreadLocalAccessor.KEY)) {
109-
map.put(Observation.class, map.get(ObservationThreadLocalAccessor.KEY));
110-
}
111107

112108
return new MapRequestContext(map);
113109
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/DefaultMongoHandlerObservationConvention.java

+60-31
Original file line numberDiff line numberDiff line change
@@ -15,76 +15,105 @@
1515
*/
1616
package org.springframework.data.mongodb.observability;
1717

18-
import org.springframework.data.mongodb.observability.MongoObservation.HighCardinalityCommandKeyNames;
18+
import java.net.InetSocketAddress;
19+
1920
import org.springframework.data.mongodb.observability.MongoObservation.LowCardinalityCommandKeyNames;
20-
import org.springframework.lang.Nullable;
2121
import org.springframework.util.ObjectUtils;
2222

23+
import com.mongodb.ConnectionString;
24+
import com.mongodb.ServerAddress;
2325
import com.mongodb.connection.ConnectionDescription;
2426
import com.mongodb.connection.ConnectionId;
2527
import com.mongodb.event.CommandStartedEvent;
2628

27-
import io.micrometer.common.KeyValue;
2829
import io.micrometer.common.KeyValues;
2930

3031
/**
3132
* Default {@link MongoHandlerObservationConvention} implementation.
3233
*
3334
* @author Greg Turnquist
34-
* @since 4
35+
* @author Mark Paluch
36+
* @since 4.0
3537
*/
3638
class DefaultMongoHandlerObservationConvention implements MongoHandlerObservationConvention {
3739

3840
@Override
3941
public KeyValues getLowCardinalityKeyValues(MongoHandlerContext context) {
4042

41-
KeyValues keyValues = KeyValues.empty();
43+
KeyValues keyValues = KeyValues.of(LowCardinalityCommandKeyNames.DB_SYSTEM.withValue("mongodb"),
44+
LowCardinalityCommandKeyNames.MONGODB_COMMAND.withValue(context.getCommandName()));
45+
46+
ConnectionString connectionString = context.getConnectionString();
47+
if (connectionString != null) {
48+
49+
keyValues = keyValues
50+
.and(LowCardinalityCommandKeyNames.DB_CONNECTION_STRING.withValue(connectionString.getConnectionString()));
51+
52+
String user = connectionString.getUsername();
53+
54+
if (!ObjectUtils.isEmpty(user)) {
55+
keyValues = keyValues.and(LowCardinalityCommandKeyNames.DB_USER.withValue(user));
56+
}
57+
58+
}
59+
60+
if (!ObjectUtils.isEmpty(context.getDatabaseName())) {
61+
keyValues = keyValues.and(LowCardinalityCommandKeyNames.DB_NAME.withValue(context.getDatabaseName()));
62+
}
4263

4364
if (!ObjectUtils.isEmpty(context.getCollectionName())) {
4465
keyValues = keyValues
4566
.and(LowCardinalityCommandKeyNames.MONGODB_COLLECTION.withValue(context.getCollectionName()));
4667
}
4768

48-
KeyValue connectionTag = connectionTag(context.getCommandStartedEvent());
49-
if (connectionTag != null) {
50-
keyValues = keyValues.and(connectionTag);
69+
ConnectionDescription connectionDescription = context.getCommandStartedEvent().getConnectionDescription();
70+
71+
if (connectionDescription != null) {
72+
73+
ServerAddress serverAddress = connectionDescription.getServerAddress();
74+
75+
if (serverAddress != null) {
76+
77+
keyValues = keyValues.and(LowCardinalityCommandKeyNames.NET_TRANSPORT.withValue("IP.TCP"),
78+
LowCardinalityCommandKeyNames.NET_PEER_NAME.withValue(serverAddress.getHost()),
79+
LowCardinalityCommandKeyNames.NET_PEER_PORT.withValue("" + serverAddress.getPort()));
80+
81+
InetSocketAddress socketAddress = serverAddress.getSocketAddress();
82+
83+
if (socketAddress != null) {
84+
85+
keyValues = keyValues.and(
86+
LowCardinalityCommandKeyNames.NET_SOCK_PEER_ADDR.withValue(socketAddress.getHostName()),
87+
LowCardinalityCommandKeyNames.NET_SOCK_PEER_PORT.withValue("" + socketAddress.getPort()));
88+
}
89+
}
90+
91+
ConnectionId connectionId = connectionDescription.getConnectionId();
92+
if (connectionId != null) {
93+
keyValues = keyValues.and(LowCardinalityCommandKeyNames.MONGODB_CLUSTER_ID
94+
.withValue(connectionId.getServerId().getClusterId().getValue()));
95+
}
5196
}
5297

5398
return keyValues;
5499
}
55100

56101
@Override
57102
public KeyValues getHighCardinalityKeyValues(MongoHandlerContext context) {
58-
59-
return KeyValues.of(
60-
HighCardinalityCommandKeyNames.MONGODB_COMMAND.withValue(context.getCommandStartedEvent().getCommandName()));
103+
return KeyValues.empty();
61104
}
62105

63106
@Override
64107
public String getContextualName(MongoHandlerContext context) {
65-
return context.getContextualName();
66-
}
67-
68-
/**
69-
* Extract connection details for a MongoDB connection into a {@link KeyValue}.
70-
*
71-
* @param event
72-
* @return
73-
*/
74-
@Nullable
75-
private static KeyValue connectionTag(CommandStartedEvent event) {
76108

77-
ConnectionDescription connectionDescription = event.getConnectionDescription();
78-
79-
if (connectionDescription != null) {
109+
String collectionName = context.getCollectionName();
110+
CommandStartedEvent commandStartedEvent = context.getCommandStartedEvent();
80111

81-
ConnectionId connectionId = connectionDescription.getConnectionId();
82-
if (connectionId != null) {
83-
return LowCardinalityCommandKeyNames.MONGODB_CLUSTER_ID
84-
.withValue(connectionId.getServerId().getClusterId().getValue());
85-
}
112+
if (ObjectUtils.isEmpty(collectionName)) {
113+
return commandStartedEvent.getCommandName();
86114
}
87115

88-
return null;
116+
return collectionName + "." + commandStartedEvent.getCommandName();
89117
}
118+
90119
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/MongoHandlerContext.java

+22-11
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.bson.BsonValue;
2424
import org.springframework.lang.Nullable;
2525

26+
import com.mongodb.ConnectionString;
2627
import com.mongodb.RequestContext;
2728
import com.mongodb.event.CommandFailedEvent;
2829
import com.mongodb.event.CommandStartedEvent;
@@ -37,9 +38,10 @@
3738
*
3839
* @author Marcin Grzejszczak
3940
* @author Greg Turnquist
40-
* @since 4.0.0
41+
* @author Mark Paluch
42+
* @since 4.0
4143
*/
42-
public class MongoHandlerContext extends SenderContext<Object> {
44+
class MongoHandlerContext extends SenderContext<Object> {
4345

4446
/**
4547
* @see <a href=
@@ -51,15 +53,19 @@ public class MongoHandlerContext extends SenderContext<Object> {
5153
"insert", "update", "collMod", "compact", "convertToCapped", "create", "createIndexes", "drop", "dropIndexes",
5254
"killCursors", "listIndexes", "reIndex"));
5355

56+
private final @Nullable ConnectionString connectionString;
5457
private final CommandStartedEvent commandStartedEvent;
5558
private final RequestContext requestContext;
5659
private final String collectionName;
5760

5861
private CommandSucceededEvent commandSucceededEvent;
5962
private CommandFailedEvent commandFailedEvent;
6063

61-
public MongoHandlerContext(CommandStartedEvent commandStartedEvent, RequestContext requestContext) {
64+
public MongoHandlerContext(@Nullable ConnectionString connectionString, CommandStartedEvent commandStartedEvent,
65+
RequestContext requestContext) {
66+
6267
super((carrier, key, value) -> {}, Kind.CLIENT);
68+
this.connectionString = connectionString;
6369
this.commandStartedEvent = commandStartedEvent;
6470
this.requestContext = requestContext;
6571
this.collectionName = getCollectionName(commandStartedEvent);
@@ -73,17 +79,21 @@ public RequestContext getRequestContext() {
7379
return this.requestContext;
7480
}
7581

82+
public String getDatabaseName() {
83+
return commandStartedEvent.getDatabaseName();
84+
}
85+
7686
public String getCollectionName() {
7787
return this.collectionName;
7888
}
7989

80-
public String getContextualName() {
81-
82-
if (this.collectionName == null) {
83-
return this.commandStartedEvent.getCommandName();
84-
}
90+
public String getCommandName() {
91+
return commandStartedEvent.getCommandName();
92+
}
8593

86-
return this.commandStartedEvent.getCommandName() + " " + this.collectionName;
94+
@Nullable
95+
public ConnectionString getConnectionString() {
96+
return connectionString;
8797
}
8898

8999
public void setCommandSucceededEvent(CommandSucceededEvent commandSucceededEvent) {
@@ -116,7 +126,7 @@ private static String getCollectionName(CommandStartedEvent event) {
116126
}
117127

118128
// Some other commands, like getMore, have a field like {"collection": collectionName}.
119-
return getNonEmptyBsonString(command.get("collection"));
129+
return command == null ? "" : getNonEmptyBsonString(command.get("collection"));
120130
}
121131

122132
/**
@@ -125,7 +135,7 @@ private static String getCollectionName(CommandStartedEvent event) {
125135
* @return trimmed string from {@code bsonValue} or null if the trimmed string was empty or the value wasn't a string
126136
*/
127137
@Nullable
128-
private static String getNonEmptyBsonString(BsonValue bsonValue) {
138+
private static String getNonEmptyBsonString(@Nullable BsonValue bsonValue) {
129139

130140
if (bsonValue == null || !bsonValue.isString()) {
131141
return null;
@@ -135,4 +145,5 @@ private static String getNonEmptyBsonString(BsonValue bsonValue) {
135145

136146
return stringValue.isEmpty() ? null : stringValue;
137147
}
148+
138149
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/observability/MongoMetricsConfiguration.java

-21
This file was deleted.

0 commit comments

Comments
 (0)