[英]Exporting Metrics to files when using Spring Boot 2.0
我正在寻找一种将 spring 引导指标导出到 Spring 引导 2 中的文件的方法。
在 Spring Boot 1.5.10 中,我们使用了自定义MetricsExporter class,它实现了 MetricWriter并覆盖了 set 和 increment 方法来使用记录器写入指标。 我们使用了日志文件,因为我们有不同的机制来处理日志文件,以便稍后进行度量分析。
我们还使用了 MetricsConfig class,它使用 bean MetricsEndpointMetricReader从自定义配置 class 中的指标端点读取器读取指标。
但是,当我们升级到 Spring Boot 2.0.1 时,这些都不起作用,因为现有指标类发生了重大变化。
有人可以帮助我们在使用 Spring Boot 2.0 时如何导出指标并使用记录器编写它们吗?
@ExportMetricWriter
public class MetricsExporter implements MetricWriter {
private static Logger LOGGER = LoggerFactory.getLogger("metrics");
@Override
public void set(Metric<?> value) {
// Write the Gauge metrics to log file
LOGGER.info("timestamp={}, name={}, value={}", value.getTimestamp(), value.getName(),value.getValue());
}
@Override
public void increment(Delta<?> delta) {
//Write the Counter metrics to log file
LOGGER.info("timestamp={}, name={}, value={}", delta.getTimestamp(), delta.getName(),delta.getValue());
}
@Override
public void reset(String metricName) {
}
}
MetricsConfig Class 如下:
@Configuration
public class MetricsConfig {
//Define the MetricsExporter bean to export metrics at regular interval to a log file
@Bean
public MetricsExporter metricsExporter() {
return new MetricsExporter();
}
//Define the MetricsEndpointMetricReader bean to export both push(counters and gauges) and pull(public) metrics
@Bean
public MetricsEndpointMetricReader metricsEndpointMetricReader(MetricsEndpoint metricsEndpoint) {
return new MetricsEndpointMetricReader(metricsEndpoint);
}
}
您可以实现自定义MeterRegistry
并将其连接为@Bean
。 MeterRegistry
实现的角色之一是定义特定监控系统(在您的情况下为日志)的展示格式。
这是一个开始:
public class LogMeterRegistry extends StepMeterRegistry {
private final Logger logger = LoggerFactory.getLogger(LogMeterRegistry.class);
/**
* @param step Governs on what frequency metrics are logged
*/
public LogMeterRegistry(Duration step) {
super(new StepRegistryConfig() {
@Override
public String prefix() {
return "log";
}
@Override
public String get(String key) {
return null;
}
@Override
public Duration step() {
return step;
}
}, Clock.SYSTEM);
}
@Override
protected void publish() {
for (Meter meter : getMeters()) {
logger.info(meter.getId().toString());
for (Measurement measurement : meter.measure()) {
logger.info(measurement.getStatistic().toString() + "=" + measurement.getValue());
}
}
}
@Override
protected TimeUnit getBaseTimeUnit() {
return TimeUnit.SECONDS;
}
}
Micrometer 1.1 存在一个问题,可以提供开箱即用的LogMeterRegistry
。
如果您使用的是 Spring Boot 2.x,这意味着 Micrometer >= 1.1.0 的版本,您可以简单地配置一个 bean,例如
@Bean
LoggingMeterRegistry loggingMeterRegistry() {
return new LoggingMeterRegistry();//by default, it will log metrics every 1m
}
您还可以配置不同的周期周期,例如:
@Bean
LoggingMeterRegistry loggingMeterRegistry() {
return new LoggingMeterRegistry(new LoggingRegistryConfig() {
@Override
public Duration step() {
return Duration.ofSeconds(10); // log every 10 seconds
}
@Override
public String get(String key) {
return null;
}
}, Clock.SYSTEM);
}
如果您没有使用足够高的 spring boot 版本,请尝试在您的 pom.xml 中声明 micrometer-core 的 1.1.x 版本
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
<version>1.1.3</version>
</dependency>
我想做一些类似于Jonathan建议的事情,但我想使用 Slf4j MDC 在一个日志行上发布所有指标。
我 output 我的日志为 json(在我的情况下为 AWS CloudWatch),因此我可以绘制查询并可视化数据。
import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.step.StepMeterRegistry;
import io.micrometer.core.instrument.step.StepRegistryConfig;
import io.micrometer.core.instrument.util.NamedThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import java.text.DecimalFormat;
import java.util.concurrent.TimeUnit;
public class LogMeterRegistry extends StepMeterRegistry {
private static final Logger logger = LoggerFactory.getLogger(LogMeterRegistry.class);
private final DecimalFormat df;
public LogMeterRegistry(CustomRegistryConfig config, Clock clock) {
super(config, clock);
start(new NamedThreadFactory("log-meter-registry-publisher"));
df = new DecimalFormat("0");
df.setMaximumFractionDigits(3);
}
@Override
protected void publish() {
MDC.put("server", getHostName());
getMeters().forEach(meter -> meter.measure().forEach(
measurement -> MDC.put(meter.getId().getName(), df.format(measurement.getValue()))));
logger.info("metrics");
MDC.clear();
}
@Override
protected TimeUnit getBaseTimeUnit() {
return TimeUnit.MILLISECONDS;
}
public interface CustomRegistryConfig extends StepRegistryConfig {
CustomRegistryConfig DEFAULT = k -> null;
@Override
default String prefix() {
return "";
}
}
}
所以使用以下指标:
new JvmHeapPressureMetrics().bindTo(meterRegistry);
new JvmThreadMetrics().bindTo(meterRegistry);
new UptimeMetrics().bindTo(meterRegistry);
new ProcessorMetrics().bindTo(meterRegistry);
json output 如下所示:
{
"@timestamp": "2022-xx-xxT11:03:00.027Z",
"level": "INFO",
"message": "metrics",
"process.thread.name": "log-meter-registry-publisher",
"log.logger": "MyClass",
"jvm.gc.overhead": "0",
"jvm.memory.usage.after.gc": "0.036",
"jvm.threads.daemon": "46",
"jvm.threads.live": "47",
"jvm.threads.peak": "54",
"jvm.threads.states": "23",
"process.cpu.usage": "0.001",
"process.start.time": "1663065827068",
"process.uptime": "1152989",
"server": "MyServer.localdomain",
"system.cpu.count": "12",
"system.cpu.usage": "0.051",
"system.load.average.1m": "2.351"
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.