Skip to content

Commit 142b9af

Browse files
committed
Tracing: added OpenTelemetry implementation.
Added TracingInfo and TracingInfoFactory implementations in separate driver-opentelemetry module.
1 parent 0ba6d87 commit 142b9af

File tree

4 files changed

+450
-0
lines changed

4 files changed

+450
-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: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
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.tracing.PrecisionLevel;
23+
import com.datastax.driver.core.tracing.TracingInfo;
24+
import io.opentelemetry.api.trace.Span;
25+
import io.opentelemetry.api.trace.Tracer;
26+
import io.opentelemetry.context.Context;
27+
import java.net.InetAddress;
28+
29+
public class OpenTelemetryTracingInfo implements TracingInfo {
30+
private Span span;
31+
private final Tracer tracer;
32+
private final Context context;
33+
private boolean tracingStarted;
34+
private final PrecisionLevel precision;
35+
36+
protected OpenTelemetryTracingInfo(Tracer tracer, Context context, PrecisionLevel precision) {
37+
this.tracer = tracer;
38+
this.context = context;
39+
this.precision = precision;
40+
this.tracingStarted = false;
41+
}
42+
43+
public Tracer getTracer() {
44+
return tracer;
45+
}
46+
47+
public Context getContext() {
48+
return context.with(span);
49+
}
50+
51+
private void assertStarted() {
52+
assert tracingStarted : "TracingInfo.setStartTime must be called before any other method";
53+
}
54+
55+
public PrecisionLevel getPrecision() {
56+
return precision;
57+
}
58+
59+
@Override
60+
public void setNameAndStartTime(String name) {
61+
assert !tracingStarted : "TracingInfo.setStartTime may only be called once.";
62+
tracingStarted = true;
63+
span = tracer.spanBuilder(name).setParent(context).startSpan();
64+
}
65+
66+
@Override
67+
public void setConsistencyLevel(ConsistencyLevel consistency) {
68+
assertStarted();
69+
span.setAttribute("db.scylla.consistency_level", consistency.toString());
70+
}
71+
72+
public void setStatement(String statement) {
73+
assertStarted();
74+
if (currentPrecisionLevelIsAtLeast(PrecisionLevel.FULL)) {
75+
span.setAttribute("db.scylla.statement", statement);
76+
}
77+
}
78+
79+
public void setHostname(String hostname) {
80+
assertStarted();
81+
if (currentPrecisionLevelIsAtLeast(PrecisionLevel.FULL)) {
82+
span.setAttribute("net.peer.name", hostname);
83+
}
84+
}
85+
86+
@Override
87+
public void setStatementType(String statementType) {
88+
assertStarted();
89+
span.setAttribute("db.scylla.statement_type", statementType);
90+
}
91+
92+
@Override
93+
public void setRetryPolicy(RetryPolicy retryPolicy) {
94+
assertStarted();
95+
span.setAttribute("db.scylla.retry_policy", retryPolicy.getClass().getSimpleName());
96+
}
97+
98+
@Override
99+
public void setLoadBalancingPolicy(LoadBalancingPolicy loadBalancingPolicy) {
100+
assertStarted();
101+
span.setAttribute(
102+
"db.scylla.load_balancing_policy", loadBalancingPolicy.getClass().getSimpleName());
103+
}
104+
105+
@Override
106+
public void setBatchSize(int batchSize) {
107+
assertStarted();
108+
span.setAttribute("db.scylla.batch_size", String.valueOf(batchSize));
109+
}
110+
111+
@Override
112+
public void setRetryCount(int retryCount) {
113+
assertStarted();
114+
span.setAttribute("db.scylla.retry_count", String.valueOf(retryCount));
115+
}
116+
117+
@Override
118+
public void setShardID(int shardID) {
119+
assertStarted();
120+
span.setAttribute("db.scylla.shard_id", String.valueOf(shardID));
121+
}
122+
123+
@Override
124+
public void setPeerName(String peerName) {
125+
assertStarted();
126+
span.setAttribute("net.peer.name", peerName);
127+
}
128+
129+
@Override
130+
public void setPeerIP(InetAddress peerIP) {
131+
assertStarted();
132+
span.setAttribute("net.peer.ip", peerIP.getHostAddress());
133+
}
134+
135+
@Override
136+
public void setPeerPort(int peerPort) {
137+
assertStarted();
138+
span.setAttribute("net.peer.port", String.valueOf(peerPort));
139+
}
140+
141+
@Override
142+
public void setQueryPaged(Boolean queryPaged) {
143+
assertStarted();
144+
if (queryPaged) span.setAttribute("db.scylla.query_paged", "true");
145+
else span.setAttribute("db.scylla.query_paged", "false");
146+
}
147+
148+
@Override
149+
public void setRowsCount(int rowsCount) {
150+
assertStarted();
151+
span.setAttribute("db.scylla.rows_count", rowsCount);
152+
}
153+
154+
@Override
155+
public void setStatement(String statement, int limit) {
156+
assertStarted();
157+
if (currentPrecisionLevelIsAtLeast(PrecisionLevel.FULL)) {
158+
if (statement.length() > limit) statement = statement.substring(0, limit);
159+
span.setAttribute("db.scylla.statement", statement);
160+
}
161+
}
162+
163+
@Override
164+
public void setKeyspace(String keyspace) {
165+
assertStarted();
166+
span.setAttribute("db.scylla.keyspace", keyspace);
167+
}
168+
169+
@Override
170+
public void setPartitionKey(String partitionKey) {
171+
assertStarted();
172+
span.setAttribute("db.scylla.partition_key", partitionKey);
173+
}
174+
175+
@Override
176+
public void setTable(String table) {
177+
assertStarted();
178+
span.setAttribute("db.scylla.table", table);
179+
}
180+
181+
@Override
182+
public void setOperationType(String operationType) {
183+
assertStarted();
184+
span.setAttribute("db.operation", operationType);
185+
}
186+
187+
@Override
188+
public void setReplicas(String replicas) {
189+
assertStarted();
190+
span.setAttribute("db.scylla.replicas", replicas);
191+
}
192+
193+
private io.opentelemetry.api.trace.StatusCode mapStatusCode(StatusCode code) {
194+
switch (code) {
195+
case OK:
196+
return io.opentelemetry.api.trace.StatusCode.OK;
197+
case ERROR:
198+
return io.opentelemetry.api.trace.StatusCode.ERROR;
199+
}
200+
return null;
201+
}
202+
203+
@Override
204+
public void recordException(Exception exception) {
205+
assertStarted();
206+
span.recordException(exception);
207+
}
208+
209+
@Override
210+
public void setStatus(StatusCode code, String description) {
211+
assertStarted();
212+
span.setStatus(mapStatusCode(code), description);
213+
}
214+
215+
@Override
216+
public void setStatus(StatusCode code) {
217+
assertStarted();
218+
span.setStatus(mapStatusCode(code));
219+
}
220+
221+
@Override
222+
public void tracingFinished() {
223+
assertStarted();
224+
span.end();
225+
}
226+
227+
private boolean currentPrecisionLevelIsAtLeast(PrecisionLevel requiredLevel) {
228+
return requiredLevel.compareTo(precision) <= 0;
229+
}
230+
}

0 commit comments

Comments
 (0)