Skip to content

Commit 177d547

Browse files
grpc metrics and minor refactoring (#62)
* grpc metrics * Grpc metrics suggestions (#61) * refactor: example * upgrade grpc-utils lib to the latest Co-authored-by: Laxman Ch <[email protected]> * refactor default tags mechanism * review comments fix Co-authored-by: Aaron Steinfeld <[email protected]>
1 parent 11e9213 commit 177d547

File tree

5 files changed

+69
-49
lines changed

5 files changed

+69
-49
lines changed

platform-grpc-service-framework/build.gradle.kts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@ dependencies {
1010
api(platform("io.grpc:grpc-bom:1.47.0"))
1111
api("io.grpc:grpc-api")
1212
api("io.grpc:grpc-services")
13-
api("org.hypertrace.core.grpcutils:grpc-client-utils:0.9.1")
13+
api("org.hypertrace.core.grpcutils:grpc-client-utils:0.10.0")
1414
api("com.typesafe:config:1.4.2")
1515
api(project(":service-framework-spi"))
1616

1717
annotationProcessor("org.projectlombok:lombok:1.18.24")
1818
compileOnly("org.projectlombok:lombok:1.18.24")
1919

20+
implementation(project(":platform-metrics"))
2021
implementation("org.slf4j:slf4j-api:1.7.36")
21-
implementation("org.hypertrace.core.grpcutils:grpc-server-utils:0.9.1")
22+
implementation("org.hypertrace.core.grpcutils:grpc-server-utils:0.10.0")
2223
}

platform-grpc-service-framework/src/main/java/org/hypertrace/core/serviceframework/grpc/ConsolidatedGrpcPlatformServiceContainer.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,6 @@ public ConsolidatedGrpcPlatformServiceContainer(ConfigClient configClient) {
2121
super(configClient);
2222
}
2323

24-
@Override
25-
protected InProcessGrpcChannelRegistry buildChannelRegistry() {
26-
return new InProcessGrpcChannelRegistry(
27-
this.getAuthorityInProcessOverrideMap(this.getInProcessServerName()));
28-
}
29-
3024
@Override
3125
protected GrpcServiceContainerEnvironment buildContainerEnvironment(
3226
InProcessGrpcChannelRegistry channelRegistry, HealthStatusManager healthStatusManager) {
@@ -63,8 +57,10 @@ protected Collection<String> getAuthoritiesToTreatAsInProcess() {
6357
return Collections.emptySet();
6458
}
6559

66-
private Map<String, String> getAuthorityInProcessOverrideMap(String inProcessName) {
60+
protected Map<String, String> getAuthorityInProcessOverrideMap() {
6761
return this.getAuthoritiesToTreatAsInProcess().stream()
68-
.collect(Collectors.toUnmodifiableMap(Function.identity(), unused -> inProcessName));
62+
.collect(
63+
Collectors.toUnmodifiableMap(
64+
Function.identity(), unused -> this.getInProcessServerName()));
6965
}
7066
}

platform-grpc-service-framework/src/main/java/org/hypertrace/core/serviceframework/grpc/GrpcPlatformServiceContainer.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
import io.grpc.health.v1.HealthGrpc.HealthBlockingStub;
1313
import io.grpc.inprocess.InProcessServerBuilder;
1414
import io.grpc.protobuf.services.HealthStatusManager;
15+
import io.micrometer.core.instrument.binder.grpc.MetricCollectingClientInterceptor;
1516
import java.io.IOException;
1617
import java.util.Collection;
18+
import java.util.Collections;
1719
import java.util.LinkedList;
1820
import java.util.List;
1921
import java.util.Map;
@@ -23,13 +25,17 @@
2325
import java.util.function.Function;
2426
import java.util.stream.Collectors;
2527
import java.util.stream.Stream;
28+
29+
import io.micrometer.core.instrument.binder.grpc.MetricCollectingServerInterceptor;
2630
import lombok.Value;
2731
import lombok.extern.slf4j.Slf4j;
32+
import org.hypertrace.core.grpcutils.client.GrpcRegistryConfig;
2833
import org.hypertrace.core.grpcutils.client.InProcessGrpcChannelRegistry;
2934
import org.hypertrace.core.grpcutils.server.InterceptorUtil;
3035
import org.hypertrace.core.grpcutils.server.ServerManagementUtil;
3136
import org.hypertrace.core.serviceframework.PlatformService;
3237
import org.hypertrace.core.serviceframework.config.ConfigClient;
38+
import org.hypertrace.core.serviceframework.metrics.PlatformMetricsRegistry;
3339
import org.hypertrace.core.serviceframework.spi.PlatformServiceLifecycle.State;
3440

3541
@Slf4j
@@ -56,6 +62,8 @@ protected void doInit() {
5662
.collect(Collectors.toUnmodifiableMap(Function.identity(), this::initializeBuilder));
5763
final ServerBuilder<?> inProcessServerBuilder =
5864
InProcessServerBuilder.forName(this.getInProcessServerName())
65+
.intercept(
66+
new MetricCollectingServerInterceptor(PlatformMetricsRegistry.getMeterRegistry()))
5967
.addService(this.healthStatusManager.getHealthService());
6068
final GrpcServiceContainerEnvironment serviceContainerEnvironment =
6169
this.buildContainerEnvironment(this.grpcChannelRegistry, this.healthStatusManager);
@@ -186,7 +194,12 @@ public boolean healthCheck() {
186194
}
187195

188196
protected InProcessGrpcChannelRegistry buildChannelRegistry() {
189-
return new InProcessGrpcChannelRegistry();
197+
return new InProcessGrpcChannelRegistry(
198+
this.getAuthorityInProcessOverrideMap(),
199+
GrpcRegistryConfig.builder()
200+
.defaultInterceptor(
201+
new MetricCollectingClientInterceptor(PlatformMetricsRegistry.getMeterRegistry()))
202+
.build());
190203
}
191204

192205
protected String getInProcessServerName() {
@@ -211,6 +224,10 @@ protected void registerManagedPeriodicTask(PlatformPeriodicTaskDefinition period
211224
}
212225
}
213226

227+
protected Map<String, String> getAuthorityInProcessOverrideMap() {
228+
return Collections.emptyMap();
229+
}
230+
214231
protected abstract List<GrpcPlatformServerDefinition> getServerDefinitions();
215232

216233
protected abstract GrpcServiceContainerEnvironment buildContainerEnvironment(
@@ -222,6 +239,9 @@ private ServerBuilder<?> initializeBuilder(GrpcPlatformServerDefinition serverDe
222239
if (serverDefinition.getMaxInboundMessageSize() > 0) {
223240
builder.maxInboundMessageSize(serverDefinition.getMaxInboundMessageSize());
224241
}
242+
// add micrometer-grpc interceptor to collect server metrics.
243+
builder.intercept(
244+
new MetricCollectingServerInterceptor(PlatformMetricsRegistry.getMeterRegistry()));
225245

226246
serverDefinition.getServerInterceptors().forEach(builder::intercept);
227247
return builder;

platform-http-service-framework/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ plugins {
55

66
dependencies {
77
api(project(":platform-service-framework"))
8-
api("org.hypertrace.core.grpcutils:grpc-client-utils:0.9.1")
8+
api("org.hypertrace.core.grpcutils:grpc-client-utils:0.10.0")
99
api("com.typesafe:config:1.4.2")
1010
api("javax.servlet:javax.servlet-api:4.0.1")
1111
api("com.google.inject:guice:5.1.0")

platform-metrics/src/main/java/org/hypertrace/core/serviceframework/metrics/PlatformMetricsRegistry.java

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.typesafe.config.Config;
1313
import io.github.mweirauch.micrometer.jvm.extras.ProcessMemoryMetrics;
1414
import io.github.mweirauch.micrometer.jvm.extras.ProcessThreadMetrics;
15+
import io.micrometer.common.util.StringUtils;
1516
import io.micrometer.core.instrument.Clock;
1617
import io.micrometer.core.instrument.Counter;
1718
import io.micrometer.core.instrument.DistributionSummary;
@@ -33,7 +34,6 @@
3334
import io.micrometer.core.instrument.logging.LoggingMeterRegistry;
3435
import io.micrometer.core.instrument.logging.LoggingRegistryConfig;
3536
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
36-
import io.micrometer.core.instrument.util.StringUtils;
3737
import io.micrometer.core.lang.NonNull;
3838
import io.micrometer.core.lang.Nullable;
3939
import io.micrometer.prometheus.PrometheusConfig;
@@ -42,6 +42,7 @@
4242
import io.prometheus.client.dropwizard.DropwizardExports;
4343
import io.prometheus.client.exporter.PushGateway;
4444
import java.time.Duration;
45+
import java.util.ArrayList;
4546
import java.util.HashMap;
4647
import java.util.HashSet;
4748
import java.util.List;
@@ -98,20 +99,19 @@ public class PlatformMetricsRegistry {
9899

99100
}};
100101
private static boolean isInit = false;
101-
private static final Set<Tag> DEFAULT_TAGS = new HashSet<>();
102102

103103
/**
104104
* Main MetricMeter registry, with which all the metrics should be registered. We use
105105
* a {@link CompositeMeterRegistry} here so that we can even registry multiple registries
106106
* like Prometheus and Logging registries, if needed.
107107
*/
108-
private static final CompositeMeterRegistry METER_REGISTRY = new CompositeMeterRegistry();
108+
private static CompositeMeterRegistry meterRegistry = new CompositeMeterRegistry();
109109

110110
private static void initPrometheusReporter(int reportInterval) {
111111
LOGGER.info("Trying to init PrometheusReporter");
112112

113113
// Add Prometheus registry to the composite registry.
114-
METER_REGISTRY.add(new PrometheusMeterRegistry(new PrometheusConfig() {
114+
meterRegistry.add(new PrometheusMeterRegistry(new PrometheusConfig() {
115115
@Override
116116
@NonNull
117117
public Duration step() {
@@ -138,7 +138,7 @@ private static void initConsoleMetricsReporter(final int reportIntervalSec) {
138138
private static void initLoggingMetricsReporter(int reportIntervalSec) {
139139
LOGGER.info("Initializing the logging metric reporter.");
140140

141-
METER_REGISTRY.add(new LoggingMeterRegistry(new LoggingRegistryConfig() {
141+
meterRegistry.add(new LoggingMeterRegistry(new LoggingRegistryConfig() {
142142
@Override
143143
@NonNull
144144
public Duration step() {
@@ -156,7 +156,7 @@ public String get(String key) {
156156
private static void initTestingMetricsReporter() {
157157
LOGGER.info("Initializing the testing metric reporter.");
158158

159-
METER_REGISTRY.add(new SimpleMeterRegistry());
159+
meterRegistry.add(new SimpleMeterRegistry());
160160
}
161161

162162
private static void initPrometheusPushGatewayReporter(String serviceName,
@@ -170,7 +170,7 @@ private static void initPrometheusPushGatewayReporter(String serviceName,
170170
throw new IllegalArgumentException("pushUrlAddress configuration is not specified.");
171171
}
172172

173-
METER_REGISTRY.add(new PrometheusPushMeterRegistry(
173+
meterRegistry.add(new PrometheusPushMeterRegistry(
174174
new PrometheusPushRegistryConfig() {
175175
@Override
176176
public String jobName() {
@@ -261,19 +261,21 @@ public synchronized static void initMetricsRegistry(String serviceName, Config c
261261
}
262262

263263
LOGGER.info("Setting default tags for all metrics to: {}", defaultTags);
264-
defaultTags.forEach((key, value) -> DEFAULT_TAGS.add(new ImmutableTag(key, value)));
264+
defaultTags.forEach((key, value) -> {
265+
meterRegistry.config().commonTags(List.of((new ImmutableTag(key, value))));
266+
});
265267

266268
// Register different metrics with the registry.
267-
new ClassLoaderMetrics(DEFAULT_TAGS).bindTo(METER_REGISTRY);
268-
new JvmGcMetrics(DEFAULT_TAGS).bindTo(METER_REGISTRY);
269-
new ProcessorMetrics(DEFAULT_TAGS).bindTo(METER_REGISTRY);
270-
new JvmThreadMetrics(DEFAULT_TAGS).bindTo(METER_REGISTRY);
271-
new JvmMemoryMetrics(DEFAULT_TAGS).bindTo(METER_REGISTRY);
272-
new UptimeMetrics(DEFAULT_TAGS).bindTo(METER_REGISTRY);
273-
new Log4j2Metrics(DEFAULT_TAGS).bindTo(METER_REGISTRY);
269+
new ClassLoaderMetrics().bindTo(meterRegistry);
270+
new JvmGcMetrics().bindTo(meterRegistry);
271+
new ProcessorMetrics().bindTo(meterRegistry);
272+
new JvmThreadMetrics().bindTo(meterRegistry);
273+
new JvmMemoryMetrics().bindTo(meterRegistry);
274+
new UptimeMetrics().bindTo(meterRegistry);
275+
new Log4j2Metrics().bindTo(meterRegistry);
274276

275-
new ProcessMemoryMetrics().bindTo(METER_REGISTRY);
276-
new ProcessThreadMetrics().bindTo(METER_REGISTRY);
277+
new ProcessMemoryMetrics().bindTo(meterRegistry);
278+
new ProcessThreadMetrics().bindTo(meterRegistry);
277279

278280
for (String key : DEFAULT_METRIC_SET.keySet()) {
279281
METRIC_REGISTRY
@@ -302,7 +304,7 @@ public static void register(String metricName, Metric metric) {
302304
* See https://micrometer.io/docs/concepts#_counters for more details on the Counter.
303305
*/
304306
public static Counter registerCounter(String name, Map<String, String> tags) {
305-
return METER_REGISTRY.counter(name, addDefaultTags(tags));
307+
return meterRegistry.counter(name, toIterable(tags));
306308
}
307309

308310
/**
@@ -326,11 +328,12 @@ public static Timer registerTimer(String name, Map<String, String> tags) {
326328
public static Timer registerTimer(String name, Map<String, String> tags, boolean histogram) {
327329
Timer.Builder builder = Timer.builder(name)
328330
.publishPercentiles(0.5, 0.95, 0.99)
329-
.tags(addDefaultTags(tags));
331+
.tags(toIterable(tags));
332+
330333
if (histogram) {
331334
builder = builder.publishPercentileHistogram();
332335
}
333-
return builder.register(METER_REGISTRY);
336+
return builder.register(meterRegistry);
334337
}
335338

336339
/**
@@ -341,7 +344,7 @@ public static Timer registerTimer(String name, Map<String, String> tags, boolean
341344
* See https://micrometer.io/docs/concepts#_gauges for more details on the Gauges.
342345
*/
343346
public static <T extends Number> T registerGauge(String name, Map<String, String> tags, T number) {
344-
Gauge.builder(name, number, Number::doubleValue).tags(addDefaultTags(tags)).strongReference(true).register(METER_REGISTRY);
347+
Gauge.builder(name, number, Number::doubleValue).tags(toIterable(tags)).strongReference(true).register(meterRegistry);
345348
return number;
346349
}
347350

@@ -372,19 +375,19 @@ public static DistributionSummary registerDistributionSummary(String name,
372375
Map<String, String> tags, boolean histogram) {
373376
DistributionSummary.Builder builder = DistributionSummary.builder(name)
374377
.publishPercentiles(0.5, 0.95, 0.99)
375-
.tags(addDefaultTags(tags));
378+
.tags(toIterable(tags));
376379
if (histogram) {
377380
builder = builder.publishPercentileHistogram();
378381
}
379-
return builder.register(METER_REGISTRY);
382+
return builder.register(meterRegistry);
380383
}
381384

382385
/**
383386
* Registers metrics for GuavaCaches using micrometer's GuavaCacheMetrics under the given
384387
* cacheName for the given guavaCache
385388
*/
386389
public static <K, V> void registerCache(String cacheName, Cache<K, V> guavaCache, Map<String, String> tags) {
387-
GuavaCacheMetrics.monitor(METER_REGISTRY, guavaCache, cacheName, addDefaultTags(tags));
390+
GuavaCacheMetrics.monitor(meterRegistry, guavaCache, cacheName, toIterable(tags));
388391

389392
}
390393

@@ -397,16 +400,16 @@ public static <K, V> void registerCache(String cacheName, Cache<K, V> guavaCache
397400
*/
398401
public static void monitorExecutorService(String name, ExecutorService executorService,
399402
@Nullable Map<String, String> tags) {
400-
new ExecutorServiceMetrics(executorService, name, addDefaultTags(tags)).bindTo(METER_REGISTRY);
403+
new ExecutorServiceMetrics(executorService, name, toIterable(tags)).bindTo(meterRegistry);
401404
}
402405

403-
private static Iterable<Tag> addDefaultTags(Map<String, String> tags) {
404-
if (tags == null || tags.isEmpty()) {
405-
return DEFAULT_TAGS;
406+
private static Iterable<Tag> toIterable(Map<String, String> tags) {
407+
List<Tag> newTags = new ArrayList<>();
408+
409+
if (tags != null) {
410+
tags.forEach((k, v) -> newTags.add(new ImmutableTag(k, v)));
406411
}
407412

408-
Set<Tag> newTags = new HashSet<>(DEFAULT_TAGS);
409-
tags.forEach((k, v) -> newTags.add(new ImmutableTag(k, v)));
410413
return newTags;
411414
}
412415

@@ -415,22 +418,22 @@ public static MetricRegistry getMetricRegistry() {
415418
}
416419

417420
public static MeterRegistry getMeterRegistry() {
418-
return METER_REGISTRY;
421+
return meterRegistry;
419422
}
420423

421424
public static synchronized void stop() {
422425
stopConsoleMetricsReporter();
423426
METRIC_REGISTRY.getNames().forEach(METRIC_REGISTRY::remove);
424427

425-
DEFAULT_TAGS.clear();
426428
/* For each meter registry in this composite, it will call the close function */
427-
METER_REGISTRY.getRegistries().forEach(MeterRegistry::close);
428-
METER_REGISTRY.forEachMeter(METER_REGISTRY::remove);
429-
METER_REGISTRY.getRegistries().forEach(MeterRegistry::clear);
430-
Set<MeterRegistry> registries = new HashSet<>(METER_REGISTRY.getRegistries());
431-
registries.forEach(METER_REGISTRY::remove);
429+
meterRegistry.getRegistries().forEach(MeterRegistry::close);
430+
meterRegistry.forEachMeter(meterRegistry::remove);
431+
meterRegistry.getRegistries().forEach(MeterRegistry::clear);
432+
Set<MeterRegistry> registries = new HashSet<>(meterRegistry.getRegistries());
433+
registries.forEach(meterRegistry::remove);
432434
registries.clear();
433435
CollectorRegistry.defaultRegistry.clear();
436+
meterRegistry = new CompositeMeterRegistry();
434437
isInit = false;
435438
}
436439

0 commit comments

Comments
 (0)