Skip to content

Commit f40dcfe

Browse files
committed
Tracing: added various request driver-side tags
All data that constitute added tags are already know by the driver, i.e. they do not require fetching any additional metadata from the cluster.
1 parent d41834f commit f40dcfe

File tree

8 files changed

+375
-0
lines changed

8 files changed

+375
-0
lines changed

clirr-ignores.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616
Modified by ScyllaDB
1717
-->
1818
<differences>
19+
<difference>
20+
<differenceType>7012</differenceType> <!-- method added to interface -->
21+
<className>com/datastax/driver/core/PreparedStatement</className>
22+
<method>java.lang.String getOperationType()</method>
23+
<justification>New method to get the type of operation performed by this PreparedStatement</justification>
24+
</difference>
1925
<difference>
2026
<differenceType>7012</differenceType> <!-- method added to interface -->
2127
<className>com/datastax/driver/core/Session</className>

driver-core/src/main/java/com/datastax/driver/core/BoundStatement.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ public class BoundStatement extends Statement
7474

7575
private ByteBuffer routingKey;
7676

77+
private final String operationType;
78+
7779
/**
7880
* Creates a new {@code BoundStatement} from the provided prepared statement.
7981
*
@@ -92,6 +94,7 @@ public BoundStatement(PreparedStatement statement) {
9294
this.setSerialConsistencyLevel(statement.getSerialConsistencyLevel());
9395
if (statement.isTracing()) this.enableTracing();
9496
if (statement.getRetryPolicy() != null) this.setRetryPolicy(statement.getRetryPolicy());
97+
this.operationType = statement.getOperationType();
9598
if (statement.getOutgoingPayload() != null)
9699
this.setOutgoingPayload(statement.getOutgoingPayload());
97100
else
@@ -104,6 +107,10 @@ public BoundStatement(PreparedStatement statement) {
104107
}
105108
}
106109

110+
public String getOperationType() {
111+
return operationType;
112+
}
113+
107114
@Override
108115
public boolean isLWT() {
109116
return statement.isLWT();

driver-core/src/main/java/com/datastax/driver/core/CodecUtils.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ public final class CodecUtils {
2424

2525
private static final long EPOCH_AS_CQL_LONG = (1L << 31);
2626

27+
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
28+
2729
private CodecUtils() {}
2830

2931
/**
@@ -212,6 +214,19 @@ public static long fromDaysSinceEpochToCqlDate(int days) {
212214
return ((long) days + EPOCH_AS_CQL_LONG);
213215
}
214216

217+
public static String bytesToHex(byte[] bytes) {
218+
final int INITIAL_CHARS = 2;
219+
char[] hexChars = new char[INITIAL_CHARS + bytes.length * 2];
220+
hexChars[0] = '0';
221+
hexChars[1] = 'x';
222+
for (int j = 0; j < bytes.length; j++) {
223+
int v = bytes[j] & 0xFF;
224+
hexChars[INITIAL_CHARS + j * 2] = HEX_ARRAY[v >>> 4];
225+
hexChars[INITIAL_CHARS + j * 2 + 1] = HEX_ARRAY[v & 0x0F];
226+
}
227+
return new String(hexChars);
228+
}
229+
215230
private static int sizeOfCollectionSize(ProtocolVersion version) {
216231
switch (version) {
217232
case V1:

driver-core/src/main/java/com/datastax/driver/core/DefaultPreparedStatement.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public class DefaultPreparedStatement implements PreparedStatement {
4141
final Cluster cluster;
4242
final boolean isLWT;
4343
final Token.Factory partitioner;
44+
final String operationType;
4445

4546
volatile ByteBuffer routingKey;
4647

@@ -66,6 +67,7 @@ private DefaultPreparedStatement(
6667
this.cluster = cluster;
6768
this.isLWT = isLWT;
6869
this.partitioner = partitioner;
70+
this.operationType = null;
6971
}
7072

7173
static DefaultPreparedStatement fromMessage(
@@ -315,4 +317,10 @@ public Boolean isIdempotent() {
315317
public boolean isLWT() {
316318
return isLWT;
317319
}
320+
321+
/** {@inheritDoc} */
322+
@Override
323+
public String getOperationType() {
324+
return operationType;
325+
}
318326
}

driver-core/src/main/java/com/datastax/driver/core/PreparedStatement.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,4 +361,7 @@ public interface PreparedStatement {
361361

362362
/** Whether a prepared statement is LWT statement */
363363
public boolean isLWT();
364+
365+
/** Type of prepared operation (e.g. SELECT) */
366+
public String getOperationType();
364367
}

