【问题标题】:What is a clean way of setting description for dynamic metrics in Micrometer?在 Micrometer 中为动态指标设置描述的简洁方法是什么?
【发布时间】:2020-07-31 10:02:27
【问题描述】:

这听起来很傻,可能有一个非常简单的答案,但我还没有找到。

Micrometer 具有以下形式的每种度量类型的 Builder 类:

<MetricType>.builder(<metricName>).description(<description>).tags(<tagsArray>).register(<meterRegistry>)

让我们以计数器指标为例。可以按如下方式递增:

<meterRegistry>.Counter(<counterName>, <Pairs of labels and their values>).increment()

当你想设置描述时,问题就出现了。如果标签的值本质上是动态的,即值是在运行时确定的,或者标签的可能组合太多,比如 10+,那么你应该如何设置描述?

我能想到的唯一解决方案是在启动度量服务时将描述存储在某处。然后围绕增量方法创建一个包装器。现在,当用户调用包装器时,调用 register 方法(带有存储的描述),然后调用 increment 方法。如果注册方法不存在,则注册方法会创建一个新指标,否则返回现有指标。

同样的问题可以在 Prometheus 中轻松解决,因为它们有一个注册方法,可让您设置所有标签(即仅键)和描述。增量方法只需要这些标签的值。

千分尺是否提供类似的功能?为简单的应用程序创建包装器似乎非常不方便。考虑到千分尺已经是 Prometheus(和其他检测服务)的包装器,我也不想围绕它创建一个包装器。

如果问题没有意义,以下示例可能会有所帮助:

让我们考虑一个带有标签type 的计数器指标requests,其值可以是alpha, beta, gamma,描述为tracks requests from clients

然后作为解决方案,我可以在启动度量服务时调用的注册函数中添加以下行。

Counter.builder("requests")
    .description("tracks requests from clients)
    .tags("type", "alpha")
    .register(meterRegistry);

然后无论我想在哪里使用这个指标,我都可以运行以下代码:

meterRegistry.Counter("request", "type", <valueOfType>).increment()

我担心的是,在这个解决方案中,我只启动了 alpha 类型,这似乎不正确,因为这是唯一的类型。另一种选择是注册所有 3 种类型,但是,这是假设所有可能的值在运行时都是已知的。如果在运行时发现这些值,则此解决方案将完全失败,现在您必须使用带有上述包装器的解决方案,或者完全忘记描述。

【问题讨论】:

    标签: java prometheus metrics micrometer


    【解决方案1】:

    我在尝试使用计数器和单个标签的多个值时遇到了类似的问题。

    这是我的解决方案:

    @RestController
    public class HelloController {
    
        private final Counter.Builder counter;
        private MeterRegistry registry;
    
        public HelloController(MeterRegistry registry) {
            this.counter = Counter.builder("counter").description("A description");
            this.registry = registry;
        }
    
        @GetMapping("/count")
        public String count1() {
            counter.tag("tag2", "value1").register(registry).increment();
    // I don't provide more description here, but I need to use .register('registry') at each call.
            return "Count";
        }
    
        @GetMapping("/count2")
        public String count2() {
            counter.tag("tag2", "value2").register(registry).increment();
            return "Count";
        }
    
    }
    
    • 注意:我必须调用 counter...register(registry) 才能获得单个描述和多个标签值。

    【讨论】:

    • 这是一个很好的解决方案,但看起来还是有点乱。我真的希望 Micrometer 有一个类似于 Prometheus 中的功能
    【解决方案2】:

    我也遇到了同样的问题,所以我发现这很有帮助post,但是... 我不喜欢这个解决方案。

    我认为更好的方法是占位符,例如this。 所以也许定义一个HierarchicalNameMapper,当标签键匹配时替换标签占位符,这是个不错的选择。

    所以现在动态标记米的问题似乎解决了,但描述仍然是个问题。所以我也没有使用这个解决方案。

    我的最终解决方案是将Counters Gauges 和其他仪表存储在地图中,并按ID(名称和标签)检索。 描述是在测量期间提供的,我在其中查找地图,如果具有该 Id 的指标已经存在,则将增加(或减少),否则将使用基于有意义的指标名称和标签键值的描述来创建。

        /**
         * Increment the {@link Counter}  with input tags. If it does not exists it will be created.
         */
        public void increment(String description, String unit, Tags tags) throws MetricsException {
                this.counter(description, unit, tags).increment();
        }
    
        /**
         * Search for a counter with input tags. If it does not exists it will be created.
         */
        private Counter counter(String description, String unit, Tags tags) {
            final String counterId = name.concat(tags.toString());
    
            Counter counter = counters.get(counterId);
            if (counter == null) {
    
                counter = Counter.builder(name)
                        .description(description)
                        .baseUnit(unit)
                        .tags(tags)
                        .register(registry);
    
                counters.put(counterId, counter);
            }
    
            return counter;
        }
    

    其中:
    registryMeterRegistry 字段值
    countersMap&lt;String, Counter&gt;

    如果您在内存使用方面遇到困难,我使用 Java 检测代理来检查 Map。这个one。 地图的一个条目就像 1KB,所以你应该有 1000 个标签名组合才能使用 1MB :)

    【讨论】:

      猜你喜欢
      • 2011-07-19
      • 1970-01-01
      • 2015-08-29
      • 2020-08-19
      • 1970-01-01
      • 1970-01-01
      • 2017-05-21
      • 2010-12-04
      • 1970-01-01
      相关资源
      最近更新 更多