@@ -617,4 +617,56 @@ TEST(PrometheusExporterUtils, MultipleScopesMetricFamilyCollisions)
617617 EXPECT_DOUBLE_EQ (translated[0 ].metric [1 ].counter .value , 20.0 );
618618}
619619
620+ TEST (PrometheusExporterUtils, TargetInfoMetricFamilyCollisions)
621+ {
622+ Resource resource = Resource::Create (ResourceAttributes{{" service.name" , " test_service" }});
623+ auto scope = InstrumentationScope::Create (" scope_1" , " 1.0.0" );
624+
625+ metric_sdk::LastValuePointData target_gauge_point{};
626+ target_gauge_point.value_ = 42.0 ;
627+ target_gauge_point.is_lastvalue_valid_ = true ;
628+
629+ metric_sdk::LastValuePointData target_info_gauge_point{};
630+ target_info_gauge_point.value_ = 99.0 ;
631+ target_info_gauge_point.is_lastvalue_valid_ = true ;
632+
633+ // A unitless gauge named "target" does not collide with the generated Info family
634+ // (which is exposed as "target_info" in Prometheus text format).
635+ metric_sdk::MetricData target_gauge{
636+ metric_sdk::InstrumentDescriptor{" target" , " target gauge description" , " " ,
637+ metric_sdk::InstrumentType::kObservableGauge ,
638+ metric_sdk::InstrumentValueType::kDouble },
639+ metric_sdk::AggregationTemporality::kCumulative , opentelemetry::common::SystemTimestamp{},
640+ opentelemetry::common::SystemTimestamp{},
641+ std::vector<metric_sdk::PointDataAttributes>{{{}, target_gauge_point}}};
642+
643+ // A gauge named "target_info" collides with the generated Info family exposed as
644+ // "target_info" and is dropped due to type conflict.
645+ metric_sdk::MetricData target_info_gauge{
646+ metric_sdk::InstrumentDescriptor{" target_info" , " conflicting target_info gauge" , " " ,
647+ metric_sdk::InstrumentType::kObservableGauge ,
648+ metric_sdk::InstrumentValueType::kDouble },
649+ metric_sdk::AggregationTemporality::kCumulative , opentelemetry::common::SystemTimestamp{},
650+ opentelemetry::common::SystemTimestamp{},
651+ std::vector<metric_sdk::PointDataAttributes>{{{}, target_info_gauge_point}}};
652+
653+ metric_sdk::ResourceMetrics data{
654+ &resource,
655+ std::vector<metric_sdk::ScopeMetrics>{
656+ {scope.get (), std::vector<metric_sdk::MetricData>{target_gauge, target_info_gauge}}}};
657+
658+ auto translated = PrometheusExporterUtils::TranslateToPrometheus (
659+ data, /* populate_target_info=*/ true , /* without_otel_scope=*/ false ,
660+ /* without_units=*/ false , /* without_type_suffix=*/ false );
661+
662+ ASSERT_EQ (translated.size (), 2U );
663+ EXPECT_EQ (translated[0 ].name , " target" );
664+ EXPECT_EQ (translated[0 ].type , prometheus_client::MetricType::Info);
665+ EXPECT_EQ (translated[1 ].name , " target" );
666+ EXPECT_EQ (translated[1 ].help , " target gauge description" );
667+ EXPECT_EQ (translated[1 ].type , prometheus_client::MetricType::Gauge);
668+ ASSERT_EQ (translated[1 ].metric .size (), 1U );
669+ EXPECT_DOUBLE_EQ (translated[1 ].metric [0 ].gauge .value , 42.0 );
670+ }
671+
620672OPENTELEMETRY_END_NAMESPACE
0 commit comments