在我的 Spring Boot 应用程序中,我使用的是一个指标库,它是一个包装器:
io.dropwizard.metrics
。所以我从 MetricsRegistry
获取所有 API 和系统指标。
因此,当我到达
/metrics
执行器端点时,我能够看到所有这些指标。
现在的问题是:所有格式为
a.b.c
的指标名称,我想将其重命名为:a_b_c
。
但我找不到任何方法来实现同样的目标。
有人可以帮忙指点一下吗?预先感谢。
MetricRegistry.java
的源代码,理论上您可以迭代MetricsRegistry
中的现有指标,并且对于每个指标,从注册表中删除该指标并使用新名称重新添加它。
但是,请注意,像这样直接操作
MetricsRegistry
可能会带来问题或限制,特别是对于由应用程序中的其他组件自动管理或更新的指标。
import com.codahale.metrics.MetricRegistry;
import java.util.Map;
import java.util.HashMap;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.PostConstruct;
@Component
public class MetricRenamer {
@Autowired
private MetricRegistry metricRegistry;
@PostConstruct
public void renameMetrics() {
// Temporary map to hold the new metrics
Map<String, Metric> renamedMetrics = new HashMap<>();
metricRegistry.getMetrics().forEach((name, metric) -> {
// Generate the new name
String newName = name.replace('.', '_');
// Add to the temporary map
renamedMetrics.put(newName, metric);
});
// Remove the old metrics and add the renamed ones
renamedMetrics.forEach((newName, metric) -> {
metricRegistry.remove(newName.replace('_', '.'));
metricRegistry.register(newName, metric);
});
}
}
在重命名之前,请考虑保留原始指标名称及其引用的备份,以确保您可以在需要时恢复更改。 如果您的应用程序在高度并发的环境中更新指标,请考虑在运行时修改
MetricsRegistry
的影响。您可能需要实现额外的同步或使用 MetricRegistryListener
来动态管理更改。
再次强调,直接操作
MetricsRegistry
可能并不适合所有应用程序,尤其是那些依赖自动指标注册和更新的应用程序。
操作 MetricsRegistry 可能并不适合所有应用程序,尤其是那些依赖自动指标注册和更新的应用程序,在这种情况下,您建议如何更改指标名称?
您确实可以尝试扩展
MetricRegistry
并重写负责注册指标的方法。然后,该自定义注册表可以替换 Spring Boot 应用程序上下文中的默认注册表。
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Metric;
public class CustomMetricRegistry extends MetricRegistry {
@Override
public <T extends Metric> T register(String name, T metric) throws IllegalArgumentException {
// Modify the metric name here before it is registered
String modifiedName = name.replace('.', '_');
return super.register(modifiedName, metric);
}
}
要使用自定义注册表,您需要确保它是 Spring Boot 自动配置所选择的注册表。这通常涉及在默认配置启动之前将其定义为 bean:
@Configuration
public class MetricsConfig {
@Bean
public MetricRegistry metricRegistry() {
return new CustomMetricRegistry();
}
}
如果您正在处理更复杂的场景,其中通过
MetricSet
或通过 MetricBuilder
注册指标,请考虑包装这些构造以在创建时修改指标名称。
import com.codahale.metrics.*;
public class CustomMetricSet implements MetricSet {
private final MetricSet original;
public CustomMetricSet(MetricSet original) {
this.original = original;
}
@Override
public Map<String, Metric> getMetrics() {
// Transform metric names in the original set
return original.getMetrics().entrySet().stream()
.collect(Collectors.toMap(
entry -> entry.getKey().replace('.', '_'),
Map.Entry::getValue
));
}
}
然后,当您注册
MetricSet
时:
metricRegistry.registerAll(new CustomMetricSet(yourOriginalMetricSet));
上注册您的自定义指标集 应该可以在 Spring Boot 应用程序中工作:它确保您的自定义指标集在所有自动配置完成后但在应用程序开始提供流量之前注册:您的指标一旦您的申请完成,就可以使用。我的一个疑问是:我应该在哪里注册自定义指标集。我应该在 ApplicationReadyEvent 上执行此操作吗?
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.beans.factory.annotation.Autowired;
import com.codahale.metrics.MetricRegistry;
@Component
public class CustomMetricSetRegistrar implements ApplicationListener<ApplicationReadyEvent> {
@Autowired
private MetricRegistry metricRegistry;
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
// Assuming you have an existing MetricSet that you wish to wrap
MetricSet yourOriginalMetricSet = ...; // Your existing MetricSet
// Wrap and register the MetricSet with transformed metric names
metricRegistry.registerAll(new CustomMetricSet(yourOriginalMetricSet));
}
}
CustomMetricSet
是原始 MetricSet
的包装,您设计它是为了根据命名约定修改指标名称(例如,用下划线替换点)。当应用程序完全准备好时,此侦听器将触发,使用修改后的名称包装和注册您的指标集。