]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/monitoring/statistics.cc
build: use dgit for download target
[ceph.git] / ceph / src / rocksdb / monitoring / statistics.cc
CommitLineData
7c673cae 1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
11fdf7f2
TL
2// This source code is licensed under both the GPLv2 (found in the
3// COPYING file in the root directory) and Apache 2.0 License
4// (found in the LICENSE.Apache file in the root directory).
7c673cae
FG
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
11fdf7f2
TL
24StatisticsImpl::StatisticsImpl(std::shared_ptr<Statistics> stats,
25 bool enable_internal_stats)
26 : stats_(std::move(stats)), enable_internal_stats_(enable_internal_stats) {}
7c673cae
FG
27
28StatisticsImpl::~StatisticsImpl() {}
29
30uint64_t StatisticsImpl::getTickerCount(uint32_t tickerType) const {
31 MutexLock lock(&aggregate_lock_);
32 return getTickerCountLocked(tickerType);
33}
34
35uint64_t StatisticsImpl::getTickerCountLocked(uint32_t tickerType) const {
36 assert(
37 enable_internal_stats_ ?
38 tickerType < INTERNAL_TICKER_ENUM_MAX :
39 tickerType < TICKER_ENUM_MAX);
11fdf7f2
TL
40 uint64_t res = 0;
41 for (size_t core_idx = 0; core_idx < per_core_stats_.Size(); ++core_idx) {
42 res += per_core_stats_.AccessAtCore(core_idx)->tickers_[tickerType];
7c673cae 43 }
11fdf7f2 44 return res;
7c673cae
FG
45}
46
47void StatisticsImpl::histogramData(uint32_t histogramType,
48 HistogramData* const data) const {
49 MutexLock lock(&aggregate_lock_);
11fdf7f2 50 getHistogramImplLocked(histogramType)->Data(data);
7c673cae
FG
51}
52
11fdf7f2
TL
53std::unique_ptr<HistogramImpl> StatisticsImpl::getHistogramImplLocked(
54 uint32_t histogramType) const {
7c673cae
FG
55 assert(
56 enable_internal_stats_ ?
57 histogramType < INTERNAL_HISTOGRAM_ENUM_MAX :
58 histogramType < HISTOGRAM_ENUM_MAX);
11fdf7f2
TL
59 std::unique_ptr<HistogramImpl> res_hist(new HistogramImpl());
60 for (size_t core_idx = 0; core_idx < per_core_stats_.Size(); ++core_idx) {
61 res_hist->Merge(
62 per_core_stats_.AccessAtCore(core_idx)->histograms_[histogramType]);
63 }
64 return res_hist;
7c673cae
FG
65}
66
67std::string StatisticsImpl::getHistogramString(uint32_t histogramType) const {
68 MutexLock lock(&aggregate_lock_);
11fdf7f2 69 return getHistogramImplLocked(histogramType)->ToString();
7c673cae
FG
70}
71
72void StatisticsImpl::setTickerCount(uint32_t tickerType, uint64_t count) {
73 {
74 MutexLock lock(&aggregate_lock_);
75 setTickerCountLocked(tickerType, count);
76 }
77 if (stats_ && tickerType < TICKER_ENUM_MAX) {
78 stats_->setTickerCount(tickerType, count);
79 }
80}
81
82void StatisticsImpl::setTickerCountLocked(uint32_t tickerType, uint64_t count) {
83 assert(enable_internal_stats_ ? tickerType < INTERNAL_TICKER_ENUM_MAX
84 : tickerType < TICKER_ENUM_MAX);
11fdf7f2
TL
85 for (size_t core_idx = 0; core_idx < per_core_stats_.Size(); ++core_idx) {
86 if (core_idx == 0) {
87 per_core_stats_.AccessAtCore(core_idx)->tickers_[tickerType] = count;
88 } else {
89 per_core_stats_.AccessAtCore(core_idx)->tickers_[tickerType] = 0;
90 }
7c673cae
FG
91 }
92}
93
94uint64_t StatisticsImpl::getAndResetTickerCount(uint32_t tickerType) {
95 uint64_t sum = 0;
96 {
97 MutexLock lock(&aggregate_lock_);
98 assert(enable_internal_stats_ ? tickerType < INTERNAL_TICKER_ENUM_MAX
99 : tickerType < TICKER_ENUM_MAX);
11fdf7f2
TL
100 for (size_t core_idx = 0; core_idx < per_core_stats_.Size(); ++core_idx) {
101 sum +=
102 per_core_stats_.AccessAtCore(core_idx)->tickers_[tickerType].exchange(
103 0, std::memory_order_relaxed);
7c673cae
FG
104 }
105 }
106 if (stats_ && tickerType < TICKER_ENUM_MAX) {
107 stats_->setTickerCount(tickerType, 0);
108 }
109 return sum;
110}
111
112void StatisticsImpl::recordTick(uint32_t tickerType, uint64_t count) {
113 assert(
114 enable_internal_stats_ ?
115 tickerType < INTERNAL_TICKER_ENUM_MAX :
116 tickerType < TICKER_ENUM_MAX);
11fdf7f2
TL
117 per_core_stats_.Access()->tickers_[tickerType].fetch_add(
118 count, std::memory_order_relaxed);
7c673cae
FG
119 if (stats_ && tickerType < TICKER_ENUM_MAX) {
120 stats_->recordTick(tickerType, count);
121 }
122}
123
124void StatisticsImpl::measureTime(uint32_t histogramType, uint64_t value) {
125 assert(
126 enable_internal_stats_ ?
127 histogramType < INTERNAL_HISTOGRAM_ENUM_MAX :
128 histogramType < HISTOGRAM_ENUM_MAX);
11fdf7f2 129 per_core_stats_.Access()->histograms_[histogramType].Add(value);
7c673cae
FG
130 if (stats_ && histogramType < HISTOGRAM_ENUM_MAX) {
131 stats_->measureTime(histogramType, value);
132 }
133}
134
135Status StatisticsImpl::Reset() {
136 MutexLock lock(&aggregate_lock_);
137 for (uint32_t i = 0; i < TICKER_ENUM_MAX; ++i) {
138 setTickerCountLocked(i, 0);
139 }
140 for (uint32_t i = 0; i < HISTOGRAM_ENUM_MAX; ++i) {
11fdf7f2
TL
141 for (size_t core_idx = 0; core_idx < per_core_stats_.Size(); ++core_idx) {
142 per_core_stats_.AccessAtCore(core_idx)->histograms_[i].Clear();
143 }
7c673cae
FG
144 }
145 return Status::OK();
146}
147
148namespace {
149
150// a buffer size used for temp string buffers
151const int kTmpStrBufferSize = 200;
152
153} // namespace
154
155std::string StatisticsImpl::ToString() const {
156 MutexLock lock(&aggregate_lock_);
157 std::string res;
158 res.reserve(20000);
159 for (const auto& t : TickersNameMap) {
160 if (t.first < TICKER_ENUM_MAX || enable_internal_stats_) {
161 char buffer[kTmpStrBufferSize];
162 snprintf(buffer, kTmpStrBufferSize, "%s COUNT : %" PRIu64 "\n",
163 t.second.c_str(), getTickerCountLocked(t.first));
164 res.append(buffer);
165 }
166 }
167 for (const auto& h : HistogramsNameMap) {
168 if (h.first < HISTOGRAM_ENUM_MAX || enable_internal_stats_) {
169 char buffer[kTmpStrBufferSize];
170 HistogramData hData;
11fdf7f2
TL
171 getHistogramImplLocked(h.first)->Data(&hData);
172 // don't handle failures - buffer should always be big enough and arguments
173 // should be provided correctly
174 int ret = snprintf(
7c673cae 175 buffer, kTmpStrBufferSize,
11fdf7f2
TL
176 "%s P50 : %f P95 : %f P99 : %f P100 : %f COUNT : %" PRIu64 " SUM : %"
177 PRIu64 "\n", h.second.c_str(), hData.median, hData.percentile95,
178 hData.percentile99, hData.max, hData.count, hData.sum);
179 if (ret < 0 || ret >= kTmpStrBufferSize) {
180 assert(false);
181 continue;
182 }
7c673cae
FG
183 res.append(buffer);
184 }
185 }
186 res.shrink_to_fit();
187 return res;
188}
189
190bool StatisticsImpl::HistEnabledForType(uint32_t type) const {
191 if (LIKELY(!enable_internal_stats_)) {
192 return type < HISTOGRAM_ENUM_MAX;
193 }
194 return true;
195}
196
197} // namespace rocksdb