Skip to content

Commit 1d3e754

Browse files
committed
Align tracing tag names with OpenTelemetry spec.
See #1321 Original pull request: #1322
1 parent d75da45 commit 1d3e754

File tree

12 files changed

+209
-215
lines changed

12 files changed

+209
-215
lines changed

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/observability/CassandraObservation.java

Lines changed: 97 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,6 @@ public String getName() {
3939
return "spring.data.cassandra.query";
4040
}
4141

42-
@Override
43-
public String getContextualName() {
44-
return "query";
45-
}
46-
4742
@Override
4843
public KeyName[] getLowCardinalityKeyNames() {
4944
return LowCardinalityKeyNames.values();
@@ -54,21 +49,77 @@ public KeyName[] getHighCardinalityKeyNames() {
5449
return HighCardinalityKeyNames.values();
5550
}
5651

57-
@Override
58-
public String getPrefix() {
59-
return "spring.data.cassandra.";
60-
}
6152
};
6253

6354
enum LowCardinalityKeyNames implements KeyName {
6455

56+
/**
57+
* Database system.
58+
*/
59+
DATABASE_SYSTEM {
60+
@Override
61+
public String asString() {
62+
return "db.system";
63+
}
64+
},
65+
66+
/**
67+
* Network transport.
68+
*/
69+
NET_TRANSPORT {
70+
@Override
71+
public String asString() {
72+
return "net.transport";
73+
}
74+
},
75+
76+
/**
77+
* Name of the database host.
78+
*/
79+
NET_PEER_NAME {
80+
@Override
81+
public String asString() {
82+
return "net.peer.name";
83+
}
84+
},
85+
86+
/**
87+
* Logical remote port number.
88+
*/
89+
NET_PEER_PORT {
90+
@Override
91+
public String asString() {
92+
return "net.peer.port";
93+
}
94+
},
95+
96+
/**
97+
* Cassandra peer address.
98+
*/
99+
NET_SOCK_PEER_ADDR {
100+
@Override
101+
public String asString() {
102+
return "net.sock.peer.addr";
103+
}
104+
},
105+
106+
/**
107+
* Cassandra peer port.
108+
*/
109+
NET_SOCK_PEER_PORT {
110+
@Override
111+
public String asString() {
112+
return "net.sock.peer.port";
113+
}
114+
},
115+
65116
/**
66117
* Name of the Cassandra keyspace.
67118
*/
68119
KEYSPACE_NAME {
69120
@Override
70121
public String asString() {
71-
return "spring.data.cassandra.keyspace";
122+
return "db.name";
72123
}
73124
},
74125

@@ -93,26 +144,57 @@ public String asString() {
93144
},
94145

95146
/**
96-
* Cassandra URL
147+
* The database operation.
97148
*/
98-
URL {
149+
DB_OPERATION {
99150
@Override
100151
public String asString() {
101-
return "spring.data.cassandra.url";
152+
return "db.operation";
102153
}
103154
},
104155

156+
COORDINATOR {
157+
@Override
158+
public String asString() {
159+
return "db.cassandra.coordinator.id";
160+
}
161+
},
162+
COORDINATOR_DC {
163+
@Override
164+
public String asString() {
165+
return "db.cassandra.coordinator.dc";
166+
}
167+
}
105168
}
106169

107170
enum HighCardinalityKeyNames implements KeyName {
108171

109172
/**
110173
* A key-value containing Cassandra CQL.
111174
*/
112-
CQL_TAG {
175+
DB_STATEMENT {
176+
@Override
177+
public String asString() {
178+
return "db.statement";
179+
}
180+
},
181+
182+
PAGE_SIZE {
183+
@Override
184+
public String asString() {
185+
return "db.cassandra.page_size";
186+
}
187+
},
188+
CONSISTENCY_LEVEL {
189+
@Override
190+
public String asString() {
191+
return "db.cassandra.consistency_level";
192+
}
193+
},
194+
IDEMPOTENCE {
113195
@Override
114196
public String asString() {
115-
return "spring.data.cassandra.cql";
197+
return "db.cassandra.idempotence";
116198
}
117199
},
118200

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/observability/CassandraObservationContext.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@
1515
*/
1616
package org.springframework.data.cassandra.observability;
1717

18+
import org.springframework.lang.Nullable;
19+
1820
import com.datastax.oss.driver.api.core.CqlSession;
1921
import com.datastax.oss.driver.api.core.cql.Statement;
22+
import com.datastax.oss.driver.api.core.metadata.Node;
2023

2124
import io.micrometer.observation.Observation;
2225
import io.micrometer.observation.transport.Kind;
@@ -38,6 +41,8 @@ public class CassandraObservationContext extends SenderContext<Object> {
3841
private final String sessionName;
3942
private final String keyspaceName;
4043

44+
private volatile @Nullable Node node;
45+
4146
public CassandraObservationContext(Statement<?> statement, String remoteServiceName, boolean prepare,
4247
String methodName, String sessionName, String keyspaceName) {
4348

@@ -71,4 +76,13 @@ public String getSessionName() {
7176
public String getKeyspaceName() {
7277
return keyspaceName;
7378
}
79+
80+
public void setNode(Node node) {
81+
this.node = node;
82+
}
83+
84+
@Nullable
85+
public Node getNode() {
86+
return node;
87+
}
7488
}

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/observability/CqlSessionObservationInterceptor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013-2022 the original author or authors.
2+
* Copyright 2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -39,7 +39,7 @@
3939
* @author Mark Paluch
4040
* @author Marcin Grzejszczak
4141
* @author Greg Turnquist
42-
* @since 4.0.0
42+
* @since 4.0
4343
*/
4444
final class CqlSessionObservationInterceptor implements MethodInterceptor {
4545

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/observability/DefaultCassandraObservationConvention.java

Lines changed: 67 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013-2022 the original author or authors.
2+
* Copyright 2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,17 +15,22 @@
1515
*/
1616
package org.springframework.data.cassandra.observability;
1717

18+
import java.net.InetSocketAddress;
1819
import java.util.StringJoiner;
1920

2021
import org.springframework.data.cassandra.observability.CassandraObservation.HighCardinalityKeyNames;
2122
import org.springframework.data.cassandra.observability.CassandraObservation.LowCardinalityKeyNames;
23+
import org.springframework.lang.Nullable;
2224
import org.springframework.util.StringUtils;
2325

26+
import com.datastax.oss.driver.api.core.ConsistencyLevel;
2427
import com.datastax.oss.driver.api.core.cql.BatchStatement;
2528
import com.datastax.oss.driver.api.core.cql.BatchableStatement;
2629
import com.datastax.oss.driver.api.core.cql.BoundStatement;
2730
import com.datastax.oss.driver.api.core.cql.SimpleStatement;
2831
import com.datastax.oss.driver.api.core.cql.Statement;
32+
import com.datastax.oss.driver.api.core.metadata.EndPoint;
33+
import com.datastax.oss.driver.api.core.metadata.Node;
2934

3035
import io.micrometer.common.KeyValues;
3136

@@ -41,26 +46,79 @@ class DefaultCassandraObservationConvention implements CassandraObservationConve
4146
@Override
4247
public KeyValues getLowCardinalityKeyValues(CassandraObservationContext context) {
4348

44-
KeyValues keyValues = KeyValues.of(LowCardinalityKeyNames.SESSION_NAME.withValue(context.getSessionName()),
49+
String dbOperation = context.isPrepare() ? "PREPARE" : getOperationName(getCql(context.getStatement()), "");
50+
51+
KeyValues keyValues = KeyValues.of(LowCardinalityKeyNames.DATABASE_SYSTEM.withValue("cassandra"),
4552
LowCardinalityKeyNames.KEYSPACE_NAME.withValue(context.getKeyspaceName()),
46-
LowCardinalityKeyNames.METHOD_NAME.withValue(context.getMethodName()));
53+
LowCardinalityKeyNames.SESSION_NAME.withValue(context.getSessionName()),
54+
LowCardinalityKeyNames.METHOD_NAME.withValue(context.getMethodName()),
55+
LowCardinalityKeyNames.DB_OPERATION.withValue(dbOperation));
56+
57+
Node node = context.getNode();
58+
59+
if (node == null) {
60+
node = context.getStatement().getNode();
61+
}
62+
63+
if (node != null) {
64+
65+
EndPoint endPoint = node.getEndPoint();
4766

48-
if (context.getStatement().getNode() != null) {
49-
keyValues = keyValues.and(
50-
LowCardinalityKeyNames.URL.withValue(context.getStatement().getNode().getEndPoint().resolve().toString()));
67+
keyValues = keyValues.and(LowCardinalityKeyNames.COORDINATOR.withValue("" + node.getHostId()),
68+
LowCardinalityKeyNames.COORDINATOR_DC.withValue("" + node.getDatacenter()));
69+
70+
keyValues.and(LowCardinalityKeyNames.NET_PEER_NAME.withValue(endPoint.toString()));
71+
InetSocketAddress socketAddress = tryGetSocketAddress(endPoint);
72+
73+
if (socketAddress != null) {
74+
75+
keyValues = keyValues.and(LowCardinalityKeyNames.NET_TRANSPORT.withValue("IP.TCP"),
76+
LowCardinalityKeyNames.NET_SOCK_PEER_ADDR.withValue(socketAddress.getHostString()),
77+
LowCardinalityKeyNames.NET_SOCK_PEER_PORT.withValue("" + socketAddress.getPort()));
78+
}
5179
}
5280

5381
return keyValues;
5482
}
5583

5684
@Override
5785
public KeyValues getHighCardinalityKeyValues(CassandraObservationContext context) {
58-
return KeyValues.of(HighCardinalityKeyNames.CQL_TAG.withValue(getCql(context.getStatement())));
86+
87+
Statement<?> statement = context.getStatement();
88+
89+
KeyValues keyValues = KeyValues.of(HighCardinalityKeyNames.DB_STATEMENT.withValue(getCql(statement)),
90+
HighCardinalityKeyNames.PAGE_SIZE.withValue("" + statement.getPageSize()));
91+
92+
Boolean idempotent = statement.isIdempotent();
93+
if (idempotent != null) {
94+
keyValues = keyValues
95+
.and(HighCardinalityKeyNames.IDEMPOTENCE.withValue(idempotent ? "idempotent" : "non-idempotent"));
96+
}
97+
98+
ConsistencyLevel consistencyLevel = statement.getConsistencyLevel();
99+
if (consistencyLevel != null) {
100+
keyValues = keyValues.and(HighCardinalityKeyNames.CONSISTENCY_LEVEL.withValue("" + consistencyLevel.name()));
101+
}
102+
103+
return keyValues;
104+
}
105+
106+
@Nullable
107+
private InetSocketAddress tryGetSocketAddress(EndPoint endPoint) {
108+
109+
try {
110+
if (endPoint.resolve()instanceof InetSocketAddress inet) {
111+
return inet;
112+
}
113+
114+
} catch (RuntimeException e) {}
115+
116+
return null;
59117
}
60118

61119
@Override
62120
public String getContextualName(CassandraObservationContext context) {
63-
return (context.isPrepare() ? "PREPARE: " : "") + getSpanName(getCql(context.getStatement()), "");
121+
return (context.isPrepare() ? "PREPARE: " : "") + getOperationName(getCql(context.getStatement()), "");
64122
}
65123

66124
/**
@@ -116,7 +174,7 @@ private static String getQuery(Statement<?> statement) {
116174
* @param defaultName if there's no query
117175
* @return span name
118176
*/
119-
public String getSpanName(String cql, String defaultName) {
177+
public String getOperationName(String cql, String defaultName) {
120178

121179
if (StringUtils.hasText(cql) && cql.indexOf(' ') > -1) {
122180
return cql.substring(0, cql.indexOf(' '));

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/observability/ObservableCqlSessionFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013-2022 the original author or authors.
2+
* Copyright 2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/observability/ObservableReactiveSessionFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013-2022 the original author or authors.
2+
* Copyright 2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.

0 commit comments

Comments
 (0)