driver-core/src/main/java/com/datastax/driver/core/RequestHandler.java

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import com.google.common.util.concurrent.ListenableFuture;
4949
import io.netty.util.Timeout;
5050
import io.netty.util.TimerTask;
51+
import java.net.InetSocketAddress;
5152
import java.nio.ByteBuffer;
5253
import java.util.Collections;
5354
import java.util.Iterator;
@@ -74,6 +75,10 @@ class RequestHandler {
7475
private static final QueryLogger QUERY_LOGGER = QueryLogger.builder().build();
7576
static final String DISABLE_QUERY_WARNING_LOGS = "com.datastax.driver.DISABLE_QUERY_WARNING_LOGS";
7677

78+
private static final int STATEMENT_MAX_LENGTH = 1000;
79+
private static final int PARTITION_KEY_MAX_LENGTH = 1000;
80+
private static final int BOUND_VALUES_MAX_LENGTH = 1000;
81+
7782
final String id;
7883

7984
private final SessionManager manager;
@@ -161,8 +166,92 @@ public RequestHandler(
161166
this.timerContext = metricsEnabled() ? metrics().getRequestsTimer().time() : null;
162167
this.startTime = System.nanoTime();
163168

169+
ConsistencyLevel consistency = statement.getConsistencyLevel();
170+
if (consistency == null) consistency = Statement.DEFAULT.getConsistencyLevel();
171+
172+
String statementType = null;
173+
String statementText = null;
174+
Integer batchSize = null;
175+
176+
String keyspace = null;
177+
String partitionKey = null;
178+
String boundValues = null;
179+
String table = null;
180+
String operationType = null;
181+
182+
if (statement instanceof BatchStatement) {
183+
statementType = "batch";
184+
batchSize = ((BatchStatement) statement).size();
185+
StringBuilder statementTextBuilder = new StringBuilder(STATEMENT_MAX_LENGTH);
186+
for (Statement subStatement : ((BatchStatement) statement).getStatements()) {
187+
if (subStatement instanceof BoundStatement)
188+
statementTextBuilder.append(((BoundStatement) subStatement).statement.getQueryString());
189+
else statementTextBuilder.append(subStatement.toString());
190+
}
191+
statementText = statementTextBuilder.toString();
192+
} else if (statement instanceof BoundStatement) {
193+
statementType = "prepared";
194+
statementText = ((BoundStatement) statement).statement.getQueryString();
195+
keyspace = ((BoundStatement) statement).getKeyspace();
196+
operationType = ((BoundStatement) statement).getOperationType();
197+
198+
ColumnDefinitions boundColumns =
199+
((BoundStatement) statement).statement.getPreparedId().boundValuesMetadata.variables;
200+
201+
StringBuilder boundValuesBuilder = new StringBuilder(BOUND_VALUES_MAX_LENGTH);
202+
StringBuilder partitionKeyBuilder = new StringBuilder(PARTITION_KEY_MAX_LENGTH);
203+
int[] rkIndexes = ((BoundStatement) statement).statement.getPreparedId().routingKeyIndexes;
204+
205+
for (int i = 0; i < boundColumns.size(); ++i) {
206+
Object value = ((BoundStatement) statement).getObject(i);
207+
String valueString =
208+
(value == null)
209+
? "NULL"
210+
: value instanceof ByteBuffer
211+
? CodecUtils.bytesToHex(((ByteBuffer) value).array())
212+
: value.toString();
213+
String columnName = boundColumns.getName(i);
214+
if (boundValuesBuilder.length() > 0) boundValuesBuilder.append(", ");
215+
boundValuesBuilder.append(columnName);
216+
boundValuesBuilder.append('=');
217+
boundValuesBuilder.append(valueString);
218+
219+
if (rkIndexes != null) {
220+
for (int j : rkIndexes) {
221+
if (i == j) {
222+
if (partitionKeyBuilder.length() > 0) partitionKeyBuilder.append(", ");
223+
partitionKeyBuilder.append(columnName);
224+
partitionKeyBuilder.append('=');
225+
partitionKeyBuilder.append(valueString);
226+
break;
227+
}
228+
}
229+
}
230+
}
231+
boundValues = boundValuesBuilder.toString();
232+
partitionKey = partitionKeyBuilder.toString();
233+
234+
if (boundColumns.size() > 0) table = boundColumns.getTable(0);
235+
} else if (statement instanceof RegularStatement) {
236+
statementType = "regular";
237+
statementText = ((RegularStatement) statement).toString();
238+
}
239+
164240
this.tracingInfo = tracingInfo;
165241
this.tracingInfo.setNameAndStartTime("request");
242+
this.tracingInfo.setConsistencyLevel(consistency);
243+
this.tracingInfo.setRetryPolicy(retryPolicy());
244+
this.tracingInfo.setLoadBalancingPolicy(manager.loadBalancingPolicy());
245+
this.tracingInfo.setSpeculativeExecutionPolicy(manager.speculativeExecutionPolicy());
246+
if (statement.getFetchSize() > 0) this.tracingInfo.setFetchSize(statement.getFetchSize());
247+
if (statementType != null) this.tracingInfo.setStatementType(statementType);
248+
if (statementText != null) this.tracingInfo.setStatement(statementText, STATEMENT_MAX_LENGTH);
249+
if (batchSize != null) this.tracingInfo.setBatchSize(batchSize);
250+
if (keyspace != null) this.tracingInfo.setKeyspace(keyspace);
251+
if (boundValues != null) this.tracingInfo.setBoundValues(boundValues);
252+
if (partitionKey != null) this.tracingInfo.setPartitionKey(partitionKey);
253+
if (table != null) this.tracingInfo.setTable(table);
254+
if (operationType != null) this.tracingInfo.setOperationType(operationType);
166255
}
167256

168257
void sendRequest() {
@@ -280,6 +369,15 @@ private void setFinalResult(
280369
&& logger.isWarnEnabled()) {
281370
logServerWarnings(response.warnings);
282371
}
372+
373+
if (response.type == Message.Response.Type.RESULT) {
374+
Responses.Result rm = (Responses.Result) response;
375+
if (rm.kind == Responses.Result.Kind.ROWS) {
376+
Responses.Result.Rows r = (Responses.Result.Rows) rm;
377+
tracingInfo.setRowsCount(r.data.size());
378+
tracingInfo.setHasMorePages(r.metadata.pagingState != null);
379+
}
380+
}
283381
callback.onSet(connection, response, info, statement, System.nanoTime() - startTime);
284382

285383
tracingInfo.setStatus(
@@ -336,6 +434,7 @@ private void setFinalException(
336434
// Triggered when an execution reaches the end of the query plan.
337435
// This is only a failure if there are no other running executions.
338436
private void reportNoMoreHosts(SpeculativeExecution execution) {
437+
execution.parentTracingInfo.setAttemptCount(execution.retryCount() + 1);
339438
execution.parentTracingInfo.setStatus(TracingInfo.StatusCode.ERROR);
340439
execution.parentTracingInfo.tracingFinished();
341440
runningExecutions.remove(execution);
@@ -460,6 +559,10 @@ private boolean query(final Host host) {
460559

461560
currentChildTracingInfo = manager.getTracingInfoFactory().buildTracingInfo(parentTracingInfo);
462561
currentChildTracingInfo.setNameAndStartTime("attempt");
562+
InetSocketAddress hostAddress = host.getEndPoint().resolve();
563+
currentChildTracingInfo.setPeerName(hostAddress.getHostName());
564+
currentChildTracingInfo.setPeerIP(hostAddress.getAddress());
565+
currentChildTracingInfo.setPeerPort(hostAddress.getPort());
463566

464567
if (allowSpeculativeExecutions && nextExecutionScheduled.compareAndSet(false, true))
465568
scheduleExecution(speculativeExecutionPlan.nextExecution(host));
@@ -679,6 +782,7 @@ void cancel() {
679782
CancelledSpeculativeExecutionException.INSTANCE,
680783
System.nanoTime() - startTime);
681784
}
785+
parentTracingInfo.setAttemptCount(previous.retryCount + 1);
682786
parentTracingInfo.setStatus(TracingInfo.StatusCode.OK);
683787
parentTracingInfo.tracingFinished();
684788
return;
@@ -693,6 +797,7 @@ void cancel() {
693797
CancelledSpeculativeExecutionException.INSTANCE,
694798
System.nanoTime() - startTime);
695799
}
800+
parentTracingInfo.setAttemptCount(previous.retryCount + 1);
696801
parentTracingInfo.setStatus(TracingInfo.StatusCode.OK);
697802
parentTracingInfo.tracingFinished();
698803
return;
@@ -710,6 +815,7 @@ public Message.Request request() {
710815
@Override
711816
public void onSet(
712817
Connection connection, Message.Response response, long latency, int retryCount) {
818+
currentChildTracingInfo.setShardID(connection.shardId());
713819
currentChildTracingInfo.setStatus(TracingInfo.StatusCode.OK);
714820
currentChildTracingInfo.tracingFinished();
715821

@@ -1021,6 +1127,7 @@ public boolean onTimeout(Connection connection, long latency, int retryCount) {
10211127
@Override
10221128
public void onException(
10231129
Connection connection, Exception exception, long latency, int retryCount) {
1130+
currentChildTracingInfo.setShardID(connection.shardId());
10241131
currentChildTracingInfo.recordException(exception);
10251132
currentChildTracingInfo.setStatus(TracingInfo.StatusCode.ERROR);
10261133
currentChildTracingInfo.tracingFinished();
@@ -1062,6 +1169,7 @@ public void onException(
10621169

10631170
@Override
10641171
public boolean onTimeout(Connection connection, long latency, int retryCount) {
1172+
currentChildTracingInfo.setShardID(connection.shardId());
10651173
currentChildTracingInfo.setStatus(TracingInfo.StatusCode.ERROR, "timeout");
10661174
currentChildTracingInfo.tracingFinished();
10671175

@@ -1106,12 +1214,14 @@ public int retryCount() {
11061214
}
11071215

11081216
private void setFinalException(Connection connection, Exception exception) {
1217+
parentTracingInfo.setAttemptCount(retryCount() + 1);
11091218
parentTracingInfo.setStatus(TracingInfo.StatusCode.ERROR);
11101219
parentTracingInfo.tracingFinished();
11111220
RequestHandler.this.setFinalException(this, connection, exception);
11121221
}
11131222

11141223
private void setFinalResult(Connection connection, Message.Response response) {
1224+
parentTracingInfo.setAttemptCount(retryCount() + 1);
11151225
parentTracingInfo.setStatus(TracingInfo.StatusCode.OK);
11161226
parentTracingInfo.tracingFinished();
11171227
RequestHandler.this.setFinalResult(this, connection, response);

driver-core/src/main/java/com/datastax/driver/core/tracing/NoopTracingInfoFactory.java

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,82 @@
1616

1717
package com.datastax.driver.core.tracing;
1818

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 java.net.InetAddress;
24+
1925
public class NoopTracingInfoFactory implements TracingInfoFactory {
2026

2127
private static class NoopTracingInfo implements TracingInfo {
2228
@Override
2329
public void setNameAndStartTime(String name) {}
2430

31+
@Override
32+
public void setConsistencyLevel(ConsistencyLevel consistency) {}
33+
34+
@Override
35+
public void setStatementType(String statementType) {}
36+
37+
@Override
38+
public void setRetryPolicy(RetryPolicy retryPolicy) {}
39+
40+
@Override
41+
public void setLoadBalancingPolicy(LoadBalancingPolicy loadBalancingPolicy) {};
42+
43+
@Override
44+
public void setSpeculativeExecutionPolicy(
45+
SpeculativeExecutionPolicy speculativeExecutionPolicy) {}
46+
47+
@Override
48+
public void setBatchSize(int batchSize) {}
49+
50+
@Override
51+
public void setAttemptCount(int attemptCount) {}
52+
53+
@Override
54+
public void setShardID(int shardID) {}
55+
56+
@Override
57+
public void setPeerName(String peerName) {}
58+
59+
@Override
60+
public void setPeerIP(InetAddress peerIP) {}
61+
62+
@Override
63+
public void setPeerPort(int peerPort) {}
64+
65+
@Override
66+
public void setFetchSize(int fetchSize) {}
67+
68+
@Override
69+
public void setHasMorePages(boolean hasMorePages) {}
70+
71+
@Override
72+
public void setRowsCount(int rowsCount) {}
73+
74+
@Override
75+
public void setStatement(String statement, int limit) {}
76+
77+
@Override
78+
public void setKeyspace(String keyspace) {}
79+
80+
@Override
81+
public void setBoundValues(String boundValues) {}
82+
83+
@Override
84+
public void setPartitionKey(String partitionKey) {}
85+
86+
@Override
87+
public void setTable(String table) {}
88+
89+
@Override
90+
public void setOperationType(String operationType) {}
91+
92+
@Override
93+
public void setReplicas(String replicas) {}
94+
2595
@Override
2696
public void recordException(Exception exception) {}
2797

0 commit comments

Comments
 (0)