/* * Copyright 2018 The Cartographer Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "cartographer/metrics/family_factory.h" #include "cartographer/metrics/register.h" #include "cartographer_grpc/metrics/prometheus/family_factory.h" #include "glog/logging.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include "prometheus/exposer.h" namespace cartographer_grpc { namespace metrics { namespace prometheus { namespace { static auto* kCounter = cartographer::metrics::Counter::Null(); static auto* kGauge = cartographer::metrics::Gauge::Null(); static auto* kScoresMetric = cartographer::metrics::Histogram::Null(); const char kLabelKey[] = "kind"; const char kLabelValue[] = "score"; const std::array kObserveScores = {{-1, 0.11, 0.2, 0.5, 2}}; class Algorithm { public: static void RegisterMetrics(cartographer::metrics::FamilyFactory* factory) { auto boundaries = cartographer::metrics::Histogram::FixedWidth(0.05, 20); auto* scores_family = factory->NewHistogramFamily( "/algorithm/scores", "Scores achieved", boundaries); kScoresMetric = scores_family->Add({{kLabelKey, kLabelValue}}); } void Run() { for (double score : kObserveScores) { kScoresMetric->Observe(score); } } }; TEST(MetricsTest, CollectCounter) { FamilyFactory factory; auto* counter_family = factory.NewCounterFamily("/test/hits", "Hits"); kCounter = counter_family->Add({{kLabelKey, kLabelValue}}); kCounter->Increment(); kCounter->Increment(5); double expected_value = 1 + 5; std::vector<::io::prometheus::client::MetricFamily> collected; { std::shared_ptr<::prometheus::Collectable> collectable; CHECK(collectable = factory.GetCollectable().lock()); collected = collectable->Collect(); } ASSERT_EQ(collected.size(), 1); ASSERT_EQ(collected[0].metric_size(), 1); EXPECT_THAT( collected[0].metric(0).label(), testing::AllOf( testing::ElementsAre(testing::Property( &io::prometheus::client::LabelPair::name, kLabelKey)), testing::ElementsAre(testing::Property( &io::prometheus::client::LabelPair::value, kLabelValue)))); EXPECT_THAT(collected[0].metric(0).counter().value(), testing::DoubleEq(expected_value)); } TEST(MetricsTest, CollectGauge) { FamilyFactory factory; auto* gauge_family = factory.NewGaugeFamily("/test/queue/length", "Length of some queue"); kGauge = gauge_family->Add({{kLabelKey, kLabelValue}}); kGauge->Increment(); kGauge->Increment(5); kGauge->Decrement(); kGauge->Decrement(2); double expected_value = 1 + 5 - 1 - 2; std::vector<::io::prometheus::client::MetricFamily> collected; { std::shared_ptr<::prometheus::Collectable> collectable; CHECK(collectable = factory.GetCollectable().lock()); collected = collectable->Collect(); } ASSERT_EQ(collected.size(), 1); ASSERT_EQ(collected[0].metric_size(), 1); EXPECT_THAT( collected[0].metric(0).label(), testing::AllOf( testing::ElementsAre(testing::Property( &io::prometheus::client::LabelPair::name, kLabelKey)), testing::ElementsAre(testing::Property( &io::prometheus::client::LabelPair::value, kLabelValue)))); EXPECT_THAT(collected[0].metric(0).gauge().value(), testing::DoubleEq(expected_value)); } TEST(MetricsTest, CollectHistogram) { FamilyFactory registry; Algorithm::RegisterMetrics(®istry); Algorithm algorithm; algorithm.Run(); std::vector<::io::prometheus::client::MetricFamily> collected; { std::shared_ptr<::prometheus::Collectable> collectable; CHECK(collectable = registry.GetCollectable().lock()); collected = collectable->Collect(); } ASSERT_EQ(collected.size(), 1); ASSERT_EQ(collected[0].metric_size(), 1); EXPECT_THAT( collected[0].metric(0).label(), testing::AllOf( testing::ElementsAre(testing::Property( &io::prometheus::client::LabelPair::name, kLabelKey)), testing::ElementsAre(testing::Property( &io::prometheus::client::LabelPair::value, kLabelValue)))); EXPECT_THAT(collected[0].metric(0).histogram().sample_count(), testing::Eq(kObserveScores.size())); EXPECT_EQ(collected[0].metric(0).histogram().bucket(0).cumulative_count(), 1); } TEST(MetricsTest, RunExposerServer) { FamilyFactory registry; Algorithm::RegisterMetrics(®istry); cartographer::metrics::RegisterAllMetrics(®istry); ::prometheus::Exposer exposer("0.0.0.0:9100"); exposer.RegisterCollectable(registry.GetCollectable()); Algorithm algorithm; algorithm.Run(); } } // namespace } // namespace prometheus } // namespace metrics } // namespace cartographer_grpc