Skip to content

Commit

Permalink
[AMORO_3053]Add system metric for ams service (#3055)
Browse files Browse the repository at this point in the history
* add system metric for ams service

* add doc

* change code for commit
  • Loading branch information
xieyi888 authored Jul 29, 2024
1 parent 8b9822d commit b3d794a
Show file tree
Hide file tree
Showing 4 changed files with 297 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public class AmoroServiceContainer {
private TServer tableManagementServer;
private TServer optimizingServiceServer;
private Javalin httpServer;
private AmsServiceMetrics amsServiceMetrics;

public AmoroServiceContainer() throws Exception {
initConfig();
Expand Down Expand Up @@ -164,6 +165,7 @@ public void startService() throws Exception {

initHttpService();
startHttpService();
registerAmsServiceMetric();
}

private void addHandlerChain(RuntimeHandlerChain chain) {
Expand Down Expand Up @@ -201,6 +203,10 @@ public void dispose() {
}
optimizingService = null;

if (amsServiceMetrics != null) {
amsServiceMetrics.unregister();
}

EventsManager.dispose();
MetricManager.dispose();
}
Expand Down Expand Up @@ -294,6 +300,11 @@ private void startHttpService() {
LOG.info("Http server start at {}.", port);
}

private void registerAmsServiceMetric() {
amsServiceMetrics = new AmsServiceMetrics(MetricManager.getInstance().getGlobalRegistry());
amsServiceMetrics.register();
}

private void initThriftService() throws TTransportException {
LOG.info("Initializing thrift service...");
long maxMessageSize = serviceConfig.getLong(AmoroManagementConf.THRIFT_MAX_MESSAGE_SIZE);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.amoro.server;

import static org.apache.amoro.api.metrics.MetricDefine.defineGauge;

import org.apache.amoro.api.metrics.Metric;
import org.apache.amoro.api.metrics.MetricDefine;
import org.apache.amoro.api.metrics.MetricKey;
import org.apache.amoro.server.metrics.MetricRegistry;
import org.apache.amoro.shade.guava32.com.google.common.collect.ImmutableMap;
import org.apache.amoro.shade.guava32.com.google.common.collect.Lists;

import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryUsage;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class AmsServiceMetrics {
public static final String GARBAGE_COLLECTOR_TAG = "garbage_collector";
public static final MetricDefine AMS_JVM_CPU_LOAD =
defineGauge("ams_jvm_cpu_load").withDescription("The recent CPU usage of the AMS").build();
public static final MetricDefine AMS_JVM_CPU_TIME =
defineGauge("ams_jvm_cpu_time").withDescription("The CPU time used by the AMS").build();

public static final MetricDefine AMS_JVM_MEMORY_HEAP_USED =
defineGauge("ams_jvm_memory_heap_used")
.withDescription("The amount of heap memory currently used (in bytes) by the AMS")
.build();

public static final MetricDefine AMS_JVM_MEMORY_HEAP_COMMITTED =
defineGauge("ams_jvm_memory_heap_committed")
.withDescription(
"The amount of memory in the heap that is committed for the JVM to use (in bytes)")
.build();

public static final MetricDefine AMS_JVM_MEMORY_HEAP_MAX =
defineGauge("ams_jvm_memory_heap_max")
.withDescription(
"The maximum amount of memory in the heap (in bytes), It's equal to the value specified through -Xmx")
.build();

public static final MetricDefine AMS_JVM_THREADS_COUNT =
defineGauge("ams_jvm_threads_count")
.withDescription("The total number of live threads used by the AMS")
.build();

public static final MetricDefine AMS_JVM_GARBAGE_COLLECTOR_COUNT =
defineGauge("ams_jvm_garbage_collector_count")
.withDescription("The count of the JVM's Garbage Collector")
.withTags(GARBAGE_COLLECTOR_TAG)
.build();

public static final MetricDefine AMS_JVM_GARBAGE_COLLECTOR_TIME =
defineGauge("ams_jvm_garbage_collector_time")
.withDescription("The time of the JVM's Garbage Collector")
.withTags(GARBAGE_COLLECTOR_TAG)
.build();

private final MetricRegistry registry;
private List<MetricKey> registeredMetricKeys = Lists.newArrayList();

public AmsServiceMetrics(MetricRegistry registry) {
this.registry = registry;
}

public void register() {
registerHeapMetric();
registerThreadMetric();
registerCPuMetric();
registerGarbageCollectorMetrics();
}

public void unregister() {
registeredMetricKeys.forEach(registry::unregister);
registeredMetricKeys.clear();
}

private void registerHeapMetric() {
MemoryUsage heapMemoryUsage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
registerMetric(
registry,
AMS_JVM_MEMORY_HEAP_USED,
(org.apache.amoro.api.metrics.Gauge<Long>) () -> heapMemoryUsage.getUsed());

registerMetric(
registry,
AMS_JVM_MEMORY_HEAP_COMMITTED,
(org.apache.amoro.api.metrics.Gauge<Long>) () -> heapMemoryUsage.getCommitted());

registerMetric(
registry,
AMS_JVM_MEMORY_HEAP_MAX,
(org.apache.amoro.api.metrics.Gauge<Long>) () -> heapMemoryUsage.getMax());
}

private void registerThreadMetric() {
registerMetric(
registry,
AMS_JVM_THREADS_COUNT,
(org.apache.amoro.api.metrics.Gauge<Integer>)
() -> ManagementFactory.getThreadMXBean().getThreadCount());
}

private void registerCPuMetric() {
final com.sun.management.OperatingSystemMXBean mxBean =
(com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
registerMetric(
registry,
AMS_JVM_CPU_LOAD,
(org.apache.amoro.api.metrics.Gauge<Double>) () -> mxBean.getProcessCpuLoad());
registerMetric(
registry,
AMS_JVM_CPU_TIME,
(org.apache.amoro.api.metrics.Gauge<Long>) () -> mxBean.getProcessCpuTime());
}

private void registerGarbageCollectorMetrics() {
List<GarbageCollectorMXBean> garbageCollectorMXBeans =
ManagementFactory.getGarbageCollectorMXBeans();

for (final GarbageCollectorMXBean garbageCollector : garbageCollectorMXBeans) {
registerMetric(
registry,
AMS_JVM_GARBAGE_COLLECTOR_COUNT,
ImmutableMap.of(GARBAGE_COLLECTOR_TAG, garbageCollector.getName()),
(org.apache.amoro.api.metrics.Gauge<Long>) () -> garbageCollector.getCollectionCount());
registerMetric(
registry,
AMS_JVM_GARBAGE_COLLECTOR_TIME,
ImmutableMap.of(GARBAGE_COLLECTOR_TAG, garbageCollector.getName()),
(org.apache.amoro.api.metrics.Gauge<Long>) () -> garbageCollector.getCollectionTime());
}
}

private void registerMetric(MetricRegistry registry, MetricDefine define, Metric metric) {
MetricKey key = registry.register(define, Collections.emptyMap(), metric);
registeredMetricKeys.add(key);
}

private void registerMetric(
MetricRegistry registry, MetricDefine define, Map<String, String> tags, Metric metric) {
MetricKey key = registry.register(define, tags, metric);
registeredMetricKeys.add(key);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.amoro.server;

import static org.apache.amoro.server.AmsServiceMetrics.AMS_JVM_CPU_LOAD;
import static org.apache.amoro.server.AmsServiceMetrics.AMS_JVM_CPU_TIME;
import static org.apache.amoro.server.AmsServiceMetrics.AMS_JVM_GARBAGE_COLLECTOR_COUNT;
import static org.apache.amoro.server.AmsServiceMetrics.AMS_JVM_GARBAGE_COLLECTOR_TIME;
import static org.apache.amoro.server.AmsServiceMetrics.AMS_JVM_MEMORY_HEAP_COMMITTED;
import static org.apache.amoro.server.AmsServiceMetrics.AMS_JVM_MEMORY_HEAP_MAX;
import static org.apache.amoro.server.AmsServiceMetrics.AMS_JVM_MEMORY_HEAP_USED;
import static org.apache.amoro.server.AmsServiceMetrics.AMS_JVM_THREADS_COUNT;

import org.apache.amoro.api.metrics.Gauge;
import org.apache.amoro.api.metrics.Metric;
import org.apache.amoro.api.metrics.MetricKey;
import org.apache.amoro.server.manager.MetricManager;
import org.apache.amoro.server.metrics.MetricRegistry;
import org.junit.Assert;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import java.util.Collections;
import java.util.Map;

public class TestAmsServiceMetrics {
private static final AmsEnvironment amsEnv = AmsEnvironment.getIntegrationInstances();

@BeforeAll
public static void before() throws Exception {
amsEnv.start();
}

@Test
public void testAmsServiceMetrics() throws Exception {
MetricRegistry registry = MetricManager.getInstance().getGlobalRegistry();
Gauge<Long> heapMx =
(Gauge<Long>)
registry
.getMetrics()
.get(new MetricKey(AMS_JVM_MEMORY_HEAP_MAX, Collections.emptyMap()));
Assert.assertTrue(heapMx.getValue().longValue() > 0);
registry.unregister(new MetricKey(AMS_JVM_MEMORY_HEAP_MAX, Collections.emptyMap()));

Gauge<Long> heapUsed =
(Gauge<Long>)
registry
.getMetrics()
.get(new MetricKey(AMS_JVM_MEMORY_HEAP_USED, Collections.emptyMap()));
Assert.assertTrue(heapUsed.getValue().longValue() > 0);
registry.unregister(new MetricKey(AMS_JVM_MEMORY_HEAP_USED, Collections.emptyMap()));

Gauge<Long> heapCommitted =
(Gauge<Long>)
registry
.getMetrics()
.get(new MetricKey(AMS_JVM_MEMORY_HEAP_COMMITTED, Collections.emptyMap()));
Assert.assertTrue(heapCommitted.getValue().longValue() > 0);
registry.unregister(new MetricKey(AMS_JVM_MEMORY_HEAP_COMMITTED, Collections.emptyMap()));

Gauge<Integer> threadsCount =
(Gauge<Integer>)
registry.getMetrics().get(new MetricKey(AMS_JVM_THREADS_COUNT, Collections.emptyMap()));
Assert.assertTrue(threadsCount.getValue().intValue() > 0);
registry.unregister(new MetricKey(AMS_JVM_THREADS_COUNT, Collections.emptyMap()));

Gauge<Double> cpuLoad =
(Gauge<Double>)
registry.getMetrics().get(new MetricKey(AMS_JVM_CPU_LOAD, Collections.emptyMap()));
Assert.assertNotNull(cpuLoad);
registry.unregister(new MetricKey(AMS_JVM_CPU_LOAD, Collections.emptyMap()));

Gauge<Long> cpuTime =
(Gauge<Long>)
registry.getMetrics().get(new MetricKey(AMS_JVM_CPU_TIME, Collections.emptyMap()));
Assert.assertTrue(cpuTime.getValue().longValue() > 0);
registry.unregister(new MetricKey(AMS_JVM_CPU_TIME, Collections.emptyMap()));

Map<MetricKey, Metric> metrics = registry.getMetrics();
Assert.assertTrue(
metrics.keySet().stream()
.anyMatch(
key ->
key.getDefine().getName().equals(AMS_JVM_GARBAGE_COLLECTOR_COUNT.getName())));

Assert.assertTrue(
metrics.keySet().stream()
.anyMatch(
key -> key.getDefine().getName().equals(AMS_JVM_GARBAGE_COLLECTOR_TIME.getName())));

amsEnv.stop();
}
}
13 changes: 13 additions & 0 deletions docs/user-guides/metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,16 @@ Amoro has supported built-in metrics to measure status of table self-optimizing
| optimizer_group_optimizer_instances | Gauge | group | Number of optimizer instances in optimizer group |
| optimizer_group_memory_bytes_allocated | Gauge | group | Memory bytes allocated in optimizer group |
| optimizer_group_threads | Gauge | group | Number of total threads in optimizer group |


## Ams service metrics
| Metric Name | Type | Tags | Description |
|--------------------------------------------------------|--------|-----------------|------------------------------------------------------------------|
| ams_jvm_cpu_load | Gauge | | The recent CPU usage of the AMS |
| ams_jvm_cpu_time | Gauge | | The CPU time used by the AMS |
| ams_jvm_memory_heap_used | Gauge | | The amount of heap memory currently used (in bytes) by the AMS |
| ams_jvm_memory_heap_committed | Gauge | | The amount of memory in the heap committed for JVM use (bytes) |
| ams_jvm_memory_heap_max | Gauge | | The maximum heap memory (bytes), set by -Xmx JVM argument |
| ams_jvm_threads_count | Gauge | | The total number of live threads used by the AMS |
| ams_jvm_garbage_collector_count | Gauge |garbage_collector| The count of the JVM's Garbage Collector, such as G1 Young |
| ams_jvm_garbage_collector_time | Gauge |garbage_collector| The time spent by the JVM's Garbage Collector, such as G1 Young |

0 comments on commit b3d794a

Please sign in to comment.