Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2023, 2024 Oracle and/or its affiliates.
*
* Licensed 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 io.helidon.metrics.systemmeters;
import java.lang.management.ClassLoadingMXBean;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadMXBean;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
import io.helidon.metrics.api.Meter;
import io.helidon.metrics.api.MetricsFactory;
import io.helidon.metrics.api.Tag;
import io.helidon.metrics.spi.MetersProvider;
/**
* Provider for the built-in system meters.
*/
public class SystemMetersProvider implements MetersProvider {
private static final String BYTES = "bytes";
private static final String SECONDS = "seconds";
private static final String SCOPE = Meter.Scope.BASE;
private static final Metadata MEMORY_USED_HEAP = Metadata.builder()
.withName("memory.usedHeap")
.withDescription("Displays the amount of used heap memory in bytes.")
.withUnit(BYTES)
.build();
private static final Metadata MEMORY_COMMITTED_HEAP = Metadata.builder()
.withName("memory.committedHeap")
.withDescription(
"Displays the amount of memory in bytes that is "
+ "committed for the Java virtual "
+ "machine to use. This amount of memory is "
+ "guaranteed for the Java virtual "
+ "machine to use.")
.withUnit(BYTES)
.build();
private static final Metadata MEMORY_MAX_HEAP = Metadata.builder()
.withName("memory.maxHeap")
.withDescription(
"Displays the maximum amount of heap memory in bytes that can"
+ " be used for "
+ "memory management. This attribute displays -1 if "
+ "the maximum heap "
+ "memory size is undefined. This amount of memory is "
+ "not guaranteed to be "
+ "available for memory management if it is greater "
+ "than the amount of "
+ "committed memory. The Java virtual machine may fail"
+ " to allocate memory "
+ "even if the amount of used memory does not exceed "
+ "this maximum size.")
.withUnit(BYTES)
.build();
private static final Metadata JVM_UPTIME = Metadata.builder()
.withName("jvm.uptime")
.withDescription(
"Displays the start time of the Java virtual machine in "
+ "seconds. This "
+ "attribute displays the approximate time when the Java "
+ "virtual machine "
+ "started.")
.withUnit(SECONDS)
.build();
private static final Metadata THREAD_COUNT = Metadata.builder()
.withName("thread.count")
.withDescription("Displays the current number of live threads including both "
+ "daemon and nondaemon threads")
.build();
private static final Metadata THREAD_DAEMON_COUNT = Metadata.builder()
.withName("thread.daemon.count")
.withDescription("Displays the current number of live daemon threads.")
.build();
private static final Metadata THREAD_MAX_COUNT = Metadata.builder()
.withName("thread.max.count")
.withDescription("Displays the peak live thread count since the Java "
+ "virtual machine started or "
+ "peak was reset. This includes daemon and "
+ "non-daemon threads.")
.build();
private static final Metadata CL_LOADED_COUNT = Metadata.builder()
.withName("classloader.loadedClasses.count")
.withDescription("Displays the number of classes that are currently loaded in "
+ "the Java virtual machine.")
.build();
private static final Metadata CL_LOADED_TOTAL = Metadata.builder()
.withName("classloader.loadedClasses.total")
.withDescription("Displays the total number of classes that have been loaded "
+ "since the Java virtual machine has started execution.")
.build();
private static final Metadata CL_UNLOADED_COUNT = Metadata.builder()
.withName("classloader.unloadedClasses.total")
.withDescription("Displays the total number of classes unloaded since the Java "
+ "virtual machine has started execution.")
.build();
private static final Metadata OS_AVAILABLE_CPU = Metadata.builder()
.withName("cpu.availableProcessors")
.withDescription("Displays the number of processors available to the Java "
+ "virtual machine. This "
+ "value may change during a particular invocation of"
+ " the virtual machine.")
.build();
private static final Metadata OS_LOAD_AVERAGE = Metadata.builder()
.withName("cpu.systemLoadAverage")
.withDescription("Displays the system load average for the last minute. The "
+ "system load average "
+ "is the sum of the number of runnable entities "
+ "queued to the available "
+ "processors and the number of runnable entities "
+ "running on the available "
+ "processors averaged over a period of time. The way "
+ "in which the load average "
+ "is calculated is operating system specific but is "
+ "typically a damped timedependent "
+ "average. If the load average is not available, a "
+ "negative value is "
+ "displayed. This attribute is designed to provide a "
+ "hint about the system load "
+ "and may be queried frequently. The load average may"
+ " be unavailable on some "
+ "platforms where it is expensive to implement this "
+ "method.")
.build();
private static final Metadata GC_TIME = Metadata.builder()
.withName("gc.time")
.withDescription(
"Displays the approximate accumulated collection elapsed time in seconds. "
+ "This attribute displays -1 if the collection elapsed time is undefined for this "
+ "collector. The Java virtual machine implementation may use a high resolution "
+ "timer to measure the elapsed time. This attribute may display the same value "
+ "even if the collection count has been incremented if the collection elapsed "
+ "time is very short.")
.withUnit("seconds")
.build();
private static final Metadata GC_COUNT = Metadata.builder()
.withName("gc.total")
.withDescription(
"Displays the total number of collections that have occurred. This attribute lists "
+ "-1 if the collection count is undefined for this collector.")
.build();
private MetricsFactory metricsFactory;
/**
* Constructs a new instance for service loading.
*
* @deprecated
*/
@Deprecated
public SystemMetersProvider() {
}
@Override
public Collection> meterBuilders(MetricsFactory metricsFactory) {
this.metricsFactory = metricsFactory; // save at the instance level for ease of access
return prepareMeterBuilders();
}
/**
* Returns a function to invoke a function on a main bean to get a sub-bean, then invoke a function on
* the sub-bean to retrieve a value.
*
* @param getSubBeanFn function to get the subbean from the main bean
* @param valueFn function to get the value from the subbean
* @param type of the main bean
* @param type of the subbean
* @param subtype of {@link java.lang.Number} returned by the value-obtaining function applied to the subbean
* @return a function for retrieving the value given the main bean
*/
private static Function typedFn(Function getSubBeanFn, Function valueFn) {
return main -> valueFn.apply(getSubBeanFn.apply(main));
}
private ,
M extends Meter>
Collection> prepareMeterBuilders() {
Collection> result = new ArrayList<>();
MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
// load all base metrics
registerGauge(result,
MEMORY_USED_HEAP,
memoryBean,
typedFn(MemoryMXBean::getHeapMemoryUsage, MemoryUsage::getUsed));
registerGauge(result,
MEMORY_COMMITTED_HEAP,
memoryBean,
typedFn(MemoryMXBean::getHeapMemoryUsage, MemoryUsage::getCommitted));
registerGauge(result,
MEMORY_MAX_HEAP,
memoryBean,
typedFn(MemoryMXBean::getHeapMemoryUsage, MemoryUsage::getMax));
RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
registerGauge(result, JVM_UPTIME, runtimeBean, rtBean -> rtBean.getUptime() / 1000.0D);
ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
registerGauge(result, THREAD_COUNT, threadBean, ThreadMXBean::getThreadCount);
registerGauge(result, THREAD_DAEMON_COUNT, threadBean, ThreadMXBean::getDaemonThreadCount);
registerGauge(result, THREAD_MAX_COUNT, threadBean, ThreadMXBean::getPeakThreadCount);
ClassLoadingMXBean clBean = ManagementFactory.getClassLoadingMXBean();
registerGauge(result, CL_LOADED_COUNT, clBean, ClassLoadingMXBean::getLoadedClassCount);
registerFunctionalCounter(result, CL_LOADED_TOTAL, clBean, ClassLoadingMXBean::getTotalLoadedClassCount);
registerFunctionalCounter(result, CL_UNLOADED_COUNT, clBean, ClassLoadingMXBean::getUnloadedClassCount);
OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();
registerGauge(result, OS_AVAILABLE_CPU, osBean, OperatingSystemMXBean::getAvailableProcessors);
registerGauge(result, OS_LOAD_AVERAGE, osBean, OperatingSystemMXBean::getSystemLoadAverage);
List gcBeans = ManagementFactory.getGarbageCollectorMXBeans();
for (GarbageCollectorMXBean gcBean : gcBeans) {
String poolName = gcBean.getName();
registerFunctionalCounter(result,
GC_COUNT,
gcBean,
GarbageCollectorMXBean::getCollectionCount,
Tag.create("name", poolName));
// Express the GC time in seconds.
// @Deprecated(forRemoval = true) - Starting in Helidon 5 always register a gauge instead of checking which
// type of meter to register.
if (isGcTimeGauge()) {
registerGauge(result,
GC_TIME,
gcBean,
bean -> (long) (bean.getCollectionTime() / 1000.0D),
Tag.create("name", poolName));
} else {
registerFunctionalCounter(result,
GC_TIME,
gcBean,
bean -> (long) (bean.getCollectionTime() / 1000.0D),
Tag.create("name", poolName));
}
}
return result;
}
private void registerGauge(Collection> result,
Metadata metadata,
T object,
Function fn,
Tag... tags) {
result.add(metricsFactory.gaugeBuilder(metadata.name, object, obj -> fn.apply(obj).doubleValue())
.scope(SCOPE)
.description(metadata.description)
.baseUnit(metadata.baseUnit)
.tags(Arrays.asList(tags)));
}
private void registerFunctionalCounter(Collection> result,
Metadata metadata,
T object,
Function fn,
Tag... tags) {
result.add(metricsFactory.functionalCounterBuilder(metadata.name, object, fn)
.scope(SCOPE)
.description(metadata.description)
.baseUnit(metadata.baseUnit)
.tags(Arrays.asList(tags)));
}
@Deprecated(since = "4.1", forRemoval = true)
private boolean isGcTimeGauge() {
// Compare using the string so we can avoid exposing the temporary, deprecated enum as public in the config type.
return metricsFactory.metricsConfig().gcTimeType().name().equals("GAUGE");
}
private static class Metadata {
private final String name;
private final String description;
private final String baseUnit;
private Metadata(Builder builder) {
name = builder.name;
description = builder.description;
baseUnit = builder.baseUnit;
}
static Builder builder() {
return new Builder();
}
private static class Builder implements io.helidon.common.Builder {
private String name;
private String description;
private String baseUnit;
@Override
public SystemMetersProvider.Metadata build() {
return new SystemMetersProvider.Metadata(this);
}
Builder withName(String name) {
this.name = name;
return this;
}
Builder withDescription(String description) {
this.description = description;
return this;
}
Builder withUnit(String unit) {
baseUnit = unit;
return this;
}
}
}
}