| 1 | #include "PrometheusMetricsWriter.h" | 
|---|
| 2 |  | 
|---|
| 3 | #include <algorithm> | 
|---|
| 4 |  | 
|---|
| 5 | #include <IO/WriteHelpers.h> | 
|---|
| 6 |  | 
|---|
| 7 | namespace | 
|---|
| 8 | { | 
|---|
| 9 |  | 
|---|
| 10 | template <typename T> | 
|---|
| 11 | void writeOutLine(DB::WriteBuffer & wb, T && val) | 
|---|
| 12 | { | 
|---|
| 13 | DB::writeText(std::forward<T>(val), wb); | 
|---|
| 14 | DB::writeChar('\n', wb); | 
|---|
| 15 | } | 
|---|
| 16 |  | 
|---|
| 17 | template <typename T, typename... TArgs> | 
|---|
| 18 | void writeOutLine(DB::WriteBuffer & wb, T && val, TArgs &&... args) | 
|---|
| 19 | { | 
|---|
| 20 | DB::writeText(std::forward<T>(val), wb); | 
|---|
| 21 | DB::writeChar(' ', wb); | 
|---|
| 22 | writeOutLine(wb, std::forward<TArgs>(args)...); | 
|---|
| 23 | } | 
|---|
| 24 |  | 
|---|
| 25 | void replaceInvalidChars(std::string & metric_name) | 
|---|
| 26 | { | 
|---|
| 27 | std::replace(metric_name.begin(), metric_name.end(), '.', '_'); | 
|---|
| 28 | } | 
|---|
| 29 |  | 
|---|
| 30 | } | 
|---|
| 31 |  | 
|---|
| 32 |  | 
|---|
| 33 | namespace DB | 
|---|
| 34 | { | 
|---|
| 35 |  | 
|---|
| 36 | PrometheusMetricsWriter::PrometheusMetricsWriter( | 
|---|
| 37 | const Poco::Util::AbstractConfiguration & config, const std::string & config_name, | 
|---|
| 38 | const AsynchronousMetrics & async_metrics_) | 
|---|
| 39 | : async_metrics(async_metrics_) | 
|---|
| 40 | , send_events(config.getBool(config_name + ".events", true)) | 
|---|
| 41 | , send_metrics(config.getBool(config_name + ".metrics", true)) | 
|---|
| 42 | , send_asynchronous_metrics(config.getBool(config_name + ".asynchronous_metrics", true)) | 
|---|
| 43 | { | 
|---|
| 44 | } | 
|---|
| 45 |  | 
|---|
| 46 | void PrometheusMetricsWriter::write(WriteBuffer & wb) const | 
|---|
| 47 | { | 
|---|
| 48 | if (send_events) | 
|---|
| 49 | { | 
|---|
| 50 | for (size_t i = 0, end = ProfileEvents::end(); i < end; ++i) | 
|---|
| 51 | { | 
|---|
| 52 | const auto counter = ProfileEvents::global_counters[i].load(std::memory_order_relaxed); | 
|---|
| 53 |  | 
|---|
| 54 | std::string metric_name{ProfileEvents::getName(static_cast<ProfileEvents::Event>(i))}; | 
|---|
| 55 | std::string metric_doc{ProfileEvents::getDocumentation(static_cast<ProfileEvents::Event>(i))}; | 
|---|
| 56 |  | 
|---|
| 57 | replaceInvalidChars(metric_name); | 
|---|
| 58 | std::string key{profile_events_prefix + metric_name}; | 
|---|
| 59 |  | 
|---|
| 60 | writeOutLine(wb, "# HELP", key, metric_doc); | 
|---|
| 61 | writeOutLine(wb, "# TYPE", key, "counter"); | 
|---|
| 62 | writeOutLine(wb, key, counter); | 
|---|
| 63 | } | 
|---|
| 64 | } | 
|---|
| 65 |  | 
|---|
| 66 | if (send_metrics) | 
|---|
| 67 | { | 
|---|
| 68 | for (size_t i = 0, end = CurrentMetrics::end(); i < end; ++i) | 
|---|
| 69 | { | 
|---|
| 70 | const auto value = CurrentMetrics::values[i].load(std::memory_order_relaxed); | 
|---|
| 71 |  | 
|---|
| 72 | std::string metric_name{CurrentMetrics::getName(static_cast<CurrentMetrics::Metric>(i))}; | 
|---|
| 73 | std::string metric_doc{CurrentMetrics::getDocumentation(static_cast<CurrentMetrics::Metric>(i))}; | 
|---|
| 74 |  | 
|---|
| 75 | replaceInvalidChars(metric_name); | 
|---|
| 76 | std::string key{current_metrics_prefix + metric_name}; | 
|---|
| 77 |  | 
|---|
| 78 | writeOutLine(wb, "# HELP", key, metric_doc); | 
|---|
| 79 | writeOutLine(wb, "# TYPE", key, "gauge"); | 
|---|
| 80 | writeOutLine(wb, key, value); | 
|---|
| 81 | } | 
|---|
| 82 | } | 
|---|
| 83 |  | 
|---|
| 84 | if (send_asynchronous_metrics) | 
|---|
| 85 | { | 
|---|
| 86 | auto async_metrics_values = async_metrics.getValues(); | 
|---|
| 87 | for (const auto & name_value : async_metrics_values) | 
|---|
| 88 | { | 
|---|
| 89 | std::string key{asynchronous_metrics_prefix + name_value.first}; | 
|---|
| 90 |  | 
|---|
| 91 | replaceInvalidChars(key); | 
|---|
| 92 | auto value = name_value.second; | 
|---|
| 93 |  | 
|---|
| 94 | // TODO: add HELP section? asynchronous_metrics contains only key and value | 
|---|
| 95 | writeOutLine(wb, "# TYPE", key, "gauge"); | 
|---|
| 96 | writeOutLine(wb, key, value); | 
|---|
| 97 | } | 
|---|
| 98 | } | 
|---|
| 99 | } | 
|---|
| 100 |  | 
|---|
| 101 | } | 
|---|
| 102 |  | 
|---|