Skip to content

Commit 4f332dc

Browse files
committed
DATACASS-808 - Fix CQL statement logging.
We now attempt to extract the CQL query from various Statement and CqlProvider objects to log the CQL query. Previously, the logger used the statement object with didn't render the query.
1 parent 244f4f9 commit 4f332dc

File tree

7 files changed

+148
-43
lines changed

7 files changed

+148
-43
lines changed

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/AsyncCqlTemplate.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ public <T> ListenableFuture<T> query(String cql, AsyncResultSetExtractor<T> resu
163163

164164
try {
165165
if (logger.isDebugEnabled()) {
166-
logger.debug("Executing CQL Statement [{}]", cql);
166+
logger.debug("Executing CQL statement [{}]", cql);
167167
}
168168

169169
CompletionStage<T> results = getCurrentSession().executeAsync(applyStatementSettings(newStatement(cql)))
@@ -285,7 +285,7 @@ public <T> ListenableFuture<T> query(Statement<?> statement, AsyncResultSetExtra
285285

286286
try {
287287
if (logger.isDebugEnabled()) {
288-
logger.debug("Executing CQL Statement [{}]", statement);
288+
logger.debug("Executing statement [{}]", QueryExtractorDelegate.getCql(statement));
289289
}
290290

291291
CompletionStage<T> results = getCurrentSession() //
@@ -525,7 +525,7 @@ public <T> ListenableFuture<T> query(AsyncPreparedStatementCreator preparedState
525525
ListenableFuture<Statement<?>> statementFuture = new MappingListenableFutureAdapter<>(
526526
preparedStatementCreator.createPreparedStatement(session), preparedStatement -> {
527527
if (logger.isDebugEnabled()) {
528-
logger.debug("Executing prepared statement [{}]", preparedStatement);
528+
logger.debug("Executing prepared statement [{}]", QueryExtractorDelegate.getCql(preparedStatement));
529529
}
530530

531531
return applyStatementSettings(psb != null ? psb.bindValues(preparedStatement) : preparedStatement.bind());

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/CassandraAccessor.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
package org.springframework.data.cassandra.core.cql;
1717

1818
import java.util.Map;
19-
import java.util.Optional;
2019

2120
import org.slf4j.Logger;
2221
import org.slf4j.LoggerFactory;
@@ -464,11 +463,6 @@ protected <T> RowMapper<T> newSingleColumnRowMapper(Class<T> requiredType) {
464463
*/
465464
@Nullable
466465
protected static String toCql(@Nullable Object cqlProvider) {
467-
468-
return Optional.ofNullable(cqlProvider) //
469-
.filter(o -> o instanceof CqlProvider) //
470-
.map(o -> (CqlProvider) o) //
471-
.map(CqlProvider::getCql) //
472-
.orElse(null);
466+
return QueryExtractorDelegate.getCql(cqlProvider);
473467
}
474468
}

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/CqlTemplate.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ public <T> T query(String cql, ResultSetExtractor<T> resultSetExtractor) throws
162162

163163
try {
164164
if (logger.isDebugEnabled()) {
165-
logger.debug("Executing CQL Statement [{}]", cql);
165+
logger.debug("Executing CQL statement [{}]", cql);
166166
}
167167

168168
Statement<?> statement = applyStatementSettings(newStatement(cql));
@@ -288,7 +288,7 @@ public <T> T query(Statement<?> statement, ResultSetExtractor<T> resultSetExtrac
288288

289289
try {
290290
if (logger.isDebugEnabled()) {
291-
logger.debug("Executing CQL Statement [{}]", statement);
291+
logger.debug("Executing statement [{}]", QueryExtractorDelegate.getCql(statement));
292292
}
293293

294294
return resultSetExtractor.extractData(getCurrentSession().execute(applyStatementSettings(statement)));
@@ -507,7 +507,7 @@ public <T> T query(PreparedStatementCreator preparedStatementCreator, @Nullable
507507
PreparedStatement preparedStatement = preparedStatementCreator.createPreparedStatement(session);
508508

509509
if (logger.isDebugEnabled()) {
510-
logger.debug("Executing prepared statement [{}]", preparedStatement);
510+
logger.debug("Executing prepared statement [{}]", QueryExtractorDelegate.getCql(preparedStatement));
511511
}
512512

513513
Statement<?> boundStatement = applyStatementSettings(
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright 2020 the original author or authors.
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+
* https://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+
package org.springframework.data.cassandra.core.cql;
17+
18+
import org.springframework.lang.Nullable;
19+
20+
import com.datastax.oss.driver.api.core.cql.BatchStatement;
21+
import com.datastax.oss.driver.api.core.cql.BatchableStatement;
22+
import com.datastax.oss.driver.api.core.cql.BoundStatement;
23+
import com.datastax.oss.driver.api.core.cql.PreparedStatement;
24+
import com.datastax.oss.driver.api.core.cql.SimpleStatement;
25+
import com.datastax.oss.driver.api.core.cql.Statement;
26+
27+
/**
28+
* Utility to extract CQL queries from a {@link Statement}.
29+
*
30+
* @author Mark Paluch
31+
* @since 3.0.5
32+
*/
33+
public class QueryExtractorDelegate {
34+
35+
/**
36+
* Try to extract the {@link SimpleStatement#getQuery() CQL query} from a statement object.
37+
*
38+
* @param statement the statement object.
39+
* @return the CQL query when {@code statement} is not {@code null}.
40+
*/
41+
@Nullable
42+
public static String getCql(@Nullable Object statement) {
43+
44+
if (statement == null) {
45+
return null;
46+
}
47+
48+
if (statement instanceof CqlProvider) {
49+
return ((CqlProvider) statement).getCql();
50+
}
51+
52+
if (statement instanceof SimpleStatement) {
53+
return ((SimpleStatement) statement).getQuery();
54+
}
55+
56+
if (statement instanceof PreparedStatement) {
57+
return ((PreparedStatement) statement).getQuery();
58+
}
59+
60+
if (statement instanceof BoundStatement) {
61+
return getCql(((BoundStatement) statement).getPreparedStatement());
62+
}
63+
64+
if (statement instanceof BatchStatement) {
65+
66+
StringBuilder builder = new StringBuilder();
67+
68+
for (BatchableStatement<?> batchableStatement : ((BatchStatement) statement)) {
69+
70+
String query = getCql(batchableStatement);
71+
builder.append(query).append(query.endsWith(";") ? "" : ";");
72+
}
73+
74+
return builder.toString();
75+
}
76+
77+
return String.format("Unknown: %s", statement);
78+
}
79+
}

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/ReactiveCqlTemplate.java

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ public <T> Flux<T> query(Statement<?> statement, ReactiveResultSetExtractor<T> r
440440
return createFlux(statement, (session, stmt) -> {
441441

442442
if (logger.isDebugEnabled()) {
443-
logger.debug("Executing CQL Statement [{}]", statement);
443+
logger.debug("Executing statement [{}]", QueryExtractorDelegate.getCql(statement));
444444
}
445445

446446
return session.execute(applyStatementSettings(statement)).flatMapMany(rse::extractData);
@@ -507,8 +507,7 @@ public Mono<ReactiveResultSet> queryForResultSet(Statement<?> statement) throws
507507
return createMono(statement, (session, executedStatement) -> {
508508

509509
if (logger.isDebugEnabled()) {
510-
logger.debug("Executing CQL [{}]", executedStatement);
511-
510+
logger.debug("Executing statement [{}]", QueryExtractorDelegate.getCql(statement));
512511
}
513512

514513
return session.execute(applyStatementSettings(executedStatement));
@@ -568,14 +567,15 @@ public <T> Flux<T> query(ReactivePreparedStatementCreator psc,
568567
Assert.notNull(psc, "ReactivePreparedStatementCreator must not be null");
569568
Assert.notNull(rse, "ReactiveResultSetExtractor object must not be null");
570569

571-
return execute(psc, (session, ps) -> Mono.just(ps).flatMapMany(pps -> {
570+
return execute(psc, (session, preparedStatement) -> Mono.just(preparedStatement).flatMapMany(pps -> {
572571

573572
if (logger.isDebugEnabled()) {
574-
logger.debug("Executing Prepared CQL Statement [{}]", ps.getQuery());
573+
logger.debug("Executing prepared statement [{}]", QueryExtractorDelegate.getCql(preparedStatement));
575574
}
576575

577-
BoundStatement boundStatement = (preparedStatementBinder != null ? preparedStatementBinder.bindValues(ps)
578-
: ps.bind());
576+
BoundStatement boundStatement = (preparedStatementBinder != null
577+
? preparedStatementBinder.bindValues(preparedStatement)
578+
: preparedStatement.bind());
579579

580580
return session.execute(applyStatementSettings(boundStatement));
581581
}).flatMap(rse::extractData)).onErrorMap(translateException("Query", getCql(psc)));
@@ -738,7 +738,7 @@ public Flux<Boolean> execute(String cql, Publisher<Object[]> args) throws DataAc
738738
return execute(newReactivePreparedStatementCreator(cql), (session, ps) -> Flux.from(args).flatMap(objects -> {
739739

740740
if (logger.isDebugEnabled()) {
741-
logger.debug("Executing Prepared CQL Statement [{}]", cql);
741+
logger.debug("Executing prepared CQL statement [{}]", cql);
742742
}
743743

744744
BoundStatement boundStatement = newArgPreparedStatementBinder(objects).bindValues(ps);
@@ -918,12 +918,7 @@ private Mono<ReactiveSession> getSession() {
918918
*/
919919
@Nullable
920920
private static String getCql(@Nullable Object cqlProvider) {
921-
922-
return Optional.ofNullable(cqlProvider) //
923-
.filter(o -> o instanceof CqlProvider) //
924-
.map(o -> (CqlProvider) o) //
925-
.map(CqlProvider::getCql) //
926-
.orElse(null);
921+
return QueryExtractorDelegate.getCql(cqlProvider);
927922
}
928923

929924
static class SimpleReactivePreparedStatementCreator implements ReactivePreparedStatementCreator, CqlProvider {

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/cql/session/DefaultBridgedReactiveSession.java

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,35 @@
1515
*/
1616
package org.springframework.data.cassandra.core.cql.session;
1717

18+
import reactor.core.publisher.Flux;
19+
import reactor.core.publisher.Mono;
20+
import reactor.core.publisher.MonoProcessor;
21+
import reactor.core.scheduler.Scheduler;
22+
1823
import java.util.Collections;
1924
import java.util.List;
2025
import java.util.Map;
2126
import java.util.concurrent.CompletionStage;
2227

28+
import org.slf4j.Logger;
29+
import org.slf4j.LoggerFactory;
30+
31+
import org.springframework.data.cassandra.ReactiveResultSet;
32+
import org.springframework.data.cassandra.ReactiveSession;
33+
import org.springframework.util.Assert;
34+
2335
import com.datastax.oss.driver.api.core.CqlSession;
2436
import com.datastax.oss.driver.api.core.context.DriverContext;
2537
import com.datastax.oss.driver.api.core.cql.AsyncResultSet;
38+
import com.datastax.oss.driver.api.core.cql.BatchStatement;
39+
import com.datastax.oss.driver.api.core.cql.BatchableStatement;
40+
import com.datastax.oss.driver.api.core.cql.BoundStatement;
2641
import com.datastax.oss.driver.api.core.cql.ColumnDefinitions;
2742
import com.datastax.oss.driver.api.core.cql.ExecutionInfo;
2843
import com.datastax.oss.driver.api.core.cql.PreparedStatement;
2944
import com.datastax.oss.driver.api.core.cql.Row;
3045
import com.datastax.oss.driver.api.core.cql.SimpleStatement;
3146
import com.datastax.oss.driver.api.core.cql.Statement;
32-
import org.slf4j.Logger;
33-
import org.slf4j.LoggerFactory;
34-
import reactor.core.publisher.Flux;
35-
import reactor.core.publisher.Mono;
36-
import reactor.core.publisher.MonoProcessor;
37-
import reactor.core.scheduler.Scheduler;
38-
39-
import org.springframework.data.cassandra.ReactiveResultSet;
40-
import org.springframework.data.cassandra.ReactiveSession;
41-
import org.springframework.util.Assert;
4247

4348
/**
4449
* Default implementation of a {@link ReactiveSession}. This implementation bridges asynchronous {@link CqlSession}
@@ -142,7 +147,7 @@ public Mono<ReactiveResultSet> execute(Statement<?> statement) {
142147
return Mono.fromCompletionStage(() -> {
143148

144149
if (logger.isDebugEnabled()) {
145-
logger.debug("Executing Statement [{}]", statement);
150+
logger.debug("Executing statement [{}]", getCql(statement));
146151
}
147152

148153
return this.session.executeAsync(statement);
@@ -171,13 +176,43 @@ public Mono<PreparedStatement> prepare(SimpleStatement statement) {
171176
return Mono.fromCompletionStage(() -> {
172177

173178
if (logger.isDebugEnabled()) {
174-
logger.debug("Preparing Statement [{}]", statement);
179+
logger.debug("Preparing statement [{}]", getCql(statement));
175180
}
176181

177182
return this.session.prepareAsync(statement);
178183
});
179184
}
180185

186+
private static String getCql(Object statement) {
187+
188+
if (statement instanceof SimpleStatement) {
189+
return ((SimpleStatement) statement).getQuery();
190+
}
191+
192+
if (statement instanceof PreparedStatement) {
193+
return ((PreparedStatement) statement).getQuery();
194+
}
195+
196+
if (statement instanceof BoundStatement) {
197+
return getCql(((BoundStatement) statement).getPreparedStatement());
198+
}
199+
200+
if (statement instanceof BatchStatement) {
201+
202+
StringBuilder builder = new StringBuilder();
203+
204+
for (BatchableStatement<?> batchableStatement : ((BatchStatement) statement)) {
205+
206+
String query = getCql(batchableStatement);
207+
builder.append(query).append(query.endsWith(";") ? "" : ";");
208+
}
209+
210+
return builder.toString();
211+
}
212+
213+
return String.format("Unknown: %s", statement);
214+
}
215+
181216
/* (non-Javadoc)
182217
* @see org.springframework.data.cassandra.ReactiveSession#close()
183218
*/
@@ -291,4 +326,5 @@ public List<ExecutionInfo> getAllExecutionInfo() {
291326
return Collections.singletonList(getExecutionInfo());
292327
}
293328
}
329+
294330
}

spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/QueryStatementCreator.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.slf4j.LoggerFactory;
2424

2525
import org.springframework.data.cassandra.core.StatementFactory;
26+
import org.springframework.data.cassandra.core.cql.QueryExtractorDelegate;
2627
import org.springframework.data.cassandra.core.cql.QueryOptions;
2728
import org.springframework.data.cassandra.core.cql.QueryOptionsUtil;
2829
import org.springframework.data.cassandra.core.mapping.CassandraPersistentEntity;
@@ -115,7 +116,7 @@ SimpleStatement count(StatementFactory statementFactory, PartTree tree,
115116
SimpleStatement statement = statementFactory.count(query, getPersistentEntity()).build();
116117

117118
if (LOG.isDebugEnabled()) {
118-
LOG.debug(String.format("Created query [%s].", statement));
119+
LOG.debug(String.format("Created query [%s].", QueryExtractorDelegate.getCql(statement)));
119120
}
120121

121122
return statement;
@@ -142,7 +143,7 @@ SimpleStatement delete(StatementFactory statementFactory, PartTree tree,
142143
SimpleStatement statement = statementFactory.delete(query, getPersistentEntity()).build();
143144

144145
if (LOG.isDebugEnabled()) {
145-
LOG.debug(String.format("Created query [%s].", statement));
146+
LOG.debug(String.format("Created query [%s].", QueryExtractorDelegate.getCql(statement)));
146147
}
147148

148149
return statement;
@@ -169,7 +170,7 @@ SimpleStatement exists(StatementFactory statementFactory, PartTree tree,
169170
SimpleStatement statement = statementFactory.select(query.limit(1), getPersistentEntity()).build();
170171

171172
if (LOG.isDebugEnabled()) {
172-
LOG.debug(String.format("Created query [%s].", statement));
173+
LOG.debug(String.format("Created query [%s].", QueryExtractorDelegate.getCql(statement)));
173174
}
174175

175176
return statement;
@@ -254,7 +255,7 @@ SimpleStatement select(StringBasedQuery stringBasedQuery, CassandraParameterAcce
254255
}
255256

256257
if (LOG.isDebugEnabled()) {
257-
LOG.debug(String.format("Created query [%s].", queryToUse));
258+
LOG.debug(String.format("Created query [%s].", QueryExtractorDelegate.getCql(queryToUse)));
258259
}
259260

260261
return queryToUse;

0 commit comments

Comments
 (0)