在 Spring Boot 应用程序中重命名 Dropwizard MetricsRegistry 中的指标

问题描述 投票:0回答:1

在我的 Spring Boot 应用程序中,我使用的是一个指标库,它是一个包装器:

io.dropwizard.metrics
。所以我从
MetricsRegistry
获取所有 API 和系统指标。

因此,当我到达

/metrics
执行器端点时,我能够看到所有这些指标。

现在的问题是:所有格式为

a.b.c
的指标名称,我想将其重命名为:
a_b_c

但我找不到任何方法来实现同样的目标。

有人可以帮忙指点一下吗?预先感谢。

java spring-boot metrics dropwizard
1个回答
1
投票

查看

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));

我的一个疑问是:我应该在哪里注册自定义指标集。我应该在 ApplicationReadyEvent 上执行此操作吗?

是的,在 ApplicationReadyEvent

 上注册您的自定义指标集  应该可以在 Spring Boot 应用程序中工作:它确保您的自定义指标集在所有自动配置完成后但在应用程序开始提供流量之前注册:您的指标一旦您的申请完成,就可以使用。

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
的包装,您设计它是为了根据命名约定修改指标名称(例如,用下划线替换点)。当应用程序完全准备好时,此侦听器将触发,使用修改后的名称包装和注册您的指标集。

© www.soinside.com 2019 - 2024. All rights reserved.