]> git.lizzy.rs Git - minetest.git/blob - src/util/metricsbackend.cpp
Increase `ftos` precision (#13141)
[minetest.git] / src / util / metricsbackend.cpp
1 /*
2 Minetest
3 Copyright (C) 2013-2020 Minetest core developers team
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "metricsbackend.h"
21 #include "util/thread.h"
22 #if USE_PROMETHEUS
23 #include <prometheus/exposer.h>
24 #include <prometheus/registry.h>
25 #include <prometheus/counter.h>
26 #include <prometheus/gauge.h>
27 #include "log.h"
28 #include "settings.h"
29 #endif
30
31 /* Plain implementation */
32
33 class SimpleMetricCounter : public MetricCounter
34 {
35 public:
36         SimpleMetricCounter() : MetricCounter(), m_counter(0.0) {}
37
38         virtual ~SimpleMetricCounter() {}
39
40         void increment(double number) override
41         {
42                 MutexAutoLock lock(m_mutex);
43                 m_counter += number;
44         }
45         double get() const override
46         {
47                 MutexAutoLock lock(m_mutex);
48                 return m_counter;
49         }
50
51 private:
52         mutable std::mutex m_mutex;
53         double m_counter;
54 };
55
56 class SimpleMetricGauge : public MetricGauge
57 {
58 public:
59         SimpleMetricGauge() : MetricGauge(), m_gauge(0.0) {}
60
61         virtual ~SimpleMetricGauge() {}
62
63         void increment(double number) override
64         {
65                 MutexAutoLock lock(m_mutex);
66                 m_gauge += number;
67         }
68         void decrement(double number) override
69         {
70                 MutexAutoLock lock(m_mutex);
71                 m_gauge -= number;
72         }
73         void set(double number) override
74         {
75                 MutexAutoLock lock(m_mutex);
76                 m_gauge = number;
77         }
78         double get() const override
79         {
80                 MutexAutoLock lock(m_mutex);
81                 return m_gauge;
82         }
83
84 private:
85         mutable std::mutex m_mutex;
86         double m_gauge;
87 };
88
89 MetricCounterPtr MetricsBackend::addCounter(
90                 const std::string &name, const std::string &help_str, Labels labels)
91 {
92         return std::make_shared<SimpleMetricCounter>();
93 }
94
95 MetricGaugePtr MetricsBackend::addGauge(
96                 const std::string &name, const std::string &help_str, Labels labels)
97 {
98         return std::make_shared<SimpleMetricGauge>();
99 }
100
101 /* Prometheus backend */
102
103 #if USE_PROMETHEUS
104
105 class PrometheusMetricCounter : public MetricCounter
106 {
107 public:
108         PrometheusMetricCounter() = delete;
109
110         PrometheusMetricCounter(const std::string &name, const std::string &help_str,
111                         MetricsBackend::Labels labels,
112                         std::shared_ptr<prometheus::Registry> registry) :
113                         MetricCounter(),
114                         m_family(prometheus::BuildCounter()
115                                                         .Name(name)
116                                                         .Help(help_str)
117                                                         .Register(*registry)),
118                         m_counter(m_family.Add(labels))
119         {
120         }
121
122         virtual ~PrometheusMetricCounter() {}
123
124         virtual void increment(double number) { m_counter.Increment(number); }
125         virtual double get() const { return m_counter.Value(); }
126
127 private:
128         prometheus::Family<prometheus::Counter> &m_family;
129         prometheus::Counter &m_counter;
130 };
131
132 class PrometheusMetricGauge : public MetricGauge
133 {
134 public:
135         PrometheusMetricGauge() = delete;
136
137         PrometheusMetricGauge(const std::string &name, const std::string &help_str,
138                         MetricsBackend::Labels labels,
139                         std::shared_ptr<prometheus::Registry> registry) :
140                         MetricGauge(),
141                         m_family(prometheus::BuildGauge()
142                                                         .Name(name)
143                                                         .Help(help_str)
144                                                         .Register(*registry)),
145                         m_gauge(m_family.Add(labels))
146         {
147         }
148
149         virtual ~PrometheusMetricGauge() {}
150
151         virtual void increment(double number) { m_gauge.Increment(number); }
152         virtual void decrement(double number) { m_gauge.Decrement(number); }
153         virtual void set(double number) { m_gauge.Set(number); }
154         virtual double get() const { return m_gauge.Value(); }
155
156 private:
157         prometheus::Family<prometheus::Gauge> &m_family;
158         prometheus::Gauge &m_gauge;
159 };
160
161 class PrometheusMetricsBackend : public MetricsBackend
162 {
163 public:
164         PrometheusMetricsBackend(const std::string &addr) :
165                         MetricsBackend(), m_exposer(std::make_unique<prometheus::Exposer>(addr)),
166                         m_registry(std::make_shared<prometheus::Registry>())
167         {
168                 m_exposer->RegisterCollectable(m_registry);
169         }
170
171         virtual ~PrometheusMetricsBackend() {}
172
173         MetricCounterPtr addCounter(
174                         const std::string &name, const std::string &help_str,
175                         Labels labels = {}) override;
176         MetricGaugePtr addGauge(
177                         const std::string &name, const std::string &help_str,
178                         Labels labels = {}) override;
179
180 private:
181         std::unique_ptr<prometheus::Exposer> m_exposer;
182         std::shared_ptr<prometheus::Registry> m_registry;
183 };
184
185 MetricCounterPtr PrometheusMetricsBackend::addCounter(
186                 const std::string &name, const std::string &help_str, Labels labels)
187 {
188         return std::make_shared<PrometheusMetricCounter>(name, help_str, labels, m_registry);
189 }
190
191 MetricGaugePtr PrometheusMetricsBackend::addGauge(
192                 const std::string &name, const std::string &help_str, Labels labels)
193 {
194         return std::make_shared<PrometheusMetricGauge>(name, help_str, labels, m_registry);
195 }
196
197 MetricsBackend *createPrometheusMetricsBackend()
198 {
199         std::string addr;
200         g_settings->getNoEx("prometheus_listener_address", addr);
201         return new PrometheusMetricsBackend(addr);
202 }
203
204 #endif