当前位置: 首页 > 知识库问答 >
问题:

千分尺-普罗米修斯:有些仪表显示,其他没有

贺博厚
2023-03-14

我有一个 rabbitmq 消息队列,许多其他服务在其上报告所谓的的状态更新。现在,在单独的服务(使用SpringBoot编写)上,我需要侦听这些Point更新并将其转换为Prometheus可擦除的endpoint。

所以我的计划是将传入的Point对象转换为Meter并将它们注册到Meter注册表中。这是可行的,但只适用于某些点。我还没有弄清楚哪些是可见的,哪些不是,因为看起来这取决于它们在重新启动服务后进入的顺序。我还想不出任何模式,这将有助于故障排除。

根据我对千分尺留档的理解,Meter创建一次,我们给它一个对象和一个函数,允许它从该对象中检索度量的双精度值。因为,我每隔几秒钟就会有新的Point实例出现,该值不会只是在Meter引用旧的Point时更新。

假设这是正确的,我在周围添加了一个小包装器(PointWrapper),我将其传递给Meterhtml" target="_blank">缓存PointWrapper。现在,当一个新的进来时,我检查是否已经有了一个PointWrapper,如果是,我用新的实例替换包装器中的Point

@Service
public class PointSubscriber {
    
    private final MetricsService metrics;

    public PointSubscriber(@Autowired MetricsService metrics) {
        this.metrics = metrics;
    }

    @Bean
    public Consumer<PointUpdate> processPoint() {
        return (update) -> {
            metrics.update(update.getPoint());
        };
    }

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class MetricsService {

    private Logger logger = LoggerFactory.getLogger(getClass());

    private final MeterRegistry meterRegistry;

    private Map<String, PointWrapper> cache = new HashMap<>();

    public void update(Point point) {

        // Check if wrapper already in cache
        String pointId = point.getId();
        PointWrapper cached = cache.get(pointId);
        
        // Replace the point in the wrapper to update the value
        if (cached != null) {
            logger.debug("Updating value for {}", point.getId());
            cached.setPoint(point);
            
        // Create the wrapper, cache it and register Meter
        } else {
            PointWrapper pointMeter = PointWrapper.from(point.getId(), point);
            // Don't register Meters that will return null
            if (pointMeter.getMetricValue() == null) {
                logger.debug("Not going to register point with null value: {}", point.getId());
                return;
            }
            logger.debug("Registering point {}", point.getId());
            register(pointMeter, meterRegistry);
            cache.put(pointId, pointMeter);
        }
    }
    
    public Meter register(PointWrapper pointMeter, MeterRegistry registry) {
        Set<Tag> tags = new HashSet<>();
        tags.add(Tag.of("pointId", pointMeter.getPoint().getId()));
        tags.addAll(pointMeter.getPoint().getLabels().entrySet().stream()
            .map (e -> Tag.of(e.getKey(),e.getValue()))
            .collect(Collectors.toSet()));
        
        return Gauge.builder(pointMeter.getMetricName(), pointMeter, PointWrapper::getMetricValue)
            .tags(tags)
            .register(registry);
    }
    
}
@Data
@Builder
public class PointWrapper {
    
    public static PointWrapper from(String id, Point point) {       
        return PointWrapper.builder()
            .id(id)
            .metricName("symphony_point")
            .point(point)
            .build();
    }
        
    private String id;
    
    private String metricName;
     
    @EqualsAndHashCode.Exclude
    private Point point; 
    
