Skip to content

Commit 9ae8287

Browse files
committed
Added grpc calls metrics
1 parent 1525e10 commit 9ae8287

File tree

3 files changed

+137
-0
lines changed

3 files changed

+137
-0
lines changed

jdbc/ydb-token-app/src/main/java/tech/ydb/apps/Application.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ public static void main(String[] args) {
5757
private volatile boolean isStopped = false;
5858

5959
public Application(Config config, SchemeService schemeService, TokenService tokenService, MeterRegistry registry) {
60+
GrpcMetrics.init(registry);
61+
6062
this.config = config;
6163
this.schemeService = schemeService;
6264
this.tokenService = tokenService;
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package tech.ydb.apps;
2+
3+
import java.util.function.Consumer;
4+
5+
import javax.annotation.Nullable;
6+
7+
import io.grpc.Attributes;
8+
import io.grpc.CallOptions;
9+
import io.grpc.Channel;
10+
import io.grpc.ClientCall;
11+
import io.grpc.ClientInterceptor;
12+
import io.grpc.ManagedChannelBuilder;
13+
import io.grpc.Metadata;
14+
import io.grpc.MethodDescriptor;
15+
import io.grpc.Status;
16+
import io.micrometer.core.instrument.Counter;
17+
import io.micrometer.core.instrument.MeterRegistry;
18+
19+
/**
20+
*
21+
* @author Aleksandr Gorshenin
22+
*/
23+
public class GrpcMetrics implements Consumer<ManagedChannelBuilder<?>>, ClientInterceptor {
24+
private static final Counter.Builder REQUEST = Counter.builder("grpc.request");
25+
private static final Counter.Builder RESPONSE = Counter.builder("grpc.response");
26+
27+
private static MeterRegistry REGISTRY = null;
28+
29+
public static void init(MeterRegistry registry) {
30+
REGISTRY = registry;
31+
}
32+
33+
@Override
34+
public void accept(ManagedChannelBuilder<?> t) {
35+
t.intercept(this);
36+
}
37+
38+
@Override
39+
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
40+
MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
41+
if (REGISTRY != null) {
42+
return new ProxyClientCall<>(REGISTRY, next, method, callOptions);
43+
}
44+
return next.newCall(method, callOptions);
45+
}
46+
47+
private static class ProxyClientCall<ReqT, RespT> extends ClientCall<ReqT, RespT> {
48+
private final MeterRegistry registry;
49+
private final String method;
50+
private final String authority;
51+
private final ClientCall<ReqT, RespT> delegate;
52+
53+
private ProxyClientCall(MeterRegistry registry, Channel channel, MethodDescriptor<ReqT, RespT> method,
54+
CallOptions callOptions) {
55+
this.registry = registry;
56+
this.method = method.getBareMethodName();
57+
this.authority = channel.authority();
58+
this.delegate = channel.newCall(method, callOptions);
59+
}
60+
61+
@Override
62+
public void request(int numMessages) {
63+
delegate.request(numMessages);
64+
}
65+
66+
@Override
67+
public void cancel(@Nullable String message, @Nullable Throwable cause) {
68+
delegate.cancel(message, cause);
69+
}
70+
71+
@Override
72+
public void halfClose() {
73+
delegate.halfClose();
74+
}
75+
76+
@Override
77+
public void setMessageCompression(boolean enabled) {
78+
delegate.setMessageCompression(enabled);
79+
}
80+
81+
@Override
82+
public boolean isReady() {
83+
return delegate.isReady();
84+
}
85+
86+
@Override
87+
public Attributes getAttributes() {
88+
return delegate.getAttributes();
89+
}
90+
91+
@Override
92+
public void start(Listener<RespT> listener, Metadata headers) {
93+
REQUEST.tag("method", method).tag("authority", authority).register(registry).increment();
94+
delegate.start(new ProxyListener(listener), headers);
95+
}
96+
97+
@Override
98+
public void sendMessage(ReqT message) {
99+
delegate.sendMessage(message);
100+
}
101+
102+
private class ProxyListener extends Listener<RespT> {
103+
private final Listener<RespT> delegate;
104+
105+
public ProxyListener(Listener<RespT> delegate) {
106+
this.delegate = delegate;
107+
}
108+
109+
110+
@Override
111+
public void onHeaders(Metadata headers) {
112+
delegate.onHeaders(headers);
113+
}
114+
115+
@Override
116+
public void onMessage(RespT message) {
117+
delegate.onMessage(message);
118+
}
119+
120+
@Override
121+
public void onClose(Status status, Metadata trailers) {
122+
RESPONSE.tag("method", method).tag("authority", authority).tag("status", status.getCode().toString())
123+
.register(registry).increment();
124+
delegate.onClose(status, trailers);
125+
}
126+
127+
@Override
128+
public void onReady() {
129+
delegate.onReady();
130+
}
131+
}
132+
}
133+
}

jdbc/ydb-token-app/src/main/resources/application.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ spring.datasource.driver-class-name=tech.ydb.jdbc.YdbDriver
1313

1414
spring.datasource.hikari.maximum-pool-size=200
1515
spring.datasource.hikari.data-source-properties.enableTxTracer=true
16+
spring.datasource.hikari.data-source-properties.channelInitializer=tech.ydb.apps.GrpcMetrics
1617

1718
spring.jpa.properties.hibernate.jdbc.batch_size=1000
1819
spring.jpa.properties.hibernate.order_updates=true
@@ -23,6 +24,7 @@ spring.jpa.properties.hibernate.dialect=tech.ydb.hibernate.dialect.YdbDialect
2324
management.metrics.enable.all=false
2425
management.metrics.enable.jdbc=true
2526
management.metrics.enable.sdk=true
27+
management.metrics.enable.grpc=true
2628
management.metrics.distribution.percentiles-histogram.all=true
2729
management.metrics.export.prometheus.pushgateway.enabled=${app.pushMetrics}
2830
management.metrics.export.prometheus.pushgateway.push-rate=15s

0 commit comments

Comments
 (0)