Skip to content

Commit dbc89b3

Browse files
authored
Fix clickhouse query failing with syntax error with agent (#13020)
1 parent 8c15a7a commit dbc89b3

File tree

4 files changed

+67
-2
lines changed

4 files changed

+67
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package com.clickhouse.client;
7+
8+
// helper class for accessing package private members in com.clickhouse.client package
9+
public final class ClickHouseRequestAccess {
10+
11+
public static String getQuery(ClickHouseRequest<?> clickHouseRequest) {
12+
return clickHouseRequest.getQuery();
13+
}
14+
15+
private ClickHouseRequestAccess() {}
16+
}

instrumentation/clickhouse-client-0.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/clickhouse/ClickHouseClientInstrumentation.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import com.clickhouse.client.ClickHouseClient;
1616
import com.clickhouse.client.ClickHouseRequest;
17+
import com.clickhouse.client.ClickHouseRequestAccess;
1718
import com.clickhouse.client.config.ClickHouseDefaults;
1819
import io.opentelemetry.context.Context;
1920
import io.opentelemetry.javaagent.bootstrap.CallDepth;
@@ -59,7 +60,7 @@ public static ClickHouseScope onEnter(
5960
.getServer()
6061
.getDatabase()
6162
.orElse(ClickHouseDefaults.DATABASE.getDefaultValue().toString()),
62-
clickHouseRequest.getPreparedQuery().getOriginalQuery());
63+
ClickHouseRequestAccess.getQuery(clickHouseRequest));
6364

6465
return ClickHouseScope.start(parentContext, request);
6566
}

instrumentation/clickhouse-client-0.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/clickhouse/ClickHouseInstrumentationModule.java

+13-1
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,27 @@
1010
import com.google.auto.service.AutoService;
1111
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
1212
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
13+
import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule;
1314
import java.util.List;
1415

1516
@AutoService(InstrumentationModule.class)
16-
public class ClickHouseInstrumentationModule extends InstrumentationModule {
17+
public class ClickHouseInstrumentationModule extends InstrumentationModule
18+
implements ExperimentalInstrumentationModule {
1719

1820
public ClickHouseInstrumentationModule() {
1921
super("clickhouse-client", "clickhouse-client-0.5", "clickhouse");
2022
}
2123

24+
@Override
25+
public boolean isHelperClass(String className) {
26+
return "com.clickhouse.client.ClickHouseRequestAccess".equals(className);
27+
}
28+
29+
@Override
30+
public List<String> injectedClassNames() {
31+
return singletonList("com.clickhouse.client.ClickHouseRequestAccess");
32+
}
33+
2234
@Override
2335
public List<TypeInstrumentation> typeInstrumentations() {
2436
return singletonList(new ClickHouseClientInstrumentation());

instrumentation/clickhouse-client-0.5/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/clickhouse/ClickHouseClientTest.java

+36
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import io.opentelemetry.sdk.testing.assertj.AttributeAssertion;
3434
import io.opentelemetry.sdk.trace.data.StatusData;
3535
import io.opentelemetry.semconv.incubating.DbIncubatingAttributes;
36+
import java.time.Instant;
3637
import java.util.List;
3738
import java.util.concurrent.CompletableFuture;
3839
import org.junit.jupiter.api.AfterAll;
@@ -338,6 +339,41 @@ void testParameterizedQueryInput() throws ClickHouseException {
338339
"select * from " + tableName + " where s=:val", "SELECT"))));
339340
}
340341

342+
// regression test for
343+
// https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/13019
344+
// {s:String} used in the query really a syntax error, should be {s: String}. This test verifies
345+
// that this syntax error isn't detected when running with the agent as it is also ignored when
346+
// running without the agent.
347+
@Test
348+
void testPlaceholderQueryInput() throws Exception {
349+
ClickHouseRequest<?> request =
350+
client.read(server).format(ClickHouseFormat.RowBinaryWithNamesAndTypes);
351+
testing.runWithSpan(
352+
"parent",
353+
() -> {
354+
ClickHouseResponse response =
355+
request
356+
// {s:String} is really a syntax error should be {s: String}
357+
.query("select * from " + tableName + " where s={s:String}")
358+
.settings(ImmutableMap.of("param_s", "" + Instant.now().getEpochSecond()))
359+
.execute()
360+
.get();
361+
response.close();
362+
});
363+
364+
testing.waitAndAssertTraces(
365+
trace ->
366+
trace.hasSpansSatisfyingExactly(
367+
span -> span.hasName("parent").hasNoParent().hasAttributes(Attributes.empty()),
368+
span ->
369+
span.hasName("SELECT " + dbName)
370+
.hasKind(SpanKind.CLIENT)
371+
.hasParent(trace.getSpan(0))
372+
.hasAttributesSatisfyingExactly(
373+
attributeAssertions(
374+
"select * from " + tableName + " where s={s:String}", "SELECT"))));
375+
}
376+
341377
@SuppressWarnings("deprecation") // using deprecated semconv
342378
private static List<AttributeAssertion> attributeAssertions(String statement, String operation) {
343379
return asList(

0 commit comments

Comments
 (0)