mirror of https://github.com/sysown/proxysql
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
262 lines
7.8 KiB
262 lines
7.8 KiB
diff --git a/pull/include/prometheus/exposer.h b/pull/include/prometheus/exposer.h
|
|
index 93e0b2b..0e83a7a 100644
|
|
--- a/pull/include/prometheus/exposer.h
|
|
+++ b/pull/include/prometheus/exposer.h
|
|
@@ -6,9 +6,12 @@
|
|
#include <mutex>
|
|
#include <string>
|
|
#include <vector>
|
|
+#include <functional>
|
|
+#include <map>
|
|
|
|
#include "prometheus/collectable.h"
|
|
#include "prometheus/detail/pull_export.h"
|
|
+#include "prometheus/registry.h"
|
|
|
|
class CivetServer;
|
|
struct CivetCallbacks;
|
|
@@ -17,6 +20,7 @@ namespace prometheus {
|
|
|
|
namespace detail {
|
|
class Endpoint;
|
|
+class SerialMetricsHandler;
|
|
} // namespace detail
|
|
|
|
class PROMETHEUS_CPP_PULL_EXPORT Exposer {
|
|
@@ -53,4 +57,18 @@ class PROMETHEUS_CPP_PULL_EXPORT Exposer {
|
|
std::mutex mutex_;
|
|
};
|
|
|
|
+class SerialExposer {
|
|
+ public:
|
|
+ explicit SerialExposer(const std::function<void()> update_callback = std::function<void()> {});
|
|
+ std::pair<std::map<std::string, std::string>, std::string>
|
|
+ operator()(const std::map<std::string, std::string>& req_headers);
|
|
+ void RegisterCollectable(const std::weak_ptr<Collectable>& collectable);
|
|
+ ~SerialExposer();
|
|
+
|
|
+ private:
|
|
+ std::vector<std::weak_ptr<Collectable>> collectables_;
|
|
+ std::shared_ptr<Registry> exposer_registry_;
|
|
+ std::unique_ptr<detail::SerialMetricsHandler> metrics_handler_;
|
|
+};
|
|
+
|
|
} // namespace prometheus
|
|
diff --git a/pull/src/exposer.cc b/pull/src/exposer.cc
|
|
index 38a28e0..0d62bf3 100644
|
|
--- a/pull/src/exposer.cc
|
|
+++ b/pull/src/exposer.cc
|
|
@@ -1,4 +1,5 @@
|
|
#include "prometheus/exposer.h"
|
|
+#include "handler.h"
|
|
|
|
#include <algorithm>
|
|
#include <iterator>
|
|
@@ -63,4 +64,28 @@ detail::Endpoint& Exposer::GetEndpointForUri(const std::string& uri) {
|
|
return *endpoints_.back().get();
|
|
}
|
|
|
|
+SerialExposer::SerialExposer(
|
|
+ const std::function<void()> update_callback
|
|
+) :
|
|
+ exposer_registry_(std::make_shared<Registry>()),
|
|
+ metrics_handler_(new detail::SerialMetricsHandler {
|
|
+ collectables_, *exposer_registry_, update_callback
|
|
+ })
|
|
+{
|
|
+ RegisterCollectable(exposer_registry_);
|
|
+}
|
|
+
|
|
+SerialExposer::~SerialExposer() {}
|
|
+
|
|
+std::pair<std::map<std::string, std::string>, std::string>
|
|
+SerialExposer::operator()(const std::map<std::string, std::string>& req_headers) {
|
|
+ return (*this->metrics_handler_)(req_headers);
|
|
+}
|
|
+
|
|
+void SerialExposer::RegisterCollectable(
|
|
+ const std::weak_ptr<Collectable>& collectable
|
|
+) {
|
|
+ collectables_.push_back(collectable);
|
|
+}
|
|
+
|
|
} // namespace prometheus
|
|
diff --git a/pull/src/handler.cc b/pull/src/handler.cc
|
|
index 5a55001..b6ffa85 100644
|
|
--- a/pull/src/handler.cc
|
|
+++ b/pull/src/handler.cc
|
|
@@ -172,5 +172,124 @@ void MetricsHandler::CleanupStalePointers(
|
|
}),
|
|
std::end(collectables));
|
|
}
|
|
+
|
|
+//////////////////////////////////////////////////////
|
|
+/// Serial Metrics Handler ///
|
|
+//////////////////////////////////////////////////////
|
|
+
|
|
+SerialMetricsHandler::SerialMetricsHandler(
|
|
+ const std::vector<std::weak_ptr<Collectable>>& collectables,
|
|
+ Registry& registry,
|
|
+ const std::function<void()> update_callback)
|
|
+:
|
|
+ collectables_(collectables),
|
|
+ bytes_transferred_family_(
|
|
+ BuildCounter()
|
|
+ .Name("exposer_transferred_bytes_total")
|
|
+ .Help("Transferred bytes to metrics services")
|
|
+ .Register(registry)),
|
|
+ bytes_transferred_(bytes_transferred_family_.Add({})),
|
|
+ num_scrapes_family_(BuildCounter()
|
|
+ .Name("exposer_scrapes_total")
|
|
+ .Help("Number of times metrics were scraped")
|
|
+ .Register(registry)),
|
|
+ num_scrapes_(num_scrapes_family_.Add({})),
|
|
+ request_latencies_family_(
|
|
+ BuildSummary()
|
|
+ .Name("exposer_request_latencies")
|
|
+ .Help("Latencies of serving scrape requests, in microseconds")
|
|
+ .Register(registry)),
|
|
+ request_latencies_(request_latencies_family_.Add(
|
|
+ {}, Summary::Quantiles{{0.5, 0.05}, {0.9, 0.01}, {0.99, 0.001}})),
|
|
+ update_callback_(update_callback)
|
|
+{}
|
|
+
|
|
+std::vector<MetricFamily> SerialMetricsHandler::CollectMetrics() const {
|
|
+ auto collected_metrics = std::vector<MetricFamily>{};
|
|
+
|
|
+ for (auto&& wcollectable : collectables_) {
|
|
+ auto collectable = wcollectable.lock();
|
|
+ if (!collectable) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ auto&& metrics = collectable->Collect();
|
|
+ collected_metrics.insert(collected_metrics.end(),
|
|
+ std::make_move_iterator(metrics.begin()),
|
|
+ std::make_move_iterator(metrics.end()));
|
|
+ }
|
|
+
|
|
+ return collected_metrics;
|
|
+}
|
|
+
|
|
+using std::pair;
|
|
+using std::vector;
|
|
+using std::string;
|
|
+using std::map;
|
|
+
|
|
+#ifdef HAVE_ZLIB
|
|
+static bool IsEncodingAccepted(const map<string, string>& headers, string encoding) {
|
|
+ auto accept_encoding = headers.find("Accept-Encoding");
|
|
+ if (accept_encoding == headers.end()) {
|
|
+ return false;
|
|
+ }
|
|
+ return accept_encoding->second == encoding;
|
|
+}
|
|
+#endif
|
|
+
|
|
+static pair<map<string, string>, std::string> WriteResponse(
|
|
+ const std::map<std::string, std::string>& req_headers,
|
|
+ const std::string& body
|
|
+) {
|
|
+ map<string, string> headers {};
|
|
+
|
|
+ headers.insert({ "Content-Type", "text/plain" });
|
|
+
|
|
+#ifdef HAVE_ZLIB
|
|
+ auto acceptsGzip = IsEncodingAccepted(req_headers, "gzip");
|
|
+
|
|
+ if (acceptsGzip) {
|
|
+ auto compressed = GZipCompress(body);
|
|
+
|
|
+ if (!compressed.empty()) {
|
|
+ headers.insert({"Content-Encoding", "gzip"});
|
|
+ headers.insert({"Content-Length", std::to_string(static_cast<unsigned long>(compressed.size()))});
|
|
+
|
|
+ // Convert the vector<BYTE> into std::string
|
|
+ std::string res_body { compressed.begin(), compressed.end() };
|
|
+
|
|
+ return { headers, res_body };
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
+ headers.insert({"Content-Length", std::to_string(static_cast<unsigned long>(body.size()))});
|
|
+
|
|
+ return { headers, body };
|
|
+}
|
|
+
|
|
+pair<map<string, string>, string> SerialMetricsHandler::operator()(
|
|
+ const map<string, string>& req_headers
|
|
+) {
|
|
+ auto start_time_of_request = std::chrono::steady_clock::now();
|
|
+
|
|
+ // Execute the callback updating the metrics
|
|
+ this->update_callback_();
|
|
+
|
|
+ auto metrics = CollectMetrics();
|
|
+ auto serializer = std::unique_ptr<Serializer>{ new TextSerializer() };
|
|
+ auto headers_body = WriteResponse(req_headers, serializer->Serialize(metrics));
|
|
+
|
|
+ auto stop_time_of_request = std::chrono::steady_clock::now();
|
|
+ auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
|
|
+ stop_time_of_request - start_time_of_request
|
|
+ );
|
|
+
|
|
+ request_latencies_.Observe(duration.count());
|
|
+ bytes_transferred_.Increment(headers_body.second.size());
|
|
+ num_scrapes_.Increment();
|
|
+
|
|
+ return headers_body;
|
|
+}
|
|
+
|
|
} // namespace detail
|
|
} // namespace prometheus
|
|
diff --git a/pull/src/handler.h b/pull/src/handler.h
|
|
index 10c90f9..8b62aab 100644
|
|
--- a/pull/src/handler.h
|
|
+++ b/pull/src/handler.h
|
|
@@ -3,6 +3,7 @@
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include <vector>
|
|
+#include <functional>
|
|
|
|
#include "CivetServer.h"
|
|
#include "prometheus/collectable.h"
|
|
@@ -34,6 +35,36 @@ class MetricsHandler : public CivetHandler {
|
|
Counter& num_scrapes_;
|
|
Family<Summary>& request_latencies_family_;
|
|
Summary& request_latencies_;
|
|
+ std::function<void()> update_callback_ {};
|
|
};
|
|
+
|
|
+//////////////////////////////////////////////////////
|
|
+/// Serial Metrics Handler ///
|
|
+//////////////////////////////////////////////////////
|
|
+
|
|
+class SerialMetricsHandler {
|
|
+ public:
|
|
+ SerialMetricsHandler(
|
|
+ const std::vector<std::weak_ptr<Collectable>>& collectables,
|
|
+ Registry& registry,
|
|
+ const std::function<void()> update_callback = std::function<void()> {}
|
|
+ );
|
|
+
|
|
+ std::pair<std::map<std::string, std::string>, std::string>
|
|
+ operator()(const std::map<std::string, std::string>& req_headers);
|
|
+
|
|
+ private:
|
|
+ std::vector<MetricFamily> CollectMetrics() const;
|
|
+
|
|
+ const std::vector<std::weak_ptr<Collectable>>& collectables_;
|
|
+ Family<Counter>& bytes_transferred_family_;
|
|
+ Counter& bytes_transferred_;
|
|
+ Family<Counter>& num_scrapes_family_;
|
|
+ Counter& num_scrapes_;
|
|
+ Family<Summary>& request_latencies_family_;
|
|
+ Summary& request_latencies_;
|
|
+ std::function<void()> update_callback_ {};
|
|
+};
|
|
+
|
|
} // namespace detail
|
|
} // namespace prometheus
|