Skip to content

Commit a5c1412

Browse files
authored
Collect JVM memory metrics (#2937)
* add jvm metrics * include all changes * Fix tests and lint errors * Fix formatting * Instantiate jvmmetrics class in stackdriver module * add metrics registration behaviour and explicit call * redo tests * fix formatting/variable name * lint
1 parent 41393e5 commit a5c1412

File tree

3 files changed

+205
-2
lines changed

3 files changed

+205
-2
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package google.registry.monitoring.whitebox;
16+
17+
import com.google.common.base.Supplier;
18+
import com.google.common.collect.ImmutableList;
19+
import com.google.common.collect.ImmutableMap;
20+
import com.google.common.collect.ImmutableSet;
21+
import com.google.monitoring.metrics.LabelDescriptor;
22+
import com.google.monitoring.metrics.MetricRegistry;
23+
import com.google.monitoring.metrics.MetricRegistryImpl;
24+
import jakarta.inject.Inject;
25+
import jakarta.inject.Singleton;
26+
import java.lang.management.ManagementFactory;
27+
import java.lang.management.MemoryMXBean;
28+
import java.lang.management.MemoryUsage;
29+
30+
/** Exposes JVM metrics. */
31+
@Singleton
32+
class JvmMetrics {
33+
34+
private static final ImmutableSet<LabelDescriptor> TYPE_LABEL_SET =
35+
ImmutableSet.of(LabelDescriptor.create("type", "Memory type (e.g., heap, non_heap)"));
36+
private final MemoryMXBean memoryMxBean;
37+
38+
@Inject
39+
JvmMetrics() {
40+
this(ManagementFactory.getMemoryMXBean());
41+
}
42+
43+
/** Constructor for testing. */
44+
JvmMetrics(MemoryMXBean memoryMxBean) {
45+
this.memoryMxBean = memoryMxBean;
46+
}
47+
48+
/** Registers JVM gauges with the default registry. */
49+
void register() {
50+
MetricRegistry registry = MetricRegistryImpl.getDefault();
51+
52+
registry.newGauge(
53+
"/jvm/memory/used",
54+
"Current memory usage in bytes",
55+
"bytes",
56+
TYPE_LABEL_SET,
57+
(Supplier<ImmutableMap<ImmutableList<String>, Long>>) this::getUsedMemory,
58+
Long.class);
59+
60+
registry.newGauge(
61+
"/jvm/memory/committed",
62+
"Committed memory in bytes",
63+
"bytes",
64+
TYPE_LABEL_SET,
65+
(Supplier<ImmutableMap<ImmutableList<String>, Long>>) this::getCommittedMemory,
66+
Long.class);
67+
68+
registry.newGauge(
69+
"/jvm/memory/max",
70+
"Maximum memory in bytes",
71+
"bytes",
72+
TYPE_LABEL_SET,
73+
(Supplier<ImmutableMap<ImmutableList<String>, Long>>) this::getMaxMemory,
74+
Long.class);
75+
}
76+
77+
ImmutableMap<ImmutableList<String>, Long> getUsedMemory() {
78+
MemoryUsage heapUsage = memoryMxBean.getHeapMemoryUsage();
79+
MemoryUsage nonHeapUsage = memoryMxBean.getNonHeapMemoryUsage();
80+
81+
return ImmutableMap.of(
82+
ImmutableList.of("heap"), heapUsage.getUsed(),
83+
ImmutableList.of("non_heap"), nonHeapUsage.getUsed());
84+
}
85+
86+
ImmutableMap<ImmutableList<String>, Long> getCommittedMemory() {
87+
MemoryUsage heapUsage = memoryMxBean.getHeapMemoryUsage();
88+
MemoryUsage nonHeapUsage = memoryMxBean.getNonHeapMemoryUsage();
89+
90+
return ImmutableMap.of(
91+
ImmutableList.of("heap"), heapUsage.getCommitted(),
92+
ImmutableList.of("non_heap"), nonHeapUsage.getCommitted());
93+
}
94+
95+
ImmutableMap<ImmutableList<String>, Long> getMaxMemory() {
96+
MemoryUsage heapUsage = memoryMxBean.getHeapMemoryUsage();
97+
MemoryUsage nonHeapUsage = memoryMxBean.getNonHeapMemoryUsage();
98+
99+
return ImmutableMap.of(
100+
ImmutableList.of("heap"), heapUsage.getMax(),
101+
ImmutableList.of("non_heap"), nonHeapUsage.getMax());
102+
}
103+
}

core/src/main/java/google/registry/monitoring/whitebox/StackdriverModule.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
import jakarta.inject.Singleton;
3333
import org.joda.time.Duration;
3434

35-
/** Dagger module for Google Stackdriver service connection objects. */
35+
/** Dagger module for monitoring and Google Stackdriver service connection objects. */
3636
@Module
3737
public final class StackdriverModule {
3838

@@ -77,7 +77,11 @@ static MetricWriter provideMetricWriter(
7777

7878
@Provides
7979
static MetricReporter provideMetricReporter(
80-
MetricWriter metricWriter, @Config("metricsWriteInterval") Duration writeInterval) {
80+
MetricWriter metricWriter,
81+
@Config("metricsWriteInterval") Duration writeInterval,
82+
JvmMetrics jvmMetrics) {
83+
jvmMetrics.register();
84+
8185
return new MetricReporter(
8286
metricWriter,
8387
writeInterval.getStandardSeconds(),
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package google.registry.monitoring.whitebox;
16+
17+
import static com.google.common.truth.Truth.assertThat;
18+
import static org.mockito.Mockito.mock;
19+
import static org.mockito.Mockito.when;
20+
21+
import com.google.common.collect.ImmutableList;
22+
import com.google.common.collect.ImmutableMap;
23+
import com.google.monitoring.metrics.MetricRegistry;
24+
import com.google.monitoring.metrics.MetricRegistryImpl;
25+
import java.lang.management.MemoryMXBean;
26+
import java.lang.management.MemoryUsage;
27+
import org.junit.jupiter.api.BeforeEach;
28+
import org.junit.jupiter.api.Test;
29+
30+
/** Unit tests for {@link JvmMetrics}. */
31+
class JvmMetricsTests {
32+
33+
private MetricRegistry registry;
34+
private JvmMetrics jvmMetrics;
35+
private MemoryMXBean mockMemoryMXBean = mock(MemoryMXBean.class);
36+
37+
private static final MemoryUsage HEAP_USAGE =
38+
new MemoryUsage(/*init*/ 100, /*used*/ 200, /*commited*/ 500, /*max*/ 1000);
39+
private static final MemoryUsage NON_HEAP_USAGE =
40+
new MemoryUsage(/*init*/ 50, /*used*/ 100, /*commited*/ 250, /*max*/ 500);
41+
42+
@BeforeEach
43+
public void setUp() {
44+
MetricRegistryImpl.getDefault().unregisterAllMetrics();
45+
registry = MetricRegistryImpl.getDefault();
46+
47+
when(mockMemoryMXBean.getHeapMemoryUsage()).thenReturn(HEAP_USAGE);
48+
when(mockMemoryMXBean.getNonHeapMemoryUsage()).thenReturn(NON_HEAP_USAGE);
49+
50+
jvmMetrics = new JvmMetrics(mockMemoryMXBean);
51+
}
52+
53+
@Test
54+
public void metricsRegistered() {
55+
jvmMetrics.register();
56+
57+
assertThat(registry.getRegisteredMetrics()).hasSize(3);
58+
59+
for (var metric : registry.getRegisteredMetrics()) {
60+
assertThat(metric).isInstanceOf(com.google.monitoring.metrics.VirtualMetric.class);
61+
}
62+
}
63+
64+
@Test
65+
public void testGetUsedMemory() {
66+
jvmMetrics.register();
67+
ImmutableMap<ImmutableList<String>, Long> values = jvmMetrics.getUsedMemory();
68+
69+
assertThat(values)
70+
.containsExactly(
71+
ImmutableList.of("heap"), 200L,
72+
ImmutableList.of("non_heap"), 100L);
73+
}
74+
75+
@Test
76+
public void testGetCommittedMemory() {
77+
jvmMetrics.register();
78+
ImmutableMap<ImmutableList<String>, Long> values = jvmMetrics.getCommittedMemory();
79+
80+
assertThat(values)
81+
.containsExactly(
82+
ImmutableList.of("heap"), 500L,
83+
ImmutableList.of("non_heap"), 250L);
84+
}
85+
86+
@Test
87+
public void testGetMaxMemory() {
88+
jvmMetrics.register();
89+
ImmutableMap<ImmutableList<String>, Long> values = jvmMetrics.getMaxMemory();
90+
91+
assertThat(values)
92+
.containsExactly(
93+
ImmutableList.of("heap"), 1000L,
94+
ImmutableList.of("non_heap"), 500L);
95+
}
96+
}

0 commit comments

Comments
 (0)