userver: userver/storages/postgres/statistics.hpp Source File
Loading...
Searching...
No Matches
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<
133 USERVER_NAMESPACE::utils::statistics::RecentPeriod<
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