Skip to content

Commit aa2128f

Browse files
committed
Tracing: added OpenTelemetry implementation
Added TracingInfo and TracingInfoFactory implementations in separate driver-opentelemetry module.
1 parent eaecf47 commit aa2128f

File tree

4 files changed

+464
-0
lines changed

4 files changed

+464
-0
lines changed

driver-opentelemetry/pom.xml

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<!--
2+
3+
Copyright DataStax, Inc.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
17+
-->
18+
<!--
19+
Copyright (C) 2021 ScyllaDB
20+
Modified by ScyllaDB
21+
-->
22+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
23+
24+
<modelVersion>4.0.0</modelVersion>
25+
26+
<parent>
27+
<groupId>com.scylladb</groupId>
28+
<artifactId>scylla-driver-parent</artifactId>
29+
<version>3.11.2.1-SNAPSHOT</version>
30+
</parent>
31+
32+
<artifactId>scylla-driver-opentelemetry</artifactId>
33+
<name>Java Driver for Scylla and Apache Cassandra - OpenTelemetry integration</name>
34+
<description>An extension of Java Driver for Scylla and Apache Cassandra by adding
35+
functionality of creating traces and spans in OpenTelemetry format.
36+
</description>
37+
38+
<dependencyManagement>
39+
40+
<dependencies>
41+
42+
<dependency>
43+
<groupId>io.opentelemetry</groupId>
44+
<artifactId>opentelemetry-bom</artifactId>
45+
<version>1.9.1</version>
46+
<type>pom</type>
47+
<scope>import</scope>
48+
</dependency>
49+
50+
</dependencies>
51+
52+
</dependencyManagement>
53+
54+
<dependencies>
55+
56+
<!-- driver dependencies -->
57+
58+
<dependency>
59+
<groupId>com.scylladb</groupId>
60+
<artifactId>scylla-driver-core</artifactId>
61+
</dependency>
62+
63+
<!-- OpenTelemetry -->
64+
65+
<dependency>
66+
<groupId>io.opentelemetry</groupId>
67+
<artifactId>opentelemetry-api</artifactId>
68+
<version>1.9.1</version>
69+
</dependency>
70+
71+
<!-- tests -->
72+
73+
<dependency>
74+
<groupId>com.scylladb</groupId>
75+
<artifactId>scylla-driver-core</artifactId>
76+
<type>test-jar</type>
77+
<scope>test</scope>
78+
</dependency>
79+
80+
<dependency>
81+
<groupId>io.opentelemetry</groupId>
82+
<artifactId>opentelemetry-sdk</artifactId>
83+
<scope>test</scope>
84+
</dependency>
85+
86+
<dependency>
87+
<groupId>org.apache.commons</groupId>
88+
<artifactId>commons-exec</artifactId>
89+
<scope>test</scope>
90+
</dependency>
91+
92+
<dependency>
93+
<groupId>org.testng</groupId>
94+
<artifactId>testng</artifactId>
95+
<scope>test</scope>
96+
</dependency>
97+
98+
<dependency>
99+
<groupId>org.slf4j</groupId>
100+
<artifactId>slf4j-log4j12</artifactId>
101+
<scope>test</scope>
102+
</dependency>
103+
104+
</dependencies>
105+
106+
<build>
107+
<plugins>
108+
109+
<plugin>
110+
<artifactId>maven-compiler-plugin</artifactId>
111+
<configuration>
112+
<source>1.8</source>
113+
<target>1.8</target>
114+
</configuration>
115+
</plugin>
116+
117+
<!-- Disable check-jdk6 check for this submodule. -->
118+
<plugin>
119+
<groupId>org.codehaus.mojo</groupId>
120+
<artifactId>animal-sniffer-maven-plugin</artifactId>
121+
<version>1.15</version>
122+
<executions>
123+
<execution>
124+
<id>check-jdk6</id>
125+
<phase>process-classes</phase>
126+
<goals>
127+
<goal>check</goal>
128+
</goals>
129+
<configuration>
130+
<skip>true</skip>
131+
</configuration>
132+
</execution>
133+
<execution>
134+
<id>check-jdk8</id>
135+
<goals>
136+
<goal>check</goal>
137+
</goals>
138+
<configuration>
139+
<skip>true</skip>
140+
</configuration>
141+
</execution>
142+
</executions>
143+
</plugin>
144+
145+
</plugins>
146+
147+
</build>
148+
149+
</project>
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
/*
2+
* Copyright (C) 2021 ScyllaDB
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.datastax.driver.opentelemetry;
18+
19+
import com.datastax.driver.core.ConsistencyLevel;
20+
import com.datastax.driver.core.policies.LoadBalancingPolicy;
21+
import com.datastax.driver.core.policies.RetryPolicy;
22+
import com.datastax.driver.core.policies.SpeculativeExecutionPolicy;
23+
import com.datastax.driver.core.tracing.PrecisionLevel;
24+
import com.datastax.driver.core.tracing.TracingInfo;
25+
import io.opentelemetry.api.trace.Span;
26+
import io.opentelemetry.api.trace.Tracer;
27+
import io.opentelemetry.context.Context;
28+
import java.net.InetAddress;
29+
30+
public class OpenTelemetryTracingInfo implements TracingInfo {
31+
private Span span;
32+
private final Tracer tracer;
33+
private final Context context;
34+
private boolean tracingStarted;
35+
private final PrecisionLevel precision;
36+
37+
protected OpenTelemetryTracingInfo(Tracer tracer, Context context, PrecisionLevel precision) {
38+
this.tracer = tracer;
39+
this.context = context;
40+
this.precision = precision;
41+
this.tracingStarted = false;
42+
}
43+
44+
public Tracer getTracer() {
45+
return tracer;
46+
}
47+
48+
public Context getContext() {
49+
return context.with(span);
50+
}
51+
52+
private void assertStarted() {
53+
assert tracingStarted : "TracingInfo.setStartTime must be called before any other method";
54+
}
55+
56+
public PrecisionLevel getPrecision() {
57+
return precision;
58+
}
59+
60+
@Override
61+
public void setNameAndStartTime(String name) {
62+
assert !tracingStarted : "TracingInfo.setStartTime may only be called once.";
63+
tracingStarted = true;
64+
span = tracer.spanBuilder(name).setParent(context).startSpan();
65+
}
66+
67+
@Override
68+
public void setConsistencyLevel(ConsistencyLevel consistency) {
69+
assertStarted();
70+
span.setAttribute("db.scylla.consistency_level", consistency.toString());
71+
}
72+
73+
public void setStatement(String statement) {
74+
assertStarted();
75+
if (currentPrecisionLevelIsAtLeast(PrecisionLevel.FULL)) {
76+
span.setAttribute("db.scylla.statement", statement);
77+
}
78+
}
79+
80+
public void setHostname(String hostname) {
81+
assertStarted();
82+
if (currentPrecisionLevelIsAtLeast(PrecisionLevel.FULL)) {
83+
span.setAttribute("net.peer.name", hostname);
84+
}
85+
}
86+
87+
@Override
88+
public void setStatementType(String statementType) {
89+
assertStarted();
90+
span.setAttribute("db.scylla.statement_type", statementType);
91+
}
92+
93+
@Override
94+
public void setRetryPolicy(RetryPolicy retryPolicy) {
95+
assertStarted();
96+
span.setAttribute("db.scylla.retry_policy", retryPolicy.getClass().getSimpleName());
97+
}
98+
99+
@Override
100+
public void setLoadBalancingPolicy(LoadBalancingPolicy loadBalancingPolicy) {
101+
assertStarted();
102+
span.setAttribute(
103+
"db.scylla.load_balancing_policy", loadBalancingPolicy.getClass().getSimpleName());
104+
}
105+
106+
@Override
107+
public void setSpeculativeExecutionPolicy(SpeculativeExecutionPolicy speculativeExecutionPolicy) {
108+
assertStarted();
109+
span.setAttribute(
110+
"db.scylla.speculative_execution_policy",
111+
speculativeExecutionPolicy.getClass().getSimpleName());
112+
}
113+
114+
@Override
115+
public void setBatchSize(int batchSize) {
116+
assertStarted();
117+
span.setAttribute("db.scylla.batch_size", String.valueOf(batchSize));
118+
}
119+
120+
@Override
121+
public void setAttemptCount(int attemptCount) {
122+
assertStarted();
123+
span.setAttribute("db.scylla.attempt_count", String.valueOf(attemptCount));
124+
}
125+
126+
@Override
127+
public void setShardID(int shardID) {
128+
assertStarted();
129+
span.setAttribute("db.scylla.shard_id", String.valueOf(shardID));
130+
}
131+
132+
@Override
133+
public void setPeerName(String peerName) {
134+
assertStarted();
135+
span.setAttribute("net.peer.name", peerName);
136+
}
137+
138+
@Override
139+
public void setPeerIP(InetAddress peerIP) {
140+
assertStarted();
141+
span.setAttribute("net.peer.ip", peerIP.getHostAddress());
142+
}
143+
144+
@Override
145+
public void setPeerPort(int peerPort) {
146+
assertStarted();
147+
span.setAttribute("net.peer.port", String.valueOf(peerPort));
148+
}
149+
150+
@Override
151+
public void setFetchSize(int fetchSize) {
152+
assertStarted();
153+
span.setAttribute("db.scylla.fetch_size", Integer.toString(fetchSize));
154+
}
155+
156+
@Override
157+
public void setHasMorePages(boolean hasMorePages) {
158+
assertStarted();
159+
span.setAttribute("db.scylla.has_more_pages", Boolean.toString(hasMorePages));
160+
}
161+
162+
@Override
163+
public void setRowsCount(int rowsCount) {
164+
assertStarted();
165+
span.setAttribute("db.scylla.rows_count", Integer.toString(rowsCount));
166+
}
167+
168+
@Override
169+
public void setStatement(String statement, int limit) {
170+
assertStarted();
171+
if (currentPrecisionLevelIsAtLeast(PrecisionLevel.FULL)) {
172+
if (statement.length() > limit) statement = statement.substring(0, limit);
173+
span.setAttribute("db.scylla.statement", statement);
174+
}
175+
}
176+
177+
@Override
178+
public void setKeyspace(String keyspace) {
179+
assertStarted();
180+
span.setAttribute("db.scylla.keyspace", keyspace);
181+
}
182+
183+
@Override
184+
public void setPartitionKey(String partitionKey) {
185+
assertStarted();
186+
span.setAttribute("db.scylla.partition_key", partitionKey);
187+
}
188+
189+
@Override
190+
public void setTable(String table) {
191+
assertStarted();
192+
span.setAttribute("db.scylla.table", table);
193+
}
194+
195+
@Override
196+
public void setOperationType(String operationType) {
197+
assertStarted();
198+
span.setAttribute("db.operation", operationType);
199+
}
200+
201+
@Override
202+
public void setReplicas(String replicas) {
203+
assertStarted();
204+
span.setAttribute("db.scylla.replicas", replicas);
205+
}
206+
207+
private io.opentelemetry.api.trace.StatusCode mapStatusCode(StatusCode code) {
208+
switch (code) {
209+
case OK:
210+
return io.opentelemetry.api.trace.StatusCode.OK;
211+
case ERROR:
212+
return io.opentelemetry.api.trace.StatusCode.ERROR;
213+
}
214+
return null;
215+
}
216+
217+
@Override
218+
public void recordException(Exception exception) {
219+
assertStarted();
220+
span.recordException(exception);
221+
}
222+
223+
@Override
224+
public void setStatus(StatusCode code, String description) {
225+
assertStarted();
226+
span.setStatus(mapStatusCode(code), description);
227+
}
228+
229+
@Override
230+
public void setStatus(StatusCode code) {
231+
assertStarted();
232+
span.setStatus(mapStatusCode(code));
233+
}
234+
235+
@Override
236+
public void tracingFinished() {
237+
assertStarted();
238+
span.end();
239+
}
240+
241+
private boolean currentPrecisionLevelIsAtLeast(PrecisionLevel requiredLevel) {
242+
return requiredLevel.compareTo(precision) <= 0;
243+
}
244+
}

0 commit comments

Comments
 (0)