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/recentperiod.hpp>
15#include <userver/utils/statistics/relaxed_counter.hpp>
16#include <userver/utils/statistics/writer.hpp>
17
18USERVER_NAMESPACE_BEGIN
19
20namespace storages::postgres {
21
22/// @brief Template transaction statistics storage
23template <typename Counter, typename PercentileAccumulator>
25 /// Number of transactions started
26 Counter total = 0;
27 /// Number of transactions committed
28 Counter commit_total = 0;
29 /// Number of transactions rolled back
30 Counter rollback_total = 0;
31 /// Number of out-of-transaction executions
32 Counter out_of_trx_total = 0;
33 /// Number of parsed queries
34 Counter parse_total = 0;
35 /// Number of query executions
36 Counter execute_total = 0;
37 /// Total number of replies
38 Counter reply_total = 0;
39 /// Number of portal bind operations
41 /// Error during query execution
43 /// Timeout while executing query
44 Counter execute_timeout = 0;
45 /// Duplicate prepared statements
46 /// This is not a hard error, the prepared statements are quite reusable due
47 /// to pretty uniqueness of names. Nevertheless we would like to see them to
48 /// diagnose certain kinds of problems
50
51 // TODO pick reasonable resolution for transaction
52 // execution times
53 /// Transaction overall execution time distribution
54 PercentileAccumulator total_percentile;
55 /// Transaction aggregated query execution time distribution
56 PercentileAccumulator busy_percentile;
57 /// Transaction wait for pool time (difference between trx_start_time and
58 /// work_start_time)
59 PercentileAccumulator wait_start_percentile;
60 /// Transaction wait for pool time (difference between last_execute_finish and
61 /// trx_end_time)
62 PercentileAccumulator wait_end_percentile;
63 /// Return to pool percentile (difference between trx_end_time and time the
64 /// connection has been returned to the pool)
65 PercentileAccumulator return_to_pool_percentile;
66};
67
68/// @brief Template connection statistics storage
69template <typename Counter, typename MmaAccumulator>
71 /// Number of connections opened
72 Counter open_total = 0;
73 /// Number of connections dropped
74 Counter drop_total = 0;
75 /// Number of active connections
76 Counter active = 0;
77 /// Number of connections in use
78 Counter used = 0;
79 /// Number of maximum allowed connections
80 Counter maximum = 0;
81 /// Number of waiting requests
82 Counter waiting = 0;
83 /// Error during connection
84 Counter error_total = 0;
85 /// Connection timeouts (timeouts while connecting)
86 Counter error_timeout = 0;
87 /// Number of maximum allowed waiting requests
88 Counter max_queue_size = 0;
89
90 /// Prepared statements count min-max-avg
91 MmaAccumulator prepared_statements;
92};
93
94/// @brief Template instance topology statistics storage
95template <typename MmaAccumulator>
97 /// Roundtrip time min-max-avg
98 MmaAccumulator roundtrip_time;
99 /// Replication lag min-max-avg
100 MmaAccumulator replication_lag;
101};
102
103/// @brief Template instance statistics storage
104template <typename Counter, typename PercentileAccumulator,
105 typename MmaAccumulator>
107 /// Connection statistics
108 ConnectionStatistics<Counter, MmaAccumulator> connection;
109 /// Transaction statistics
110 TransactionStatistics<Counter, PercentileAccumulator> transaction;
111 /// Topology statistics
113 /// Error caused by pool exhaustion
115 /// Error caused by queue size overflow
116 Counter queue_size_errors = 0;
117 /// Connect time percentile
118 PercentileAccumulator connection_percentile;
119 /// Acquire connection percentile
120 PercentileAccumulator acquire_percentile;
121 /// Congestion control statistics
125};
126
127using Percentile = USERVER_NAMESPACE::utils::statistics::Percentile<2048>;
128using MinMaxAvg = USERVER_NAMESPACE::utils::statistics::MinMaxAvg<uint32_t>;
130 USERVER_NAMESPACE::utils::statistics::RelaxedCounter<uint32_t>,
131 USERVER_NAMESPACE::utils::statistics::RecentPeriod<Percentile, Percentile,
133 USERVER_NAMESPACE::utils::statistics::RecentPeriod<MinMaxAvg, MinMaxAvg,
135
138
140 InstanceStatisticsNonatomic() = default;
141
142 template <typename Statistics>
143 InstanceStatisticsNonatomic(const Statistics& stats) {
144 *this = stats;
145 }
146 InstanceStatisticsNonatomic(InstanceStatisticsNonatomic&&) = default;
148 default;
149
151 const InstanceStatistics& stats,
152 const decltype(InstanceStatistics::topology)& topology_stats) {
153 connection.open_total = stats.connection.open_total;
154 connection.drop_total = stats.connection.drop_total;
155 connection.active = stats.connection.active;
156 connection.used = stats.connection.used;
157 connection.maximum = stats.connection.maximum;
158 connection.waiting = stats.connection.waiting;
159 connection.error_total = stats.connection.error_total;
160 connection.error_timeout = stats.connection.error_timeout;
161 connection.prepared_statements =
162 stats.connection.prepared_statements.GetStatsForPeriod();
163 connection.max_queue_size = stats.connection.max_queue_size;
164
165 transaction.total = stats.transaction.total;
166 transaction.commit_total = stats.transaction.commit_total;
167 transaction.rollback_total = stats.transaction.rollback_total;
168 transaction.out_of_trx_total = stats.transaction.out_of_trx_total;
169 transaction.parse_total = stats.transaction.parse_total;
170 transaction.execute_total = stats.transaction.execute_total;
171 transaction.reply_total = stats.transaction.reply_total;
172 transaction.portal_bind_total = stats.transaction.portal_bind_total;
173 transaction.error_execute_total = stats.transaction.error_execute_total;
174 transaction.execute_timeout = stats.transaction.execute_timeout;
175 transaction.duplicate_prepared_statements =
176 stats.transaction.duplicate_prepared_statements;
177 transaction.total_percentile =
178 stats.transaction.total_percentile.GetStatsForPeriod();
179 transaction.busy_percentile =
180 stats.transaction.busy_percentile.GetStatsForPeriod();
181 transaction.wait_start_percentile =
182 stats.transaction.wait_start_percentile.GetStatsForPeriod();
183 transaction.wait_end_percentile =
184 stats.transaction.wait_end_percentile.GetStatsForPeriod();
185 transaction.return_to_pool_percentile =
186 stats.transaction.return_to_pool_percentile.GetStatsForPeriod();
187
188 topology.roundtrip_time = topology_stats.roundtrip_time.GetStatsForPeriod();
189 topology.replication_lag =
190 topology_stats.replication_lag.GetStatsForPeriod();
191
192 pool_exhaust_errors = stats.pool_exhaust_errors;
193 queue_size_errors = stats.queue_size_errors;
194 connection_percentile = stats.connection_percentile.GetStatsForPeriod();
195 acquire_percentile = stats.acquire_percentile.GetStatsForPeriod();
196
197 return *this;
198 }
199
201 const std::unordered_map<std::string, Percentile>& timings) {
202 for (const auto& [name, percentile] : timings) {
203 const auto [it, inserted] =
204 statement_timings.try_emplace(name, percentile);
205 if (!inserted) it->second.Add(percentile);
206 }
207
208 return *this;
209 }
210
211 std::unordered_map<std::string, Percentile> statement_timings;
212};
213
214/// @brief Instance statistics with description
216 /// host[:port] of an instance
217 std::string host_port;
218 /// Statistics of an instance
220};
221
222/// @brief Cluster statistics storage
224 /// Master instance statistics
226 /// Sync slave instance statistics
228 /// Slave instances statistics
230 /// Unknown/unreachable instances statistics
232};
233
234// InstanceStatisticsNonatomic values support for utils::statistics::Writer
235void DumpMetric(USERVER_NAMESPACE::utils::statistics::Writer& writer,
236 const InstanceStatisticsNonatomic& stats);
237
238/// @brief InstanceStatsDescriptor values support for utils::statistics::Writer
239void DumpMetric(USERVER_NAMESPACE::utils::statistics::Writer& writer,
240 const InstanceStatsDescriptor& value);
241
242/// @brief ClusterStatistics values support for utils::statistics::Writer
243void DumpMetric(USERVER_NAMESPACE::utils::statistics::Writer& writer,
244 const ClusterStatistics& value);
245
247
248} // namespace storages::postgres
249
250USERVER_NAMESPACE_END