Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 普罗米修斯反矛盾_Java_Prometheus_Prometheus Java - Fatal编程技术网

Java 普罗米修斯反矛盾

Java 普罗米修斯反矛盾,java,prometheus,prometheus-java,Java,Prometheus,Prometheus Java,我在web服务中使用Prometheus Java simpleclient来跟踪有多少事件会导致某种状态 我能够在日志中检查计数器是否正在被调用,并且在内部递增,但似乎很多时候数据都没有到达/metrics端点 例如,刚才,将相同状态的计数器分别递增3次后,日志将打印三次“当前值=0,新值=1”。前两次没有显示/metrics端点上的任何数据,在第三次增量之后,它最终显示值1,这意味着我丢失了前两次事件的记录 除了一些名称更改外,我的代码如下所示 private static final Co

我在web服务中使用Prometheus Java simpleclient来跟踪有多少事件会导致某种状态

我能够在日志中检查计数器是否正在被调用,并且在内部递增,但似乎很多时候数据都没有到达/metrics端点

例如,刚才,将相同状态的计数器分别递增3次后,日志将打印三次“当前值=0,新值=1”。前两次没有显示/metrics端点上的任何数据,在第三次增量之后,它最终显示值1,这意味着我丢失了前两次事件的记录

除了一些名称更改外,我的代码如下所示

private static final Counter myCounter = Counter.build()
        .name("myMetric")
        .help("My metric")
        .labelNames("status").register();
...

private static void incrementCounter(String status) {
    Counter.Child counter = myCounter.labels(status);
    Logger.info("Before Incrementing counter for status= " + status + ". Current value=" + counter.get());
    counter.inc();
    Logger.info("After Incrementing counter for status= " + status + ". New value=" + counter.get());
}

我不明白为什么普罗米修斯似乎不能始终跟踪这些计数器。有没有人能看到哪里出了问题,或者有更好的方法来记录这些计数器指标?

我能猜到的唯一原因是并发的
递增计数器
调用。
io.prometheus.client.SimpleCollector#labels
方法不是线程安全的(尽管
children
字段具有
ConcurrentMap
类型),因此每次调用都可能得到不同的
io.prometheus.client.Counter.Child

至于通过http获取度量,每个对
/metrics
端点的调用都会导致
io.prometheus.client.Counter#collect
方法调用,它只检索一个子节点的值

我建议您使用自己的并发映射来存储计数器:

private static final ConcurrentMap<String, Counter.Child> counters = new ConcurrentHashMap<>();   

// ...

private static void incrementCounter(String status) {
  Counter.Child counter = counters.computeIfAbsent(status, myCounter::labels) ;
  // ...
}
私有静态最终ConcurrentMap计数器=新ConcurrentHashMap();
// ...
专用静态无效增量计数器(字符串状态){
Counter.Child Counter=counters.ComputeFabSent(状态,myCounter::labels);
// ...
}

您正在创建子计数器
Counter.child Counter=myCounter.labels(状态)所以基本上每个状态都有一个不同的计数器。我理解。这一切都是为了相同的状态。是否有任何调用myCounter上的remove或clear的操作?我们没有显式编写任何操作,没有。我们使用的唯一方法是计数器子对象上的.labels(),然后是.inc(),.get()。不确定普罗米修斯图书馆里是否有这样的东西。