All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openrewrite.maven.MavenLoggingMeterRegistry Maven / Gradle / Ivy

/*
 * Copyright 2020 the original author or authors.
 * 

* Licensed under the Moderne Source Available License (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* https://docs.moderne.io/licensing/moderne-source-available-license *

* 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.openrewrite.maven; import io.micrometer.core.instrument.*; import io.micrometer.core.instrument.binder.BaseUnits; import io.micrometer.core.instrument.cumulative.*; import io.micrometer.core.instrument.distribution.DistributionStatisticConfig; import io.micrometer.core.instrument.distribution.HistogramSnapshot; import io.micrometer.core.instrument.distribution.pause.PauseDetector; import io.micrometer.core.instrument.internal.DefaultGauge; import io.micrometer.core.instrument.internal.DefaultLongTaskTimer; import io.micrometer.core.instrument.internal.DefaultMeter; import io.micrometer.core.instrument.util.TimeUtils; import org.apache.maven.plugin.logging.Log; import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; import java.time.Duration; import java.util.concurrent.TimeUnit; import java.util.function.ToDoubleFunction; import java.util.function.ToLongFunction; import java.util.stream.StreamSupport; import static io.micrometer.core.instrument.util.DoubleFormat.decimalOrNan; import static java.util.stream.Collectors.joining; @NullMarked public class MavenLoggingMeterRegistry extends MeterRegistry { private final Log log; public MavenLoggingMeterRegistry(Log log) { super(Clock.SYSTEM); this.log = log; } @Override public void close() { getMeters().stream() .sorted((m1, m2) -> { int typeComp = m1.getId().getType().compareTo(m2.getId().getType()); if (typeComp == 0) { return m1.getId().getName().compareTo(m2.getId().getName()); } return typeComp; }) .forEach(m -> { Printer print = new Printer(m); m.use( gauge -> log.info(print.id() + " value=" + print.value(gauge.value())), counter -> { double count = counter.count(); log.info(print.id() + " count=" + print.count(count)); }, timer -> { HistogramSnapshot snapshot = timer.takeSnapshot(); long count = snapshot.count(); log.info(print.id() + " count=" + print.unitlessCount(count) + " mean=" + print.time(snapshot.mean(getBaseTimeUnit())) + " max=" + print.time(snapshot.max(getBaseTimeUnit()))); }, summary -> { HistogramSnapshot snapshot = summary.takeSnapshot(); long count = snapshot.count(); log.info(print.id() + " count=" + print.unitlessCount(count) + " mean=" + print.value(snapshot.mean()) + " max=" + print.value(snapshot.max())); }, longTaskTimer -> { int activeTasks = longTaskTimer.activeTasks(); log.info(print.id() + " active=" + print.value(activeTasks) + " duration=" + print.time(longTaskTimer.duration(getBaseTimeUnit()))); }, timeGauge -> { double value = timeGauge.value(getBaseTimeUnit()); log.info(print.id() + " value=" + print.time(value)); }, counter -> { double count = counter.count(); log.info(print.id() + " count=" + print.count(count)); }, timer -> { double count = timer.count(); log.info(print.id() + " count=" + print.count(count) + " mean=" + print.time(timer.mean(getBaseTimeUnit()))); }, meter -> log.info(writeMeter(meter, print)) ); }); } String writeMeter(Meter meter, Printer print) { return StreamSupport.stream(meter.measure().spliterator(), false) .map(ms -> { String msLine = ms.getStatistic().getTagValueRepresentation() + "="; switch (ms.getStatistic()) { case TOTAL: case MAX: case VALUE: return msLine + print.value(ms.getValue()); case TOTAL_TIME: case DURATION: return msLine + print.time(ms.getValue()); case COUNT: return "count=" + print.count(ms.getValue()); default: return msLine + decimalOrNan(ms.getValue()); } }) .collect(joining(", ", print.id() + " ", "")); } @Override protected Timer newTimer(Meter.Id id, DistributionStatisticConfig distributionStatisticConfig, PauseDetector pauseDetector) { return new CumulativeTimer(id, clock, distributionStatisticConfig, pauseDetector, getBaseTimeUnit(), false); } @Override protected DistributionSummary newDistributionSummary(Meter.Id id, DistributionStatisticConfig distributionStatisticConfig, double scale) { return new CumulativeDistributionSummary(id, clock, distributionStatisticConfig, scale, false); } @Override protected Counter newCounter(Meter.Id id) { return new CumulativeCounter(id); } @Override protected Gauge newGauge(Meter.Id id, @Nullable T obj, ToDoubleFunction valueFunction) { return new DefaultGauge<>(id, obj, valueFunction); } @Override protected FunctionTimer newFunctionTimer(Meter.Id id, T obj, ToLongFunction countFunction, ToDoubleFunction totalTimeFunction, TimeUnit totalTimeFunctionUnit) { return new CumulativeFunctionTimer<>(id, obj, countFunction, totalTimeFunction, totalTimeFunctionUnit, getBaseTimeUnit()); } @Override protected FunctionCounter newFunctionCounter(Meter.Id id, T obj, ToDoubleFunction countFunction) { return new CumulativeFunctionCounter<>(id, obj, countFunction); } @Override protected LongTaskTimer newLongTaskTimer(Meter.Id id, DistributionStatisticConfig distributionStatisticConfig) { return new DefaultLongTaskTimer(id, clock, getBaseTimeUnit(), distributionStatisticConfig, false); } @Override protected Meter newMeter(Meter.Id id, Meter.Type type, Iterable measurements) { return new DefaultMeter(id, type, measurements); } @Override protected DistributionStatisticConfig defaultHistogramConfig() { return DistributionStatisticConfig.builder() .expiry(Duration.ofMinutes(1)) .bufferLength(3) .build(); } class Printer { private final Meter meter; Printer(Meter meter) { this.meter = meter; } String id() { return getConventionName(meter.getId()) + getConventionTags(meter.getId()).stream() .map(t -> t.getKey() + "=" + t.getValue()) .collect(joining(",", "{", "}")); } String count(double count) { return humanReadableBaseUnit(count); } String unitlessCount(double count) { return decimalOrNan(count); } String time(double time) { return TimeUtils.format(Duration.ofNanos((long) TimeUtils.convert(time, getBaseTimeUnit(), TimeUnit.NANOSECONDS))); } String value(double value) { return humanReadableBaseUnit(value); } // see https://stackoverflow.com/a/3758880/510017 @SuppressWarnings("StringConcatenationMissingWhitespace") String humanReadableByteCount(double bytes) { int unit = 1024; if (bytes < unit || Double.isNaN(bytes)) { return decimalOrNan(bytes) + " B"; } int exp = (int) (Math.log(bytes) / Math.log(unit)); String pre = "KMGTPE".charAt(exp - 1) + "i"; return decimalOrNan(bytes / Math.pow(unit, exp)) + " " + pre + "B"; } String humanReadableBaseUnit(double value) { String baseUnit = meter.getId().getBaseUnit(); if (BaseUnits.BYTES.equals(baseUnit)) { return humanReadableByteCount(value); } return decimalOrNan(value) + (baseUnit != null ? " " + baseUnit : ""); } } @Override protected TimeUnit getBaseTimeUnit() { return TimeUnit.MILLISECONDS; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy