diff --git a/presto-native-execution/CMakeLists.txt b/presto-native-execution/CMakeLists.txt index 15e5ed229b760..75a4dc90e1631 100644 --- a/presto-native-execution/CMakeLists.txt +++ b/presto-native-execution/CMakeLists.txt @@ -60,9 +60,17 @@ option(PRESTO_ENABLE_TESTING "Enable tests" ON) option(PRESTO_ENABLE_JWT "Enable JWT (JSON Web Token) authentication" OFF) + +option(PRESTO_ENABLE_PROMETHEUS_REPORTER + "Enables capturing of runtime metrics using prometheus client" OFF) + # Set all Velox options below add_compile_definitions(FOLLY_HAVE_INT128_T=1) +if(PRESTO_ENABLE_PROMETHEUS_REPORTER) + add_compile_definitions(PRESTO_ENABLE_PROMETHEUS_REPORTER) +endif() + if(PRESTO_ENABLE_S3) set(VELOX_ENABLE_S3 ON @@ -137,6 +145,10 @@ find_library(ZSTD zstd) find_package(ZLIB) find_library(SNAPPY snappy) +if(PRESTO_ENABLE_PROMETHEUS_REPORTER) + find_package(prometheus-cpp CONFIG REQUIRED) +endif() + find_package(folly CONFIG REQUIRED) set(FOLLY_WITH_DEPENDENCIES ${FOLLY_LIBRARIES} @@ -149,6 +161,13 @@ set(FOLLY_WITH_DEPENDENCIES ${ZSTD} ${ZLIB_LIBRARIES}) + +if(PRESTO_ENABLE_PROMETHEUS_REPORTER) + list(APPEND FOLLY_WITH_DEPENDENCIES + prometheus-cpp::core + prometheus-cpp::pull) +endif() + find_package(BZip2 MODULE) if(BZIP2_FOUND) list(APPEND FOLLY_WITH_DEPENDENCIES ${BZIP2_LIBRARIES}) @@ -168,6 +187,7 @@ find_library(WANGLE wangle) find_library(RE2 re2) + find_package(fizz CONFIG) find_package(wangle CONFIG) find_package(FBThrift) diff --git a/presto-native-execution/Makefile b/presto-native-execution/Makefile index 6e13f534923de..933f245ada95e 100644 --- a/presto-native-execution/Makefile +++ b/presto-native-execution/Makefile @@ -27,8 +27,13 @@ PRESTO_ENABLE_HDFS ?= "OFF" PRESTO_ENABLE_REMOTE_FUNCTIONS ?= "OFF" PRESTO_ENABLE_JWT ?= "OFF" EXTRA_CMAKE_FLAGS ?= "" +PRESTO_ENABLE_PROMETHEUS_REPORTER ?= "OFF" +# Check if PROMETHEUS_REPORTER is set to ON or OFF and set CMAKE_FLAGS accordingly + + CMAKE_FLAGS := -DTREAT_WARNINGS_AS_ERRORS=${TREAT_WARNINGS_AS_ERRORS} +CMAKE_FLAGS += -DPRESTO_ENABLE_PROMETHEUS_REPORTER=$(PRESTO_ENABLE_PROMETHEUS_REPORTER) CMAKE_FLAGS += -DENABLE_ALL_WARNINGS=${ENABLE_WALL} CMAKE_FLAGS += -DCMAKE_PREFIX_PATH=$(CMAKE_PREFIX_PATH) CMAKE_FLAGS += -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) @@ -54,6 +59,8 @@ CMAKE_FLAGS += -DCMAKE_CXX_COMPILER_LAUNCHER=ccache endif endif + + all: release #: Build the release version clean: #: Delete all build artifacts diff --git a/presto-native-execution/presto_cpp/CMakeLists.txt b/presto-native-execution/presto_cpp/CMakeLists.txt index e860e539a6a04..25fac57a29ba2 100644 --- a/presto-native-execution/presto_cpp/CMakeLists.txt +++ b/presto-native-execution/presto_cpp/CMakeLists.txt @@ -11,3 +11,8 @@ # limitations under the License. add_subdirectory(main) add_subdirectory(presto_protocol) + +if(PRESTO_ENABLE_PROMETHEUS_REPORTER) + add_subdirectory(metrics) +endif() + diff --git a/presto-native-execution/presto_cpp/main/CMakeLists.txt b/presto-native-execution/presto_cpp/main/CMakeLists.txt index 0a19fc67e0510..8bfdc892a7e85 100644 --- a/presto-native-execution/presto_cpp/main/CMakeLists.txt +++ b/presto-native-execution/presto_cpp/main/CMakeLists.txt @@ -70,6 +70,10 @@ target_link_libraries( ${GFLAGS_LIBRARIES} pthread) +if(PRESTO_ENABLE_PROMETHEUS_REPORTER) + target_link_libraries(presto_server_lib presto_metrics) +endif() + # Enabling Parquet causes build errors with missing symbols on MacOS. This is # likely due to a conflict between Arrow Thrift from velox_hive_connector and # FBThrift libraries. The build issue is fixed by linking velox_hive_connector diff --git a/presto-native-execution/presto_cpp/main/PrestoMain.cpp b/presto-native-execution/presto_cpp/main/PrestoMain.cpp index 9e74b5b1dacfd..c6e86fdfdd9d7 100644 --- a/presto-native-execution/presto_cpp/main/PrestoMain.cpp +++ b/presto-native-execution/presto_cpp/main/PrestoMain.cpp @@ -17,6 +17,9 @@ #include #include "presto_cpp/main/PrestoServer.h" #include "presto_cpp/main/common/Utils.h" +#ifdef PRESTO_ENABLE_PROMETHEUS_REPORTER +#include "presto_cpp/metrics/PrometheusStatsReporter.h" +#endif #include "velox/common/base/StatsReporter.h" DEFINE_string(etc_dir, ".", "etc directory for presto configuration"); @@ -31,7 +34,14 @@ int main(int argc, char* argv[]) { PRESTO_SHUTDOWN_LOG(INFO) << "Exiting main()"; } +#ifdef PRESTO_ENABLE_PROMETHEUS_REPORTER +// Initialize singleton for the reporter +folly::Singleton reporter([]() { + return new facebook::presto::PrometheusStatsReporter(); +}); +#else // Initialize singleton for the reporter. folly::Singleton reporter([]() { return new facebook::velox::DummyStatsReporter(); }); +#endif \ No newline at end of file diff --git a/presto-native-execution/presto_cpp/main/PrestoServer.cpp b/presto-native-execution/presto_cpp/main/PrestoServer.cpp index 0cd9b5f62084b..af0bae7805471 100644 --- a/presto-native-execution/presto_cpp/main/PrestoServer.cpp +++ b/presto-native-execution/presto_cpp/main/PrestoServer.cpp @@ -133,6 +133,10 @@ PrestoServer::PrestoServer(const std::string& configDirectoryPath) PrestoServer::~PrestoServer() {} +void registerPrometheusMetrics() { + facebook::velox::BaseStatsReporter::registered = true; +} + void PrestoServer::run() { auto systemConfig = SystemConfig::instance(); auto nodeConfig = NodeConfig::instance(); @@ -226,6 +230,10 @@ void PrestoServer::run() { PRESTO_STARTUP_LOG(ERROR) << "Failed to start server due to " << e.what(); exit(EXIT_FAILURE); } + #ifdef PRESTO_ENABLE_PROMETHEUS_REPORTER + // This flag must be set to register the counters. + registerPrometheusMetrics(); + #endif registerStatsCounters(); registerFileSinks(); diff --git a/presto-native-execution/presto_cpp/main/common/Configs.cpp b/presto-native-execution/presto_cpp/main/common/Configs.cpp index e07d83461b63e..c4bbe333ca10c 100644 --- a/presto-native-execution/presto_cpp/main/common/Configs.cpp +++ b/presto-native-execution/presto_cpp/main/common/Configs.cpp @@ -619,6 +619,7 @@ NodeConfig::NodeConfig() { NONE_PROP(kNodeIp), NONE_PROP(kNodeInternalAddress), NONE_PROP(kNodeLocation), + NONE_PROP(KNodeMetricPort), }; } @@ -635,6 +636,16 @@ std::string NodeConfig::nodeId() const { return requiredProperty(kNodeId); } +std::string NodeConfig::nodeMetricPort(std::string& defaultPort) const { + auto resultOpt = optionalProperty(KNodeMetricPort); + if (resultOpt.has_value()) { + return resultOpt.value(); + } else { + return defaultPort; + } + return requiredProperty(KNodeMetricPort); +} + std::string NodeConfig::nodeLocation() const { return requiredProperty(kNodeLocation); } diff --git a/presto-native-execution/presto_cpp/main/common/Configs.h b/presto-native-execution/presto_cpp/main/common/Configs.h index f0a442deab3eb..bf9fd600b5121 100644 --- a/presto-native-execution/presto_cpp/main/common/Configs.h +++ b/presto-native-execution/presto_cpp/main/common/Configs.h @@ -692,6 +692,7 @@ class NodeConfig : public ConfigBase { static constexpr std::string_view kNodeInternalAddress{ "node.internal-address"}; static constexpr std::string_view kNodeLocation{"node.location"}; + static constexpr std::string_view KNodeMetricPort{"node.prometheus_port"}; NodeConfig(); @@ -703,6 +704,8 @@ class NodeConfig : public ConfigBase { std::string nodeId() const; + std::string nodeMetricPort(std::string& defaultPort) const; + std::string nodeInternalAddress( const std::function& defaultIp = nullptr) const; diff --git a/presto-native-execution/presto_cpp/metrics/CMakeLists.txt b/presto-native-execution/presto_cpp/metrics/CMakeLists.txt new file mode 100644 index 0000000000000..0e293547ee771 --- /dev/null +++ b/presto-native-execution/presto_cpp/metrics/CMakeLists.txt @@ -0,0 +1,19 @@ +# 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. + +add_library(presto_metrics OBJECT PrometheusStatsReporter.cpp) + +target_link_libraries(presto_metrics presto_common velox_config velox_core velox_exception prometheus-cpp::core prometheus-cpp::pull) + +if(PRESTO_ENABLE_TESTING) + add_subdirectory(tests) +endif() \ No newline at end of file diff --git a/presto-native-execution/presto_cpp/metrics/PrometheusStatsReporter.cpp b/presto-native-execution/presto_cpp/metrics/PrometheusStatsReporter.cpp new file mode 100644 index 0000000000000..1c738385d2d7d --- /dev/null +++ b/presto-native-execution/presto_cpp/metrics/PrometheusStatsReporter.cpp @@ -0,0 +1,170 @@ +/* +* 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 "PrometheusStatsReporter.h" +#include "velox/common/base/StatsReporter.h" +#include "prometheus/client_metric.h" +#include "prometheus/counter.h" +#include "prometheus/summary.h" +#include "prometheus/gauge.h" + + +namespace facebook::presto { + +void PrometheusStatsReporter::registerMetricExportType(folly::StringPiece key, facebook::velox::StatType statType) const { + registerMetricExportType(key.start(), statType); +} + + +void PrometheusStatsReporter::registerMetricExportType(const char* key, velox::StatType statType) const { + std::string keyStr = sanitizeMetricName(key); + statTypeMap.insert({keyStr, statType}); + LOG(INFO) << "Registered metric: " << keyStr << " with type: " << statTypeToString(statType); + + switch (statType) { + case velox::StatType::AVG:{ + registerSummaryMetricForAverageStatType(keyStr); + break; + } + case velox::StatType::SUM: { + registerGaugeMetric(keyStr); + break; + } + case velox::StatType::COUNT: { + registerCounterMetric(keyStr); + break; + } + case velox::StatType::RATE: + // ToDo: RATE Type is not yet used anywhere + default: + LOG(WARNING) << "Unsupported stat type for key: " << keyStr; + break; + } +} + + + +void PrometheusStatsReporter::addMetricValue(const char* key, size_t value) + const { + addMetricValue(std::string(key), value); +} + +void PrometheusStatsReporter::addMetricValue(folly::StringPiece key, size_t value) + const { + addMetricValue(key.str(), value); +} + +void PrometheusStatsReporter::addMetricValue(const std::string& key, size_t value) const { + std::string keyStr = sanitizeMetricName(key); + auto statTypeIt = statTypeMap.find(keyStr); + if (statTypeIt == statTypeMap.end()) { + LOG(WARNING) << "Metric not registered: " << keyStr; + return; + } + + switch (statTypeIt->second) { + case velox::StatType::AVG: { + updateSummaryMetric(keyStr, value); + break; + } + case velox::StatType::SUM: { + updateGaugeMetric(keyStr, value); + break; + } + case velox::StatType::COUNT: { + updateCounterMetric(keyStr, value); + break; + } + case velox::StatType::RATE: + // ToDo: RATE Type is not yet used anywhere + default: + LOG(WARNING) << "Unsupported stat type for key: " << keyStr; + break; + } +} + +void PrometheusStatsReporter::registerSummaryMetricForAverageStatType(const std::string& keyStr) const { + auto& summaryFamily = prometheus::BuildSummary() + .Name(keyStr) + .Help("Summary for " + keyStr) + .Register(*registry); + auto& summary = summaryFamily.Add({{"cluster", cluster_}, {"node", node_}, {"host", host_}}, + prometheus::Summary::Quantiles{{0.5, 0.05}}); + summaryMap.insert({keyStr, &summary}); +} + +void PrometheusStatsReporter::registerGaugeMetric(const std::string& keyStr) const { + auto& gaugeFamily = prometheus::BuildGauge() + .Name(keyStr) + .Help("Gauge for " + keyStr) + .Register(*registry); + auto& gauge = gaugeFamily.Add({{"cluster", cluster_}, {"node", node_}, {"host", host_}}); + gaugeMap.insert({keyStr, &gauge}); +} + +void PrometheusStatsReporter::registerCounterMetric(const std::string& keyStr) const { + auto& counterFamily = prometheus::BuildCounter() + .Name(keyStr) + .Help("Counter for " + keyStr) + .Register(*registry); + auto& counter = counterFamily.Add({{"cluster", cluster_}, {"node", node_}, {"host", host_}}); + counterMap.insert({keyStr, &counter}); +} + +void PrometheusStatsReporter::updateSummaryMetric(const std::string& keyStr, size_t value) const { + auto summaryIt = summaryMap.find(keyStr); + if (summaryIt != summaryMap.end()) { + summaryIt->second->Observe(static_cast(value)); + } else { + LOG(WARNING) << "Summary metric not found: " << keyStr; + } +} + +void PrometheusStatsReporter::updateGaugeMetric(const std::string& keyStr, size_t value) const { + auto gaugeIt = gaugeMap.find(keyStr); + if (gaugeIt != gaugeMap.end()) { + gaugeIt->second->Increment(static_cast(value)); + } else { + LOG(WARNING) << "Gauge metric not found: " << keyStr; + } +} + +void PrometheusStatsReporter::updateCounterMetric(const std::string& keyStr, size_t value) const { + auto counterIt = counterMap.find(keyStr); + if (counterIt != counterMap.end()) { + counterIt->second->Increment(static_cast(value)); + } else { + LOG(WARNING) << "Counter metric not found: " << keyStr; + } +} + +std::string PrometheusStatsReporter::sanitizeMetricName( + const std::string& name) { + std::string sanitized = name; + std::replace(sanitized.begin(), sanitized.end(), '.', '_'); + return sanitized; +} +std::string PrometheusStatsReporter::statTypeToString( + velox::StatType statType) const { + switch (statType) { + case velox::StatType::AVG: return "AVG"; + case velox::StatType::SUM: return "SUM"; + case velox::StatType::RATE: return "RATE"; + case velox::StatType::COUNT: return "COUNT"; + default: return "Unknown StatType"; + } +} + + +} // namespace facebook::presto diff --git a/presto-native-execution/presto_cpp/metrics/PrometheusStatsReporter.h b/presto-native-execution/presto_cpp/metrics/PrometheusStatsReporter.h new file mode 100644 index 0000000000000..9f9d4469b971b --- /dev/null +++ b/presto-native-execution/presto_cpp/metrics/PrometheusStatsReporter.h @@ -0,0 +1,154 @@ +/* +* 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. + */ + +#pragma once + +#include +#include +#include +#include +#include "presto_cpp/main/common/Configs.h" +#include "presto_cpp/main/common/Counters.h" +#include "velox/common/base/StatsReporter.h" +#include "velox/velox/common/base/Exceptions.h" +#include +#include + +namespace facebook::presto { + +/** + * @brief Reporter class for Prometheus metrics + * + * This class is responsible for reporting statistics and metrics + * to Prometheus. + */ +class PrometheusStatsReporter : public facebook::velox::BaseStatsReporter { + + + public: + + explicit PrometheusStatsReporter() { + const char* odinCluster = std::getenv("ODIN_CLUSTER"); + const char* odinNode = std::getenv("ODIN_NODE"); + const char* hostName = std::getenv("HOST_NAME"); + cluster_ = (odinCluster != nullptr) ? odinCluster : ""; + node_ = (odinNode != nullptr) ? odinNode : ""; + host_ = (hostName != nullptr) ? hostName : ""; + // Get IP + auto nodeConfig = facebook::presto::NodeConfig::instance(); + // Create the server + std::string address_ = fmt::format("{}:{}", nodeConfig->nodeInternalAddress([this]() -> std::string { + return default_ip; + }), nodeConfig->nodeMetricPort(default_port)); + exposer = std::make_unique<::prometheus::Exposer>(address_); + LOG(INFO) << "Started Prometheus Metrics Server at " << address_; + registry = std::make_shared(); + exposer->RegisterCollectable(registry); + } + + // /// Register a stat of the given stat type. + // /// @param key The key to identify the stat. + // /// @param statType How the stat is aggregated. + void registerMetricExportType( + folly::StringPiece key, + facebook::velox::StatType statType) const override; + + void registerMetricExportType( + const char* key, + facebook::velox::StatType statType) const override; + + + /// Add the given value to the stat. + void addMetricValue(const std::string& key, size_t value = 1) const override; + + void addMetricValue(const char* key, size_t value = 1) const override; + + void addMetricValue(folly::StringPiece key, size_t value = 1) const override; + + + /// Add the given value to the histogram. + virtual void addHistogramMetricValue(const std::string& key, size_t value) + const override {} + + virtual void addHistogramMetricValue(const char* key, size_t value) const override {} + + virtual void addHistogramMetricValue(folly::StringPiece key, size_t value) + const override {} + + + /// Register a histogram with a list of percentiles defined. + /// @param key The key to identify the histogram. + /// @param bucketWidth The width of the buckets. + /// @param min The starting value of the buckets. + /// @param max The ending value of the buckets. + /// @param pcts The aggregated percentiles to be reported. + virtual void registerHistogramMetricExportType( + const char* key, + int64_t bucketWidth, + int64_t min, + int64_t max, + const std::vector& pcts ) const override{}; + + virtual void registerHistogramMetricExportType( + folly::StringPiece key, + int64_t bucketWidth, + int64_t min, + int64_t max, + const std::vector& pcts) const override {} + + // Getters for testing purposes + const folly::ConcurrentHashMap& getCounterMapForTest() const { + return counterMap; + } + + const folly::ConcurrentHashMap& getMetricTypesMapForTest() const { + return statTypeMap; + } + + // Visible for testing + prometheus::Counter* getCounter(std::string key){ + return counterMap[key]; + } + + // Visible for testing + velox::StatType getMetricType(std::string key){ + return statTypeMap[key]; + } + + // Visible for testing + mutable folly::ConcurrentHashMap statTypeMap; + mutable folly::ConcurrentHashMap counterMap; + mutable folly::ConcurrentHashMap gaugeMap; + mutable folly::ConcurrentHashMap summaryMap; + + private: + std::unique_ptr exposer; + std::shared_ptr registry; + std::string cluster_; + std::string host_; + std::string node_; + std::string default_port = "8082"; + std::string default_ip = "127.0.0.1"; + + void registerSummaryMetricForAverageStatType(const std::string& keyStr) const; + void registerGaugeMetric(const std::string& keyStr) const; + void registerCounterMetric(const std::string& keyStr) const; + void updateSummaryMetric(const std::string& keyStr, size_t value) const; + void updateGaugeMetric(const std::string& keyStr, size_t value) const; + void updateCounterMetric(const std::string& keyStr, size_t value) const; + static std::string sanitizeMetricName(const std::string& name) ; + std::string statTypeToString(velox::StatType statType) const; + +}; // class PrometheusStatsReporter +} // namespace facebook::presto diff --git a/presto-native-execution/presto_cpp/metrics/tests/CMakeLists.txt b/presto-native-execution/presto_cpp/metrics/tests/CMakeLists.txt new file mode 100644 index 0000000000000..d65466a5a8ea0 --- /dev/null +++ b/presto-native-execution/presto_cpp/metrics/tests/CMakeLists.txt @@ -0,0 +1,33 @@ +# 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. +add_executable(presto_metrics_test PrometheusStatsReporterTest.cpp) + +add_test( + NAME presto_server_test + COMMAND presto_server_test + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +target_link_libraries( + presto_metrics_test + presto_metrics + velox_vector_fuzzer + velox_exec_test_lib + velox_hive_partition_function + velox_vector_test_lib + velox_type + velox_vector + velox_exec + velox_memory + velox_exec + gmock + gtest + gtest_main) diff --git a/presto-native-execution/presto_cpp/metrics/tests/PrometheusStatsReporterTest.cpp b/presto-native-execution/presto_cpp/metrics/tests/PrometheusStatsReporterTest.cpp new file mode 100644 index 0000000000000..1c6f7bd76eaff --- /dev/null +++ b/presto-native-execution/presto_cpp/metrics/tests/PrometheusStatsReporterTest.cpp @@ -0,0 +1,65 @@ +#include +#include +#include "prometheus/counter.h" +#include "prometheus/summary.h" +#include "prometheus/gauge.h" +#include "presto_cpp/metrics/PrometheusStatsReporter.h" +#include "velox/common/base/StatsReporter.h" + +class PrometheusStatsReporterTest : public ::testing::Test { +}; + +// Derived from StatsReporterTest +TEST_F(PrometheusStatsReporterTest, trivialPReporter) { + auto reporter = std::dynamic_pointer_cast( + folly::Singleton::try_get()); + DEFINE_METRIC("key1", facebook::velox::StatType::COUNT); + DEFINE_METRIC("key2", facebook::velox::StatType::SUM); + DEFINE_METRIC("key3", facebook::velox::StatType::AVG); + //TODO: Turn on when adding histogram + // REPORT_ADD_HISTOGRAM_EXPORT_PERCENTILE("key4", 10, 0, 100, 50, 99, 100); + + EXPECT_EQ( facebook::velox::StatType::COUNT, reporter->statTypeMap["key1"]); + EXPECT_EQ( facebook::velox::StatType::SUM, reporter->statTypeMap["key2"]); + EXPECT_EQ( facebook::velox::StatType::AVG, reporter->statTypeMap["key3"]); + + //TODO: Turn on when adding histogram + std::vector expected = {50, 99, 100}; + // EXPECT_EQ(expected, reporter->histogramPercentilesMap["key4"]); + EXPECT_TRUE( + reporter->statTypeMap.find("key5") == reporter->statTypeMap.end()); + + RECORD_METRIC_VALUE("key1", 10); + RECORD_METRIC_VALUE("key1", 11); + RECORD_METRIC_VALUE("key1", 15); + RECORD_METRIC_VALUE("key2", 1001); + RECORD_METRIC_VALUE("key2", 1200); + RECORD_METRIC_VALUE("key3"); + RECORD_METRIC_VALUE("key3", 1100); + RECORD_METRIC_VALUE("key3", 5502); + //TODO: Turn on when adding histogram + // REPORT_ADD_HISTOGRAM_VALUE("key4", 50); + // REPORT_ADD_HISTOGRAM_VALUE("key4", 100); + + EXPECT_EQ(36, reporter->counterMap["key1"]->Value()); + EXPECT_EQ(2201, reporter->gaugeMap["key2"]->Value()); + // Calculate the average from observed values + auto summary = reporter->summaryMap["key3"]->Collect().summary; + auto observedAvg = summary.sample_sum / summary.sample_count; + EXPECT_EQ(2201, observedAvg); + //TODO: Turn on when adding histogram + // EXPECT_EQ(100, reporter->gaugeMap["key4"]->Value()); +}; + +// Registering to folly Singleton with intended reporter type +folly::Singleton reporter([]() { + return new facebook::presto::PrometheusStatsReporter(); +}); + + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + folly::init(&argc, &argv, false); + facebook::velox::BaseStatsReporter::registered = true; + return RUN_ALL_TESTS(); +}