]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/monitoring/statistics.cc
bump version to 12.2.12-pve1
[ceph.git] / ceph / src / rocksdb / monitoring / statistics.cc
CommitLineData
7c673cae
FG
1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2// This source code is licensed under the BSD-style license found in the
3// LICENSE file in the root directory of this source tree. An additional grant
4// of patent rights can be found in the PATENTS file in the same directory.
5//
6#include "monitoring/statistics.h"
7
8#ifndef __STDC_FORMAT_MACROS
9#define __STDC_FORMAT_MACROS
10#endif
11
12#include <inttypes.h>
13#include "rocksdb/statistics.h"
14#include "port/likely.h"
15#include <algorithm>
16#include <cstdio>
17
18namespace rocksdb {
19
20std::shared_ptr<Statistics> CreateDBStatistics() {
21 return std::make_shared<StatisticsImpl>(nullptr, false);
22}
23
24StatisticsImpl::StatisticsImpl(
25 std::shared_ptr<Statistics> stats,
26 bool enable_internal_stats)
27 : stats_shared_(stats),
28 stats_(stats.get()),
29 enable_internal_stats_(enable_internal_stats) {
30}
31
32StatisticsImpl::~StatisticsImpl() {}
33
34uint64_t StatisticsImpl::getTickerCount(uint32_t tickerType) const {
35 MutexLock lock(&aggregate_lock_);
36 return getTickerCountLocked(tickerType);
37}
38
39uint64_t StatisticsImpl::getTickerCountLocked(uint32_t tickerType) const {
40 assert(
41 enable_internal_stats_ ?
42 tickerType < INTERNAL_TICKER_ENUM_MAX :
43 tickerType < TICKER_ENUM_MAX);
44 uint64_t thread_local_sum = 0;
45 tickers_[tickerType].thread_value->Fold(
46 [](void* curr_ptr, void* res) {
47 auto* sum_ptr = static_cast<uint64_t*>(res);
48 *sum_ptr += static_cast<std::atomic_uint_fast64_t*>(curr_ptr)->load(
49 std::memory_order_relaxed);
50 },
51 &thread_local_sum);
52 return thread_local_sum +
53 tickers_[tickerType].merged_sum.load(std::memory_order_relaxed);
54}
55
56std::unique_ptr<HistogramImpl>
57StatisticsImpl::HistogramInfo::getMergedHistogram() const {
58 std::unique_ptr<HistogramImpl> res_hist(new HistogramImpl());
59 {
60 MutexLock lock(&merge_lock);
61 res_hist->Merge(merged_hist);
62 }
63 thread_value->Fold(
64 [](void* curr_ptr, void* res) {
65 auto tmp_res_hist = static_cast<HistogramImpl*>(res);
66 auto curr_hist = static_cast<HistogramImpl*>(curr_ptr);
67 tmp_res_hist->Merge(*curr_hist);
68 },
69 res_hist.get());
70 return res_hist;
71}
72
73void StatisticsImpl::histogramData(uint32_t histogramType,
74 HistogramData* const data) const {
75 MutexLock lock(&aggregate_lock_);
76 histogramDataLocked(histogramType, data);
77}
78
79void StatisticsImpl::histogramDataLocked(uint32_t histogramType,
80 HistogramData* const data) const {
81 assert(
82 enable_internal_stats_ ?
83 histogramType < INTERNAL_HISTOGRAM_ENUM_MAX :
84 histogramType < HISTOGRAM_ENUM_MAX);
85 histograms_[histogramType].getMergedHistogram()->Data(data);
86}
87
88std::string StatisticsImpl::getHistogramString(uint32_t histogramType) const {
89 MutexLock lock(&aggregate_lock_);
90 assert(enable_internal_stats_ ? histogramType < INTERNAL_HISTOGRAM_ENUM_MAX
91 : histogramType < HISTOGRAM_ENUM_MAX);
92 return histograms_[histogramType].getMergedHistogram()->ToString();
93}
94
95StatisticsImpl::ThreadTickerInfo* StatisticsImpl::getThreadTickerInfo(
96 uint32_t tickerType) {
97 auto info_ptr =
98 static_cast<ThreadTickerInfo*>(tickers_[tickerType].thread_value->Get());
99 if (info_ptr == nullptr) {
100 info_ptr =
101 new ThreadTickerInfo(0 /* value */, &tickers_[tickerType].merged_sum);
102 tickers_[tickerType].thread_value->Reset(info_ptr);
103 }
104 return info_ptr;
105}
106
107StatisticsImpl::ThreadHistogramInfo* StatisticsImpl::getThreadHistogramInfo(
108 uint32_t histogram_type) {
109 auto info_ptr = static_cast<ThreadHistogramInfo*>(
110 histograms_[histogram_type].thread_value->Get());
111 if (info_ptr == nullptr) {
112 info_ptr = new ThreadHistogramInfo(&histograms_[histogram_type].merged_hist,
113 &histograms_[histogram_type].merge_lock);
114 histograms_[histogram_type].thread_value->Reset(info_ptr);
115 }
116 return info_ptr;
117}
118
119void StatisticsImpl::setTickerCount(uint32_t tickerType, uint64_t count) {
120 {
121 MutexLock lock(&aggregate_lock_);
122 setTickerCountLocked(tickerType, count);
123 }
124 if (stats_ && tickerType < TICKER_ENUM_MAX) {
125 stats_->setTickerCount(tickerType, count);
126 }
127}
128
129void StatisticsImpl::setTickerCountLocked(uint32_t tickerType, uint64_t count) {
130 assert(enable_internal_stats_ ? tickerType < INTERNAL_TICKER_ENUM_MAX
131 : tickerType < TICKER_ENUM_MAX);
132 if (tickerType < TICKER_ENUM_MAX || enable_internal_stats_) {
133 tickers_[tickerType].thread_value->Fold(
134 [](void* curr_ptr, void* res) {
135 static_cast<std::atomic<uint64_t>*>(curr_ptr)->store(
136 0, std::memory_order_relaxed);
137 },
138 nullptr /* res */);
139 tickers_[tickerType].merged_sum.store(count, std::memory_order_relaxed);
140 }
141}
142
143uint64_t StatisticsImpl::getAndResetTickerCount(uint32_t tickerType) {
144 uint64_t sum = 0;
145 {
146 MutexLock lock(&aggregate_lock_);
147 assert(enable_internal_stats_ ? tickerType < INTERNAL_TICKER_ENUM_MAX
148 : tickerType < TICKER_ENUM_MAX);
149 if (tickerType < TICKER_ENUM_MAX || enable_internal_stats_) {
150 tickers_[tickerType].thread_value->Fold(
151 [](void* curr_ptr, void* res) {
152 auto* sum_ptr = static_cast<uint64_t*>(res);
153 *sum_ptr += static_cast<std::atomic<uint64_t>*>(curr_ptr)->exchange(
154 0, std::memory_order_relaxed);
155 },
156 &sum);
157 sum += tickers_[tickerType].merged_sum.exchange(
158 0, std::memory_order_relaxed);
159 }
160 }
161 if (stats_ && tickerType < TICKER_ENUM_MAX) {
162 stats_->setTickerCount(tickerType, 0);
163 }
164 return sum;
165}
166
167void StatisticsImpl::recordTick(uint32_t tickerType, uint64_t count) {
168 assert(
169 enable_internal_stats_ ?
170 tickerType < INTERNAL_TICKER_ENUM_MAX :
171 tickerType < TICKER_ENUM_MAX);
172 if (tickerType < TICKER_ENUM_MAX || enable_internal_stats_) {
173 auto info_ptr = getThreadTickerInfo(tickerType);
174 info_ptr->value.fetch_add(count, std::memory_order_relaxed);
175 }
176 if (stats_ && tickerType < TICKER_ENUM_MAX) {
177 stats_->recordTick(tickerType, count);
178 }
179}
180
181void StatisticsImpl::measureTime(uint32_t histogramType, uint64_t value) {
182 assert(
183 enable_internal_stats_ ?
184 histogramType < INTERNAL_HISTOGRAM_ENUM_MAX :
185 histogramType < HISTOGRAM_ENUM_MAX);
186 if (histogramType < HISTOGRAM_ENUM_MAX || enable_internal_stats_) {
187 getThreadHistogramInfo(histogramType)->value.Add(value);
188 }
189 if (stats_ && histogramType < HISTOGRAM_ENUM_MAX) {
190 stats_->measureTime(histogramType, value);
191 }
192}
193
194Status StatisticsImpl::Reset() {
195 MutexLock lock(&aggregate_lock_);
196 for (uint32_t i = 0; i < TICKER_ENUM_MAX; ++i) {
197 setTickerCountLocked(i, 0);
198 }
199 for (uint32_t i = 0; i < HISTOGRAM_ENUM_MAX; ++i) {
200 histograms_[i].thread_value->Fold(
201 [](void* curr_ptr, void* res) {
202 static_cast<HistogramImpl*>(curr_ptr)->Clear();
203 },
204 nullptr /* res */);
205 }
206 return Status::OK();
207}
208
209namespace {
210
211// a buffer size used for temp string buffers
212const int kTmpStrBufferSize = 200;
213
214} // namespace
215
216std::string StatisticsImpl::ToString() const {
217 MutexLock lock(&aggregate_lock_);
218 std::string res;
219 res.reserve(20000);
220 for (const auto& t : TickersNameMap) {
221 if (t.first < TICKER_ENUM_MAX || enable_internal_stats_) {
222 char buffer[kTmpStrBufferSize];
223 snprintf(buffer, kTmpStrBufferSize, "%s COUNT : %" PRIu64 "\n",
224 t.second.c_str(), getTickerCountLocked(t.first));
225 res.append(buffer);
226 }
227 }
228 for (const auto& h : HistogramsNameMap) {
229 if (h.first < HISTOGRAM_ENUM_MAX || enable_internal_stats_) {
230 char buffer[kTmpStrBufferSize];
231 HistogramData hData;
232 histogramDataLocked(h.first, &hData);
233 snprintf(
234 buffer, kTmpStrBufferSize,
235 "%s statistics Percentiles :=> 50 : %f 95 : %f 99 : %f 100 : %f\n",
236 h.second.c_str(), hData.median, hData.percentile95,
237 hData.percentile99, hData.max);
238 res.append(buffer);
239 }
240 }
241 res.shrink_to_fit();
242 return res;
243}
244
245bool StatisticsImpl::HistEnabledForType(uint32_t type) const {
246 if (LIKELY(!enable_internal_stats_)) {
247 return type < HISTOGRAM_ENUM_MAX;
248 }
249 return true;
250}
251
252} // namespace rocksdb