Skip to content

Commit b17ae29

Browse files
adds aerospike instrumentation
1 parent 23a6a3e commit b17ae29

22 files changed

+1577
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package io.opentelemetry.instrumentation.api.instrumenter.db;
2+
3+
import static io.opentelemetry.instrumentation.api.instrumenter.db.DbMessageSizeUtil.getMessageSize;
4+
import static java.util.logging.Level.FINE;
5+
6+
import com.google.auto.value.AutoValue;
7+
import io.opentelemetry.api.common.Attributes;
8+
import io.opentelemetry.api.metrics.DoubleHistogram;
9+
import io.opentelemetry.api.metrics.DoubleHistogramBuilder;
10+
import io.opentelemetry.api.metrics.LongCounter;
11+
import io.opentelemetry.api.metrics.LongCounterBuilder;
12+
import io.opentelemetry.api.metrics.LongUpDownCounter;
13+
import io.opentelemetry.api.metrics.LongUpDownCounterBuilder;
14+
import io.opentelemetry.api.metrics.Meter;
15+
import io.opentelemetry.context.Context;
16+
import io.opentelemetry.context.ContextKey;
17+
import io.opentelemetry.instrumentation.api.instrumenter.OperationListener;
18+
import io.opentelemetry.instrumentation.api.instrumenter.OperationMetrics;
19+
import java.util.concurrent.TimeUnit;
20+
import java.util.logging.Logger;
21+
22+
public final class AerospikeMetrics implements OperationListener {
23+
private static final double NANOS_PER_MS = TimeUnit.MILLISECONDS.toNanos(1);
24+
25+
private static final ContextKey<State> AEROSPIKE_CLIENT_METRICS_STATE =
26+
ContextKey.named("aerospike-client-metrics-state");
27+
28+
private static final Logger logger = Logger.getLogger(AerospikeMetrics.class.getName());
29+
30+
private final LongCounter requestCounter;
31+
private final LongCounter responseCounter;
32+
private final LongUpDownCounter concurrencyUpDownCounter;
33+
private final DoubleHistogram clientLatencyHistogram;
34+
@SuppressWarnings("unused")
35+
private final DoubleHistogram recordSizeHistogram;
36+
37+
private AerospikeMetrics(Meter meter) {
38+
LongCounterBuilder requestCounterBuilder =
39+
meter
40+
.counterBuilder("aerospike.requests")
41+
.setDescription("Aerospike Calls");
42+
AerospikeMetricsAdvice.applyRequestCounterAdvice(requestCounterBuilder);
43+
requestCounter = requestCounterBuilder.build();
44+
LongCounterBuilder responseCounterBuilder =
45+
meter
46+
.counterBuilder("aerospike.response")
47+
.setDescription("Aerospike Responses");
48+
AerospikeMetricsAdvice.applyResponseCounterAdvice(responseCounterBuilder);
49+
responseCounter = responseCounterBuilder.build();
50+
LongUpDownCounterBuilder concurrencyUpDownCounterBuilder =
51+
meter
52+
.upDownCounterBuilder("aerospike.concurrreny")
53+
.setDescription("Aerospike Concurrent Requests");
54+
AerospikeMetricsAdvice.applyConcurrencyUpDownCounterAdvice(concurrencyUpDownCounterBuilder);
55+
concurrencyUpDownCounter = concurrencyUpDownCounterBuilder.build();
56+
DoubleHistogramBuilder durationBuilder =
57+
meter
58+
.histogramBuilder("aerospike.client.duration")
59+
.setDescription("Aerospike Response Latency")
60+
.setUnit("ms");
61+
AerospikeMetricsAdvice.applyClientDurationAdvice(durationBuilder);
62+
clientLatencyHistogram = durationBuilder.build();
63+
DoubleHistogramBuilder recordSizeHistogramBuilder =
64+
meter
65+
.histogramBuilder("aerospike.record.size")
66+
.setDescription("Aerospike Record Size")
67+
.setUnit("By");
68+
AerospikeMetricsAdvice.applyRecordSizeAdvice(recordSizeHistogramBuilder);
69+
recordSizeHistogram = recordSizeHistogramBuilder.build();
70+
}
71+
72+
public static OperationMetrics get() {
73+
return AerospikeMetrics::new;
74+
}
75+
76+
77+
@Override
78+
public Context onStart(Context context, Attributes startAttributes, long startNanos) {
79+
requestCounter.add(1, startAttributes, context);
80+
concurrencyUpDownCounter.add(1, startAttributes, context);
81+
return context.with(
82+
AEROSPIKE_CLIENT_METRICS_STATE,
83+
new AutoValue_AerospikeMetrics_State(startAttributes, startNanos));
84+
}
85+
86+
@Override
87+
public void onEnd(Context context, Attributes endAttributes, long endNanos) {
88+
State state = context.get(AEROSPIKE_CLIENT_METRICS_STATE);
89+
if (state == null) {
90+
logger.log(
91+
FINE,
92+
"No state present when ending context {0}. Cannot record Aerospike End Call metrics.",
93+
context);
94+
return;
95+
}
96+
concurrencyUpDownCounter.add(-1, state.startAttributes(), context);
97+
Attributes mergedAttributes = state.startAttributes().toBuilder().putAll(endAttributes).build();
98+
responseCounter.add(1, mergedAttributes, context);
99+
clientLatencyHistogram.record(
100+
(endNanos - state.startTimeNanos()) / NANOS_PER_MS,
101+
mergedAttributes,
102+
context);
103+
Long requestBodySize = getMessageSize(mergedAttributes);
104+
if (requestBodySize != null) {
105+
recordSizeHistogram.record(requestBodySize, mergedAttributes, context);
106+
}
107+
}
108+
109+
@AutoValue
110+
abstract static class State {
111+
112+
abstract Attributes startAttributes();
113+
114+
abstract long startTimeNanos();
115+
}
116+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
package io.opentelemetry.instrumentation.api.instrumenter.db;
2+
3+
import io.opentelemetry.api.common.AttributeKey;
4+
import io.opentelemetry.api.metrics.DoubleHistogramBuilder;
5+
import io.opentelemetry.api.metrics.LongCounterBuilder;
6+
import io.opentelemetry.api.metrics.LongUpDownCounterBuilder;
7+
import io.opentelemetry.extension.incubator.metrics.ExtendedDoubleHistogramBuilder;
8+
import io.opentelemetry.extension.incubator.metrics.ExtendedLongCounterBuilder;
9+
import io.opentelemetry.extension.incubator.metrics.ExtendedLongUpDownCounterBuilder;
10+
import io.opentelemetry.instrumentation.api.internal.SemconvStability;
11+
import io.opentelemetry.semconv.SemanticAttributes;
12+
import java.util.ArrayList;
13+
import java.util.List;
14+
15+
final class AerospikeMetricsAdvice {
16+
private AerospikeMetricsAdvice() {}
17+
18+
@SuppressWarnings("deprecation") // until old http semconv are dropped in 2.0
19+
static void applyRequestCounterAdvice(LongCounterBuilder builder) {
20+
if (!(builder instanceof ExtendedLongCounterBuilder)) {
21+
return;
22+
}
23+
24+
List<AttributeKey<?>> attributes = new ArrayList<>();
25+
attributes.add(SemanticAttributes.DB_SYSTEM);
26+
attributes.add(SemanticAttributes.DB_OPERATION);
27+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_NAMESPACE);
28+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_SET_NAME);
29+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_USER_KEY);
30+
if (SemconvStability.emitStableHttpSemconv()) {
31+
attributes.add(SemanticAttributes.NETWORK_TYPE);
32+
attributes.add(SemanticAttributes.NETWORK_TRANSPORT);
33+
attributes.add(SemanticAttributes.SERVER_ADDRESS);
34+
attributes.add(SemanticAttributes.SERVER_PORT);
35+
}
36+
if (SemconvStability.emitOldHttpSemconv()) {
37+
attributes.add(SemanticAttributes.NET_SOCK_PEER_ADDR);
38+
attributes.add(SemanticAttributes.NET_SOCK_PEER_NAME);
39+
attributes.add(SemanticAttributes.NET_SOCK_PEER_PORT);
40+
}
41+
42+
((ExtendedLongCounterBuilder) builder).setAttributesAdvice(attributes);
43+
}
44+
45+
@SuppressWarnings("deprecation") // until old http semconv are dropped in 2.0
46+
static void applyConcurrencyUpDownCounterAdvice(LongUpDownCounterBuilder builder) {
47+
if (!(builder instanceof ExtendedLongUpDownCounterBuilder)) {
48+
return;
49+
}
50+
51+
List<AttributeKey<?>> attributes = new ArrayList<>();
52+
attributes.add(SemanticAttributes.DB_SYSTEM);
53+
attributes.add(SemanticAttributes.DB_OPERATION);
54+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_NAMESPACE);
55+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_SET_NAME);
56+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_USER_KEY);
57+
if (SemconvStability.emitStableHttpSemconv()) {
58+
attributes.add(SemanticAttributes.NETWORK_TYPE);
59+
attributes.add(SemanticAttributes.NETWORK_TRANSPORT);
60+
attributes.add(SemanticAttributes.SERVER_ADDRESS);
61+
attributes.add(SemanticAttributes.SERVER_PORT);
62+
}
63+
if (SemconvStability.emitOldHttpSemconv()) {
64+
attributes.add(SemanticAttributes.NET_SOCK_PEER_ADDR);
65+
attributes.add(SemanticAttributes.NET_SOCK_PEER_NAME);
66+
attributes.add(SemanticAttributes.NET_SOCK_PEER_PORT);
67+
}
68+
69+
((ExtendedLongUpDownCounterBuilder) builder).setAttributesAdvice(attributes);
70+
}
71+
72+
@SuppressWarnings("deprecation") // until old http semconv are dropped in 2.0
73+
static void applyResponseCounterAdvice(LongCounterBuilder builder) {
74+
if (!(builder instanceof ExtendedLongCounterBuilder)) {
75+
return;
76+
}
77+
78+
List<AttributeKey<?>> attributes = new ArrayList<>();
79+
attributes.add(SemanticAttributes.DB_SYSTEM);
80+
attributes.add(SemanticAttributes.DB_OPERATION);
81+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_NAMESPACE);
82+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_SET_NAME);
83+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_USER_KEY);
84+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_STATUS);
85+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_ERROR_CODE);
86+
if (SemconvStability.emitStableHttpSemconv()) {
87+
attributes.add(SemanticAttributes.NETWORK_TYPE);
88+
attributes.add(SemanticAttributes.NETWORK_TRANSPORT);
89+
attributes.add(SemanticAttributes.SERVER_ADDRESS);
90+
attributes.add(SemanticAttributes.SERVER_PORT);
91+
}
92+
if (SemconvStability.emitOldHttpSemconv()) {
93+
attributes.add(SemanticAttributes.NET_SOCK_PEER_ADDR);
94+
attributes.add(SemanticAttributes.NET_SOCK_PEER_NAME);
95+
attributes.add(SemanticAttributes.NET_SOCK_PEER_PORT);
96+
}
97+
98+
((ExtendedLongCounterBuilder) builder).setAttributesAdvice(attributes);
99+
}
100+
101+
@SuppressWarnings("deprecation") // until old http semconv are dropped in 2.0
102+
static void applyClientDurationAdvice(DoubleHistogramBuilder builder) {
103+
if (!(builder instanceof ExtendedDoubleHistogramBuilder)) {
104+
return;
105+
}
106+
107+
List<AttributeKey<?>> attributes = new ArrayList<>();
108+
attributes.add(SemanticAttributes.DB_SYSTEM);
109+
attributes.add(SemanticAttributes.DB_OPERATION);
110+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_NAMESPACE);
111+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_SET_NAME);
112+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_USER_KEY);
113+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_STATUS);
114+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_ERROR_CODE);
115+
if (SemconvStability.emitStableHttpSemconv()) {
116+
attributes.add(SemanticAttributes.NETWORK_TYPE);
117+
attributes.add(SemanticAttributes.NETWORK_TRANSPORT);
118+
attributes.add(SemanticAttributes.SERVER_ADDRESS);
119+
attributes.add(SemanticAttributes.SERVER_PORT);
120+
}
121+
if (SemconvStability.emitOldHttpSemconv()) {
122+
attributes.add(SemanticAttributes.NET_SOCK_PEER_ADDR);
123+
attributes.add(SemanticAttributes.NET_SOCK_PEER_NAME);
124+
attributes.add(SemanticAttributes.NET_SOCK_PEER_PORT);
125+
}
126+
127+
((ExtendedDoubleHistogramBuilder) builder).setAttributesAdvice(attributes);
128+
}
129+
130+
@SuppressWarnings("deprecation") // until old http semconv are dropped in 2.0
131+
static void applyRecordSizeAdvice(DoubleHistogramBuilder builder) {
132+
if (!(builder instanceof ExtendedDoubleHistogramBuilder)) {
133+
return;
134+
}
135+
136+
List<AttributeKey<?>> attributes = new ArrayList<>();
137+
attributes.add(SemanticAttributes.DB_SYSTEM);
138+
attributes.add(SemanticAttributes.DB_OPERATION);
139+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_NAMESPACE);
140+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_SET_NAME);
141+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_USER_KEY);
142+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_ERROR_CODE);
143+
attributes.add(AerospikeSemanticAttributes.AEROSPIKE_STATUS);
144+
if (SemconvStability.emitStableHttpSemconv()) {
145+
attributes.add(SemanticAttributes.NETWORK_TYPE);
146+
attributes.add(SemanticAttributes.NETWORK_TRANSPORT);
147+
attributes.add(SemanticAttributes.SERVER_ADDRESS);
148+
attributes.add(SemanticAttributes.SERVER_PORT);
149+
}
150+
if (SemconvStability.emitOldHttpSemconv()) {
151+
attributes.add(SemanticAttributes.NET_SOCK_PEER_ADDR);
152+
attributes.add(SemanticAttributes.NET_SOCK_PEER_NAME);
153+
attributes.add(SemanticAttributes.NET_SOCK_PEER_PORT);
154+
}
155+
156+
((ExtendedDoubleHistogramBuilder) builder).setAttributesAdvice(attributes);
157+
}
158+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package io.opentelemetry.instrumentation.api.instrumenter.db;
2+
3+
import static io.opentelemetry.api.common.AttributeKey.longKey;
4+
import static io.opentelemetry.api.common.AttributeKey.stringKey;
5+
6+
import io.opentelemetry.api.common.AttributeKey;
7+
8+
public final class AerospikeSemanticAttributes {
9+
private AerospikeSemanticAttributes() {}
10+
11+
public static final AttributeKey<String> AEROSPIKE_STATUS = stringKey("aerospike.status");
12+
public static final AttributeKey<Long> AEROSPIKE_ERROR_CODE = longKey("aerospike.error.code");
13+
public static final AttributeKey<String> AEROSPIKE_NAMESPACE = stringKey("aerospike.namespace");
14+
public static final AttributeKey<String> AEROSPIKE_SET_NAME = stringKey("aerospike.set.name");
15+
public static final AttributeKey<String> AEROSPIKE_USER_KEY = stringKey("aerospike.user.key");
16+
public static final AttributeKey<Long> AEROSPIKE_TRANSFER_SIZE = longKey(
17+
"aerospike.transfer.size");
18+
19+
public static final class DbSystemValues {
20+
public static final String AEROSPIKE = "aerospike";
21+
22+
private DbSystemValues() {}
23+
}
24+
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package io.opentelemetry.instrumentation.api.instrumenter.db;
2+
3+
import io.opentelemetry.api.common.AttributeKey;
4+
import io.opentelemetry.api.common.Attributes;
5+
import javax.annotation.Nullable;
6+
7+
final class DbMessageSizeUtil {
8+
9+
@Nullable
10+
static Long getMessageSize(Attributes... attributesList) {
11+
return getAttribute(AerospikeSemanticAttributes.AEROSPIKE_TRANSFER_SIZE, attributesList);
12+
}
13+
14+
@Nullable
15+
private static <T> T getAttribute(AttributeKey<T> key, Attributes... attributesList) {
16+
for (Attributes attributes : attributesList) {
17+
T value = attributes.get(key);
18+
if (value != null) {
19+
return value;
20+
}
21+
}
22+
return null;
23+
}
24+
25+
private DbMessageSizeUtil() {}
26+
}
27+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
plugins {
2+
id("otel.javaagent-instrumentation")
3+
}
4+
5+
muzzle {
6+
pass {
7+
group.set("com.aerospike")
8+
module.set("aerospike-client")
9+
versions.set("[7.1.0,)")
10+
assertInverse.set(true)
11+
}
12+
}
13+
14+
dependencies {
15+
library("com.aerospike:aerospike-client:7.1.0")
16+
17+
compileOnly("com.google.auto.value:auto-value-annotations")
18+
annotationProcessor("com.google.auto.value:auto-value")
19+
}
20+
21+
tasks {
22+
test {
23+
jvmArgs("-Djava.net.preferIPv4Stack=true")
24+
usesService(gradle.sharedServices.registrations["testcontainersBuildService"].service)
25+
}
26+
}

0 commit comments

Comments
 (0)