From 3fa4401d736c4aac116039dfccbc83d2c1d1281c Mon Sep 17 00:00:00 2001 From: Mark Marchukov Date: Wed, 22 Jan 2020 17:07:39 -0700 Subject: [PATCH 1/2] moved Mohamed Bassem's Prometheus plugin into the LogDevice source tree. The plugin implements a StatsPublisher that makes LogDevice stats available to Prometheus over a specified TCP port. For more details see https://github.com/MohamedBassem/logdevice-prometheus. The plugin requires https://github.com/jupp0r/prometheus-cpp/ -- a C++ client library for Prometheus. It is currently pulled from GitHub on every clean build. It would be better to make it a git submodule of LogDevice. The plugin requires no new dependent packages. I changed the cmake options of prometheus-cpp build to remove the dependency on libcurl-dev. Added BUILD_PLUGINS cmake option for LogDevice. Default is ON. --- logdevice/CMake/build-config.cmake | 1 - logdevice/CMakeLists.txt | 6 + logdevice/plugins/prometheus/CMakeLists.txt | 14 ++ .../cmake/build-prometheus-cpp.cmake | 36 ++++ .../plugins/prometheus/src/CMakeLists.txt | 80 ++++++++ .../src/PrometheusPublisherFactory.h | 58 ++++++ .../prometheus/src/PrometheusSettings.h | 41 ++++ .../src/PrometheusStatsPublisher.cpp | 193 ++++++++++++++++++ .../prometheus/src/PrometheusStatsPublisher.h | 47 +++++ logdevice/plugins/prometheus/src/main.cpp | 18 ++ .../prometheus/src/tests/PublisherTest.cpp | 129 ++++++++++++ 11 files changed, 622 insertions(+), 1 deletion(-) create mode 100644 logdevice/plugins/prometheus/CMakeLists.txt create mode 100644 logdevice/plugins/prometheus/cmake/build-prometheus-cpp.cmake create mode 100644 logdevice/plugins/prometheus/src/CMakeLists.txt create mode 100644 logdevice/plugins/prometheus/src/PrometheusPublisherFactory.h create mode 100644 logdevice/plugins/prometheus/src/PrometheusSettings.h create mode 100644 logdevice/plugins/prometheus/src/PrometheusStatsPublisher.cpp create mode 100644 logdevice/plugins/prometheus/src/PrometheusStatsPublisher.h create mode 100644 logdevice/plugins/prometheus/src/main.cpp create mode 100644 logdevice/plugins/prometheus/src/tests/PublisherTest.cpp diff --git a/logdevice/CMake/build-config.cmake b/logdevice/CMake/build-config.cmake index 44038ea85e9d..fc468e617027 100644 --- a/logdevice/CMake/build-config.cmake +++ b/logdevice/CMake/build-config.cmake @@ -27,6 +27,5 @@ set(LOGDEVICE_PYTHON_CLIENT_DIR "${LOGDEVICE_DIR}/clients/python") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(UNIT_TEST_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/test) set(LOGDEVICE_PY_OUT ${CMAKE_BINARY_DIR}/python-out) diff --git a/logdevice/CMakeLists.txt b/logdevice/CMakeLists.txt index ddcd3c530398..acfca32a365e 100644 --- a/logdevice/CMakeLists.txt +++ b/logdevice/CMakeLists.txt @@ -49,6 +49,8 @@ include(build-config) option(BUILD_TESTS "If enabled, compile the tests." ON) option(BUILD_SUBMODULES "Build using Git submodules, to fulfill dependencies" ON) +option(BUILD_PLUGINS "If enabled, build standard plugins." ON) + if(${BUILD_SUBMODULES}) message("Building with submodules enabled") include(build-fmt) @@ -226,3 +228,7 @@ endif() add_subdirectory(examples) add_subdirectory(clients/python) add_subdirectory(ops) + +if (${BUILD_PLUGINS}) + add_subdirectory(plugins/prometheus) +endif() diff --git a/logdevice/plugins/prometheus/CMakeLists.txt b/logdevice/plugins/prometheus/CMakeLists.txt new file mode 100644 index 000000000000..933415d04556 --- /dev/null +++ b/logdevice/plugins/prometheus/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright (c) 2017-present, Facebook, Inc. and its affiliates. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + +set(CMAKE_THREAD_PREFER_PTHREAD ON) + +include(build-prometheus-cpp) + +add_subdirectory(src) diff --git a/logdevice/plugins/prometheus/cmake/build-prometheus-cpp.cmake b/logdevice/plugins/prometheus/cmake/build-prometheus-cpp.cmake new file mode 100644 index 000000000000..f408dcd7da61 --- /dev/null +++ b/logdevice/plugins/prometheus/cmake/build-prometheus-cpp.cmake @@ -0,0 +1,36 @@ +# Copyright (c) 2017-present, Facebook, Inc. and its affiliates. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. + +include(ExternalProject) + +ExternalProject_Add(prometheus + GIT_REPOSITORY https://github.com/jupp0r/prometheus-cpp + GIT_TAG master + PREFIX "${CMAKE_CURRENT_BINARY_DIR}" + SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/external/prometheus-cpp" + CMAKE_ARGS -DBUILD_SHARED_LIBS=OFF + -DENABLE_TESTING=OFF + -DENABLE_PUSH=OFF + -DCMAKE_POSITION_INDEPENDENT_CODE=ON + INSTALL_COMMAND make install DESTDIR=${LOGDEVICE_STAGING_DIR} + ) + +ExternalProject_Get_Property(prometheus SOURCE_DIR) +ExternalProject_Get_Property(prometheus BINARY_DIR) + +set(PROMETHEUS_LIBRARIES + ${LOGDEVICE_STAGING_DIR}/usr/local/lib/libprometheus-cpp-core.a + ${LOGDEVICE_STAGING_DIR}/usr/local/lib/libprometheus-cpp-pull.a) + +set(PROMETHEUS_INCLUDE_DIR ${LOGDEVICE_STAGING_DIR}/usr/local/include) + +message(STATUS "Prometheus Library: ${PROMETHEUS_LIBRARIES}") +message(STATUS "Prometheus Includes: ${PROMETHEUS_INCLUDE_DIR}") + +mark_as_advanced( + PROMETHEUS_LIBRARIES + PROMETHEUS_INCLUDE_DIR +) diff --git a/logdevice/plugins/prometheus/src/CMakeLists.txt b/logdevice/plugins/prometheus/src/CMakeLists.txt new file mode 100644 index 000000000000..6a52fae600b5 --- /dev/null +++ b/logdevice/plugins/prometheus/src/CMakeLists.txt @@ -0,0 +1,80 @@ +# Copyright (c) 2017-present, Facebook, Inc. and its affiliates. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. + +# The plugin's main shared library +add_library(ldprometheus + SHARED + PrometheusPublisherFactory + PrometheusStatsPublisher + PrometheusSettings + main +) + +add_dependencies(ldprometheus prometheus folly) + +target_include_directories( + ldprometheus + PUBLIC + ${LOGDEVICE_INCLUDE_DIRS} + ${PROMETHEUS_INCLUDE_DIR} +) + +# Build our shared library with -fPIC +set_target_properties( + ldprometheus + PROPERTIES + POSITION_INDEPENDENT_CODE True +) + +# Link the prometheus library statically +target_link_libraries( + ldprometheus + "-Wl,--whole-archive" + ${PROMETHEUS_LIBRARIES} + "-Wl,--no-whole-archive" +) + + +# Building the tests +if(${BUILD_TESTS}) + add_executable(prometheus_test tests/PublisherTest.cpp) + add_dependencies(prometheus_test ldprometheus) + target_include_directories( + prometheus_test + PUBLIC + ${GTEST_INCLUDE_DIRS}) + target_link_libraries( + prometheus_test + ldprometheus + common + logdevice_server + ${GTEST_LIBRARY} + ${PROMETHEUS_LIBRARIES} + ${LOGDEVICE_EXTERNAL_DEPS} + glog + Threads::Threads) + + if (HAVE_CMAKE_GTEST) + gtest_discover_tests(prometheus_test + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + else() + add_test( + NAME PrometheusTest + COMMAND ${UNIT_TEST_OUTPUT_DIRECTORY}/prometheus_test + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + endif() + + add_test(NAME prometheus_test COMMAND prometheus_test) + + set_target_properties(prometheus_test + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${UNIT_TEST_OUTPUT_DIRECTORY}) + + target_compile_definitions(prometheus_test + PRIVATE + GTEST_USE_OWN_TR1_TUPLE=0 + ) +endif(${BUILD_TESTS}) diff --git a/logdevice/plugins/prometheus/src/PrometheusPublisherFactory.h b/logdevice/plugins/prometheus/src/PrometheusPublisherFactory.h new file mode 100644 index 000000000000..16bddb3c3f4f --- /dev/null +++ b/logdevice/plugins/prometheus/src/PrometheusPublisherFactory.h @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. and its affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * @author Mohamed Bassem + */ + +#include +#include +#include +#include + +#include "PrometheusSettings.h" +#include "PrometheusStatsPublisher.h" + +namespace facebook { namespace logdevice { + +class PrometheusStatsPublisherFactory : public StatsPublisherFactory { + public: + virtual ~PrometheusStatsPublisherFactory() = default; + + PluginType type() const override { + return PluginType::STATS_PUBLISHER_FACTORY; + } + + std::unique_ptr operator()(UpdateableSettings, + int num_db_shards) override { + if (prometheus_settings_->prometheus_listen_addr.empty()) { + ld_error("Prometheus was used as the stats publisher, but the listen " + "address is not set. Will not load the plugin."); + return nullptr; + } + return std::make_unique( + prometheus_settings_->prometheus_listen_addr); + } + + std::string identifier() const override { + return "logdevice-prometheus"; + } + + std::string displayName() const override { + return "Logdevice Prometheus"; + } + + virtual void addOptions(SettingsUpdater* updater) override { + updater->registerSettings(prometheus_settings_); + } + + private: + UpdateableSettings prometheus_settings_; +}; + +}} // namespace facebook::logdevice diff --git a/logdevice/plugins/prometheus/src/PrometheusSettings.h b/logdevice/plugins/prometheus/src/PrometheusSettings.h new file mode 100644 index 000000000000..6e94ec3065e2 --- /dev/null +++ b/logdevice/plugins/prometheus/src/PrometheusSettings.h @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. and its affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * @author Mohamed Bassem + */ + +#include + +namespace facebook { namespace logdevice { + +class PrometheusSettings : public SettingsBundle { + public: + virtual const char* getName() const override { + return "Prometheus"; + } + + virtual void defineSettings(SettingEasyInit& init) { + using namespace SettingFlag; + + // TODO add support for push model for clients + init("prometheus-listen-addr", + &prometheus_listen_addr, + "", + nullptr, + "The address that the prometheus exposer will listen on", + SERVER | CLIENT | REQUIRES_RESTART, + SettingsCategory::Monitoring); + } + + virtual ~PrometheusSettings() override {} + + std::string prometheus_listen_addr; +}; + +}} // namespace facebook::logdevice diff --git a/logdevice/plugins/prometheus/src/PrometheusStatsPublisher.cpp b/logdevice/plugins/prometheus/src/PrometheusStatsPublisher.cpp new file mode 100644 index 000000000000..532bb53e56e0 --- /dev/null +++ b/logdevice/plugins/prometheus/src/PrometheusStatsPublisher.cpp @@ -0,0 +1,193 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. and its affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * @author Mohamed Bassem + */ + +#include "PrometheusStatsPublisher.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using prometheus::Family; +using prometheus::Gauge; + +namespace facebook { namespace logdevice { +namespace { + +using namespace facebook::logdevice; + +class PrometheusEnumerationCallback : public Stats::EnumerationCallbacks { + public: + PrometheusEnumerationCallback(PrometheusStatsPublisher* publisher, + const std::string& stats_name) + : publisher_(publisher), stats_name_(stats_name) {} + + virtual ~PrometheusEnumerationCallback() {} + + void updateCounter(const std::string& name, + std::map labels, + double val) { + if (!prometheus::CheckMetricName(name)) { + // TODO replace the dots with other character. + // TODO figure out what's wrong with the failing stats. + return; + } + auto& family = publisher_->getFamily(name, stats_name_); + auto& counter = family.Add(std::move(labels)); + counter.Set(val); + } + + // Simple stats. + void stat(const std::string& name, int64_t val) override { + updateCounter(name, {}, val); + } + // Per-message-type stats. + void stat(const std::string& name, + MessageType message_type, + int64_t val) override { + updateCounter( + name, {{"message_type", messageTypeNames()[message_type]}}, val); + } + // Per-shard stats. + void stat(const std::string& name, + shard_index_t shard, + int64_t val) override { + updateCounter(name, {{"shard_index", std::to_string(shard)}}, val); + } + // Per-traffic-class stats. + void stat(const std::string& name, TrafficClass tc, int64_t val) override { + updateCounter(name, {{"traffic_class", trafficClasses()[tc]}}, val); + } + // Per-flow-group stats. + void stat(const std::string& name, + NodeLocationScope flow_group, + int64_t val) override { + // Not needed as it's included in the per-flow-group per message one. + } + // Per-flow-group-and-msg-priority stats. + void stat(const std::string& name, + NodeLocationScope flow_group, + Priority priority, + int64_t val) override { + updateCounter(name, + {{"flow_group", NodeLocation::scopeNames()[flow_group]}, + {"priority", PriorityMap::toName()[priority]}}, + val); + } + // Per-msg-priority stats (totals of the previous one). + void stat(const std::string& name, Priority, int64_t val) override { + // Not needed as it's included in the per-flow-group per message one. + } + // Per-request-type stats. + void stat(const std::string& name, RequestType type, int64_t val) override { + updateCounter(name, {{"request_type", requestTypeNames[type]}}, val); + } + // Per-storage-task-type stats. + void stat(const std::string& name, + StorageTaskType type, + int64_t val) override { + updateCounter(name, {{"storage_task_type", toString(type)}}, val); + } + // Per-worker stats (only for workers of type GENERAL). + void stat(const std::string& name, + worker_id_t worker_id, + uint64_t val) override { + updateCounter(name, {{"worker_id", std::to_string(worker_id.val())}}, val); + } + // Per-log stats. + void stat(const char* name, + const std::string& log_group, + int64_t val) override { + updateCounter(name, {{"log_group", log_group}}, val); + } + // Simple histograms. + void histogram(const std::string& name, + const HistogramInterface& hist) override { + updateCounter(name, {{"percentile", "50"}}, hist.estimatePercentile(0.5)); + updateCounter(name, {{"percentile", "90"}}, hist.estimatePercentile(0.9)); + updateCounter(name, {{"percentile", "99"}}, hist.estimatePercentile(0.99)); + updateCounter(name, {{"percentile", "max"}}, hist.estimatePercentile(1)); + } + // Per-shard histograms. + void histogram(const std::string& name, + shard_index_t shard, + const HistogramInterface& hist) override { + updateCounter( + name, + {{"shard_index", std::to_string(shard)}, {"percentile", "50"}}, + hist.estimatePercentile(0.5)); + updateCounter( + name, + {{"shard_index", std::to_string(shard)}, {"percentile", "90"}}, + hist.estimatePercentile(0.9)); + updateCounter( + name, + {{"shard_index", std::to_string(shard)}, {"percentile", "99"}}, + hist.estimatePercentile(0.99)); + updateCounter( + name, + {{"shard_index", std::to_string(shard)}, {"percentile", "max"}}, + hist.estimatePercentile(1)); + } + + private: + PrometheusStatsPublisher* publisher_; + std::string stats_name_; +}; +} // namespace + +PrometheusStatsPublisher::PrometheusStatsPublisher(const std::string& listen_addr) + : registry_(std::make_shared()) { + // TODO figure out a way to make the port work in dev clusters + exposer_ = std::make_unique(listen_addr); + exposer_->RegisterCollectable(registry_); + ld_info("Listening on addr %s", listen_addr.c_str()); +} + + +PrometheusStatsPublisher::PrometheusStatsPublisher(std::shared_ptr registry) + : registry_(std::move(registry)) {} + +void PrometheusStatsPublisher::publish( + const std::vector& current, + const std::vector& previous, + std::chrono::milliseconds elapsed) { + for (const auto& c : current) { + auto cb = PrometheusEnumerationCallback(this, c->params->get()->getStatsSetName()); + c->enumerate(&cb); + } +} + +void PrometheusStatsPublisher::addRollupEntity(std::string entity) {} + +Family& PrometheusStatsPublisher::getFamily(const std::string& name, + const std::string& stats_name) { + auto it = famililes_.find(name); + if (it == famililes_.end()) { + auto& fam = prometheus::BuildGauge() + .Name(name) + .Help("") + .Labels({{"source", stats_name}}) + .Register(*registry_); + auto new_f = famililes_.emplace(name, fam); + it = new_f.first; + } + return it->second; +} + +}} // namespace facebook::logdevice diff --git a/logdevice/plugins/prometheus/src/PrometheusStatsPublisher.h b/logdevice/plugins/prometheus/src/PrometheusStatsPublisher.h new file mode 100644 index 000000000000..5f0a43bcf979 --- /dev/null +++ b/logdevice/plugins/prometheus/src/PrometheusStatsPublisher.h @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. and its affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * @author Mohamed Bassem + */ + +#include + +#include +#include +#include +#include +#include + +namespace facebook { namespace logdevice { + +class PrometheusStatsPublisher : public StatsPublisher { + public: + PrometheusStatsPublisher(const std::string& listen_addr); + + // Used for tests + PrometheusStatsPublisher(std::shared_ptr registry); + + virtual ~PrometheusStatsPublisher() = default; + + void publish(const std::vector& current, + const std::vector& previous, + std::chrono::milliseconds elapsed) override; + + void addRollupEntity(std::string entity) override; + + prometheus::Family& getFamily(const std::string& name, const std::string& stats_name); + + private: + std::unique_ptr exposer_; + std::shared_ptr registry_; + std::unordered_map&> + famililes_; +}; + +}} // namespace facebook::logdevice diff --git a/logdevice/plugins/prometheus/src/main.cpp b/logdevice/plugins/prometheus/src/main.cpp new file mode 100644 index 000000000000..6dceaed79141 --- /dev/null +++ b/logdevice/plugins/prometheus/src/main.cpp @@ -0,0 +1,18 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. and its affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * @author Mohamed Bassem + */ + +#include "PrometheusPublisherFactory.h" + +extern "C" __attribute__((__used__)) facebook::logdevice::Plugin* +logdevice_plugin() { + return new facebook::logdevice::PrometheusStatsPublisherFactory(); +} diff --git a/logdevice/plugins/prometheus/src/tests/PublisherTest.cpp b/logdevice/plugins/prometheus/src/tests/PublisherTest.cpp new file mode 100644 index 000000000000..f42b5fcf6a1e --- /dev/null +++ b/logdevice/plugins/prometheus/src/tests/PublisherTest.cpp @@ -0,0 +1,129 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. and its affiliates. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * @author Mohamed Bassem + */ + +#include + +#include + +#include "../PrometheusStatsPublisher.h" + +#include +#include + +namespace facebook { namespace logdevice { + + +namespace { + std::ostream& operator<<(std::ostream& os, const prometheus::ClientMetric::Label& l) { + os << "{" << l.name << ", " << l.value << "}"; + return os; + } +} + + +const prometheus::MetricFamily* findFamily( + const std::vector& families, + const std::string& name) { + for (const auto& f: families) { + if (f.name == name) { + return &f; + } + } + return nullptr; +} + +const prometheus::ClientMetric* findMetric( + const prometheus::MetricFamily& family, + std::vector labels) { + + sort(labels.begin(), labels.end()); + + for (const auto& metric: family.metric) { + auto mlabel = metric.label; + sort(mlabel.begin(), mlabel.end()); + if (labels == mlabel) { + return &metric; + } + } + return nullptr; +} + +TEST(PublisherTest, testBasicMetrics) { + auto registry = std::make_shared(); + PrometheusStatsPublisher publisher(registry); + + StatsParams params; + params.is_server = true; + StatsHolder holder(params); + + STAT_INCR(&holder, post_request_total); + MESSAGE_TYPE_STAT_INCR(&holder, MessageType::HELLO, message_sent); + TRAFFIC_CLASS_STAT_INCR((&holder), TrafficClass::READ_TAIL, messages_sent); + PER_SHARD_STAT_INCR(&holder, shard_dirty, shard_index_t{5}); + REQUEST_TYPE_STAT_INCR(&holder, RequestType::APPEND, post_request); + + auto stats = holder.aggregate(); + + publisher.publish( + std::vector{&stats}, + std::vector{nullptr} /* not used */, + std::chrono::seconds(60)); + + auto metrics = registry->Collect(); + + { + // Basic + auto family = findFamily(metrics, "post_request_total"); + ASSERT_NE(nullptr, family); + auto metric = findMetric(*family, {{"source", "server"}}); + ASSERT_NE(nullptr, metric); + EXPECT_EQ(1, metric->gauge.value); + } + + { + // Per message + auto family = findFamily(metrics, "message_sent"); + ASSERT_NE(nullptr, family); + auto metric = findMetric(*family, {{"source", "server"}, {"message_type", "HELLO"}}); + ASSERT_NE(nullptr, metric); + EXPECT_EQ(1, metric->gauge.value); + } + + { + // Per traffic class + auto family = findFamily(metrics, "messages_sent"); + ASSERT_NE(nullptr, family); + auto metric = findMetric(*family, {{"source", "server"}, {"traffic_class", "READ_TAIL"}}); + ASSERT_NE(nullptr, metric); + EXPECT_EQ(1, metric->gauge.value); + } + + { + // Per shard + auto family = findFamily(metrics, "shard_dirty"); + ASSERT_NE(nullptr, family); + auto metric = findMetric(*family, {{"source", "server"}, {"shard_index", "5"}}); + ASSERT_NE(nullptr, metric); + EXPECT_EQ(1, metric->gauge.value); + } + + { + // Per request + auto family = findFamily(metrics, "post_request"); + ASSERT_NE(nullptr, family); + auto metric = findMetric(*family, {{"source", "server"}, {"request_type", "APPEND"}}); + ASSERT_NE(nullptr, metric); + EXPECT_EQ(1, metric->gauge.value); + } +} + +}} From 3cf03b95ab78132b6279ff0ab9003dcbeac223f4 Mon Sep 17 00:00:00 2001 From: Mark Marchukov Date: Thu, 23 Jan 2020 12:10:10 -0700 Subject: [PATCH 2/2] make prometheus-cpp a submodule of LogDevice If ldprometheus plugin is in the main build, its external dependencies should be handled the same way all other LogDevice external dependencies are. Test plan: Did a clean pull of LogDevice with this change into a new directory. Followed the steps to rebuild LogDevice normally. Verified that build completes and the Prometheus plugin loads fine. --- .gitmodules | 3 +++ logdevice/external/prometheus-cpp | 1 + .../cmake/build-prometheus-cpp.cmake | 20 +++++++++++-------- 3 files changed, 16 insertions(+), 8 deletions(-) create mode 160000 logdevice/external/prometheus-cpp diff --git a/.gitmodules b/.gitmodules index 933ef18d79e0..d00aa242af4b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -14,3 +14,6 @@ [submodule "logdevice/external/fbthrift"] path = logdevice/external/fbthrift url = https://github.com/facebook/fbthrift/ +[submodule "logdevice/external/prometheus-cpp"] + path = logdevice/external/prometheus-cpp + url = https://github.com/jupp0r/prometheus-cpp/ diff --git a/logdevice/external/prometheus-cpp b/logdevice/external/prometheus-cpp new file mode 160000 index 000000000000..3ec526a3b401 --- /dev/null +++ b/logdevice/external/prometheus-cpp @@ -0,0 +1 @@ +Subproject commit 3ec526a3b401b089bb8bf672b74e9fda9aa9b528 diff --git a/logdevice/plugins/prometheus/cmake/build-prometheus-cpp.cmake b/logdevice/plugins/prometheus/cmake/build-prometheus-cpp.cmake index f408dcd7da61..cf88855ff2a3 100644 --- a/logdevice/plugins/prometheus/cmake/build-prometheus-cpp.cmake +++ b/logdevice/plugins/prometheus/cmake/build-prometheus-cpp.cmake @@ -4,17 +4,20 @@ # This source code is licensed under the BSD-style license found in the # LICENSE file in the root directory of this source tree. +set(PROMETHEUS_ROOT_DIR ${LOGDEVICE_DIR}/external/prometheus-cpp) + include(ExternalProject) ExternalProject_Add(prometheus - GIT_REPOSITORY https://github.com/jupp0r/prometheus-cpp - GIT_TAG master - PREFIX "${CMAKE_CURRENT_BINARY_DIR}" - SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/external/prometheus-cpp" - CMAKE_ARGS -DBUILD_SHARED_LIBS=OFF - -DENABLE_TESTING=OFF - -DENABLE_PUSH=OFF - -DCMAKE_POSITION_INDEPENDENT_CODE=ON + SOURCE_DIR "${PROMETHEUS_ROOT_DIR}" + DOWNLOAD_COMMAND "" + CMAKE_ARGS + -DBUILD_SHARED_LIBS=OFF + -DENABLE_TESTING=OFF + -DENABLE_PUSH=OFF + -DCMAKE_POSITION_INDEPENDENT_CODE=ON + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_PREFIX_PATH=${LOGDEVICE_STAGING_DIR}/usr/local INSTALL_COMMAND make install DESTDIR=${LOGDEVICE_STAGING_DIR} ) @@ -31,6 +34,7 @@ message(STATUS "Prometheus Library: ${PROMETHEUS_LIBRARIES}") message(STATUS "Prometheus Includes: ${PROMETHEUS_INCLUDE_DIR}") mark_as_advanced( + PROMETHEUS_ROOT_DIR PROMETHEUS_LIBRARIES PROMETHEUS_INCLUDE_DIR )