userver: userver/storages/postgres/statistics.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
statistics.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/storages/postgres/statistics.hpp
4/// @brief Statistics helpers
5
6#include <unordered_map>
7#include <vector>
8
9#include <userver/storages/postgres/detail/time_types.hpp>
10
11#include <userver/congestion_control/controllers/linear.hpp>
12#include <userver/utils/statistics/min_max_avg.hpp>
13#include <userver/utils/statistics/percentile.hpp>
14#include <userver/utils/statistics/rate_counter.hpp>
15#include <userver/utils/statistics/recentperiod.hpp>
16#include <userver/utils/statistics/relaxed_counter.hpp>
17#include <userver/utils/statistics/writer.hpp>
18
19USERVER_NAMESPACE_BEGIN
20
21namespace storages::postgres {
22
23/// @brief Template transaction statistics storage
24template <typename Counter, typename PercentileAccumulator>
26 /// Number of transactions started
27 Counter total = 0;
28 /// Number of transactions committed
29 Counter commit_total = 0;
30 /// Number of transactions rolled back
31 Counter rollback_total = 0;
32 /// Number of out-of-transaction executions
33 Counter out_of_trx_total = 0;
34 /// Number of parsed queries
35 Counter parse_total = 0;
36 /// Number of query executions
37 Counter execute_total = 0;
38 /// Total number of replies
39 Counter reply_total = 0;
40 /// Number of portal bind operations
42 /// Error during query execution
44 /// Timeout while executing query
45 Counter execute_timeout = 0;
46 /// Duplicate prepared statements
47 /// This is not a hard error, the prepared statements are quite reusable due
48 /// to pretty uniqueness of names. Nevertheless we would like to see them to
49 /// diagnose certain kinds of problems
51
52 // TODO pick reasonable resolution for transaction
53 // execution times
54 /// Transaction overall execution time distribution
55 PercentileAccumulator total_percentile;
56 /// Transaction aggregated query execution time distribution
57 PercentileAccumulator busy_percentile;
58 /// Transaction wait for pool time (difference between trx_start_time and
59 /// work_start_time)
60 PercentileAccumulator wait_start_percentile;
61 /// Transaction wait for pool time (difference between last_execute_finish and
62 /// trx_end_time)
63 PercentileAccumulator wait_end_percentile;
64 /// Return to pool percentile (difference between trx_end_time and time the
65 /// connection has been returned to the pool)
66 PercentileAccumulator return_to_pool_percentile;
67};
68
69/// @brief Template connection statistics storage
70template <typename Counter, typename MmaAccumulator>
72 /// Number of connections opened
73 Counter open_total = 0;
74 /// Number of connections dropped
75 Counter drop_total = 0;
76 /// Number of active connections
77 Counter active = 0;
78 /// Number of connections in use
79 Counter used = 0;
80 /// Number of maximum allowed connections
81 Counter maximum = 0;
82 /// Number of waiting requests
83 Counter waiting = 0;
84 /// Error during connection
85 Counter error_total = 0;
86 /// Connection timeouts (timeouts while connecting)
87 Counter error_timeout = 0;
88 /// Number of maximum allowed waiting requests
89 Counter max_queue_size = 0;
90
91 /// Prepared statements count min-max-avg
92 MmaAccumulator prepared_statements;
93};
94
95/// @brief Template instance topology statistics storage
96template <typename MmaAccumulator>
98 /// Roundtrip time min-max-avg
99 MmaAccumulator roundtrip_time;
100 /// Replication lag min-max-avg
101 MmaAccumulator replication_lag;
102};
103
104/// @brief Template instance statistics storage
105template <typename Counter, typename PercentileAccumulator,
106 typename MmaAccumulator>
108 /// Connection statistics
109 ConnectionStatistics<Counter, MmaAccumulator> connection;
110 /// Transaction statistics
111 TransactionStatistics<Counter, PercentileAccumulator> transaction;
112 /// Topology statistics
114 /// Error caused by pool exhaustion
116 /// Error caused by queue size overflow
117 Counter queue_size_errors = 0;
118 /// Connect time percentile
119 PercentileAccumulator connection_percentile;
120 /// Acquire connection percentile
121 PercentileAccumulator acquire_percentile;
122 /// Congestion control statistics
126};
127
128using RateCounter = USERVER_NAMESPACE::utils::statistics::RateCounter;
129using Percentile = USERVER_NAMESPACE::utils::statistics::Percentile<2048>;
130using MinMaxAvg = USERVER_NAMESPACE::utils::statistics::MinMaxAvg<uint32_t>;
132 USERVER_NAMESPACE::utils::statistics::RelaxedCounter<uint32_t>,
133 USERVER_NAMESPACE::utils::statistics::RecentPeriod<
135 USERVER_NAMESPACE::utils::statistics::RecentPeriod<
137
138struct StatementStatistics final {
139 Percentile timings{};
140 RateCounter executed{};
141 RateCounter errors{};
142
143 void Add(const StatementStatistics& other) {
144 timings.Add(other.timings);
145 executed.Add(other.executed.Load());
146 errors.Add(other.errors.Load());
147 }
148};
149
152
154 InstanceStatisticsNonatomic() = default;
155
156 template <typename Statistics>
157 InstanceStatisticsNonatomic(const Statistics& stats) {
158 *this = stats;
159 }
160 InstanceStatisticsNonatomic(InstanceStatisticsNonatomic&&) = default;
162 default;
163
165 const InstanceStatistics& stats,
166 const decltype(InstanceStatistics::topology)& topology_stats) {
167 connection.open_total = stats.connection.open_total;
168 connection.drop_total = stats.connection.drop_total;
169 connection.active = stats.connection.active;
170 connection.used = stats.connection.used;
171 connection.maximum = stats.connection.maximum;
172 connection.waiting = stats.connection.waiting;
173 connection.error_total = stats.connection.error_total;
174 connection.error_timeout = stats.connection.error_timeout;
175 connection.prepared_statements =
176 stats.connection.prepared_statements.GetStatsForPeriod();
177 connection.max_queue_size = stats.connection.max_queue_size;
178
179 transaction.total = stats.transaction.total;
180 transaction.commit_total = stats.transaction.commit_total;
181 transaction.rollback_total = stats.transaction.rollback_total;
182 transaction.out_of_trx_total = stats.transaction.out_of_trx_total;
183 transaction.parse_total = stats.transaction.parse_total;
184 transaction.execute_total = stats.transaction.execute_total;
185 transaction.reply_total = stats.transaction.reply_total;
186 transaction.portal_bind_total = stats.transaction.portal_bind_total;
187 transaction.error_execute_total = stats.transaction.error_execute_total;
188 transaction.execute_timeout = stats.transaction.execute_timeout;
189 transaction.duplicate_prepared_statements =
190 stats.transaction.duplicate_prepared_statements;
191 transaction.total_percentile =
192 stats.transaction.total_percentile.GetStatsForPeriod();
193 transaction.busy_percentile =
194 stats.transaction.busy_percentile.GetStatsForPeriod();
195 transaction.wait_start_percentile =
196 stats.transaction.wait_start_percentile.GetStatsForPeriod();
197 transaction.wait_end_percentile =
198 stats.transaction.wait_end_percentile.GetStatsForPeriod();
199 transaction.return_to_pool_percentile =
200 stats.transaction.return_to_pool_percentile.GetStatsForPeriod();
201
202 topology.roundtrip_time = topology_stats.roundtrip_time.GetStatsForPeriod();
203 topology.replication_lag =
204 topology_stats.replication_lag.GetStatsForPeriod();
205
206 pool_exhaust_errors = stats.pool_exhaust_errors;
207 queue_size_errors = stats.queue_size_errors;
208 connection_percentile = stats.connection_percentile.GetStatsForPeriod();
209 acquire_percentile = stats.acquire_percentile.GetStatsForPeriod();
210
211 return *this;
212 }
213
215 const std::unordered_map<std::string, StatementStatistics>& stats) {
216 for (const auto& [statement_name, statement_stats] : stats) {
217 const auto [it, inserted] =
218 per_statement_stats.try_emplace(statement_name, statement_stats);
219 if (!inserted) {
220 it->second.Add(statement_stats);
221 }
222 }
223
224 return *this;
225 }
226
227 std::unordered_map<std::string, StatementStatistics> per_statement_stats;
228};
229
230/// @brief Instance statistics with description
232 /// host[:port] of an instance
233 std::string host_port;
234 /// Statistics of an instance
236};
237
238/// @brief Cluster statistics storage
240 /// Master instance statistics
242 /// Sync slave instance statistics
244 /// Slave instances statistics
246 /// Unknown/unreachable instances statistics
248};
249
250// InstanceStatisticsNonatomic values support for utils::statistics::Writer
251void DumpMetric(USERVER_NAMESPACE::utils::statistics::Writer& writer,
252 const InstanceStatisticsNonatomic& stats);
253
254/// @brief InstanceStatsDescriptor values support for utils::statistics::Writer
255void DumpMetric(USERVER_NAMESPACE::utils::statistics::Writer& writer,
256 const InstanceStatsDescriptor& value);
257
258/// @brief ClusterStatistics values support for utils::statistics::Writer
259void DumpMetric(USERVER_NAMESPACE::utils::statistics::Writer& writer,
260 const ClusterStatistics& value);
261
263
264} // namespace storages::postgres
265
266USERVER_NAMESPACE_END