    public Double getMetricValue() {
        if (point == null)
            return null;
        if (point instanceof QuantityPoint) {
            return ((QuantityPoint) point).getValue();
        } else if (point instanceof StatePoint<?>) {
            StatePoint<?> s = (StatePoint<?>) point;
            if (s.getState() == null)
                return null;
            return Double.valueOf(s.getState().asNumber());
        }
        return null;
    }
        
}

正如我所提到的,这会导致普罗米修斯endpoint中出现一堆缺失的数据点。我读到米s是由它们的名字标签唯一标识的。名称始终symphony_point但我将的 ID 添加为名为 pointId标记。正因为如此,每个 Meter.Id 都是独一无二的。

我可以看到这样的日志

Registering point outdoor_brightness_north

但是普罗米修斯终结点缺少了这一点。

有什么想法吗?

UPDATE@checkketts指出同名的指标必须设置相同的标签。我快速检查了一下可以确认,我使用的数据不是这样的:

symphony.point area pointId device property floor room
symphony.point area pointId device property floor room
symphony.point area pointId property room floor device
symphony.point area pointId property room floor device
symphony.point area room pointId device property floor
symphony.point pointId area room device property floor
symphony.point area room pointId device property floor
symphony.point area room property pointId floor device
symphony.point pointId area property device
symphony.point area device property pointId
symphony.point area room pointId floor device property
symphony.point area pointId device property floor room
symphony.point area pointId device property room floor
symphony.point area pointId property floor device room
symphony.point area room property pointId floor device
symphony.point area property room floor pointId device
symphony.point pointId area room property floor device
symphony.point area device pointId property
symphony.point area device property pointId floor room
symphony.point area pointId room device property floor
symphony.point area pointId room device property floor
symphony.point area room pointId device property floor
symphony.point area pointId room floor device property
symphony.point pointId area device property
symphony.point area property room floor device pointId
symphony.point area pointId device room property floor
symphony.point area room device property floor pointId
symphony.point area device pointId property floor room
symphony.point area pointId property floor device room
symphony.point pointId area device property
symphony.point area pointId device property floor room
symphony.point area pointId property room floor device
symphony.point area pointId room device property floor
symphony.point pointId property area device
symphony.point area property pointId floor device room
symphony.point area room property pointId floor device
symphony.point area room pointId property floor device
symphony.point area pointId floor device property room
symphony.point area room device pointId property floor
symphony.point pointId property area device
symphony.point area room device property pointId floor
symphony.point area device property floor pointId room
symphony.point area room pointId floor device property
symphony.point area pointId property room floor device
symphony.point area room device property floor pointId
symphony.point area room device pointId property floor
symphony.point pointId area device property
symphony.point area property floor pointId device room
symphony.point area pointId device property floor room
symphony.point area property pointId device
symphony.point pointId area property floor device room
symphony.point area pointId floor device property room
symphony.point area property pointId floor device room
symphony.point area room pointId floor device property
symphony.point pointId area device property
symphony.point area room pointId property floor device
symphony.point area room pointId floor device property
symphony.point area room device property pointId floor
symphony.point area pointId room property floor device
symphony.point area room device property floor pointId
symphony.point area pointId property room floor device
symphony.point pointId area property device
symphony.point area pointId device property floor room
symphony.point area device pointId property floor room
symphony.point area room pointId property floor device
symphony.point area pointId device property floor room
symphony.point area pointId device room property floor
symphony.point area room pointId device property floor
symphony.point area property room pointId floor device
symphony.point pointId area device property

这是一个很大的问题,因为通过< code >点(这是我构建< code >标记的地方)得到的标签没有很好的定义。我仍然需要能够基于它们进行查询。我可以把它们都加到名字里,但是像“显示所有室内温度”这样的东西查询起来会很不愉快。

无论如何,我将尝试验证这是我问题的根本原因。

共有1个答案

栾烨华
2023-03-14

这一行很可疑:

tags.addAll(pointMeter.getPoint().getLabels().entrySet().stream()
            .map (e -> Tag.of(e.getKey(),e.getValue()))
            .collect(Collectors.toSet()));

所有点是否具有相同的标签?对于普罗米修斯,所有具有相同名称的仪表需要具有相同的标签名(又名标签)。第一个点及其标签名称将成为默认值,其他所有点将被拒绝。

 类似资料:
  • 我试图在Spring Boot 2.0.0 .版本中使用Micrometer.io生成普罗米修斯指标 当我试图将列表的大小公开为Gauge时,它一直显示NaN。在留档中,它说; 你有责任对你用量规测量的状态对象保持强烈的引用。 我已经尝试了一些不同的方法,但我不能解决这个问题。这是我的代码和一些试验。 有人能帮忙解决这个问题吗?任何帮助都将不胜感激。

  • 我已经在一个千分尺计的方法中检测了我的代码,如下所示: 我还添加了一些其他指标。 其他指标显示在普罗米修斯endpoint上,但此指标指标不会。 我错过了什么?

  • 响应于“/acturet/prometheus”的DistributionSummary可用的度量仅是度量的Sum、Max和Count。 我想显示在选定的时间量内API调用所用的平均时间。用于EX:API在过去5分钟内所用的平均时间。

  • 我正在将Spring Boot应用程序从Spring Boot 1(使用Prometheus Simpleclient)转换为Spring Boot 2(使用微米)。 我很难将我们在《春靴1》和《普罗米修斯》中的标签转换为千分尺的概念。例如(普罗米修斯): Micrometer的标签似乎与Prometheus的标签有些不同:所有的值都必须预先声明,不仅仅是键。 可以将普罗米修斯的标签与Spring

  • 我可以在http://localhost:8080/hello/q/metrics看到这个指标。现在我想把这个度量标准推到普罗米修斯,但我还没有找到任何指南,说明如何在普罗米修斯注册/集成这些度量标准。理想情况下,我想把它们推到石墨上,但这不受支持。所以我想知道如何推动这些指标,这样我就可以在格拉法纳可视化它们。

  • 根据Micrometer的文档https://Micrometer.io/docs/concepts#_server_side,框架(Micrometer)应该处理将计时器度量从绝对量转换为速率 下面的代码模拟一个伪定时器: 然而,在Prometheus中,我只看到单调增加的度量和而不是将它们视为速率 也许我误解了或者忽略了文档中的某些内容?