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