]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/statbag.cc
Make the constructors taking a pthread_rwlock_t * private.
[thirdparty/pdns.git] / pdns / statbag.cc
CommitLineData
12c86877 1/*
6edbf68a
PL
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
870a0fe4
AT
22#ifdef HAVE_CONFIG_H
23#include "config.h"
24#endif
896e5153 25#include "utility.hh"
12c86877 26#include "statbag.hh"
5c409fa2 27#include "pdnsexception.hh"
12c86877
BH
28#include <iostream>
29#include <sstream>
30#include <algorithm>
31#include "arguments.hh"
32#include "lock.hh"
4eb26e0f 33#include "iputils.hh"
fa8fd4d2 34
12c86877 35
10f4eea8 36#include "namespaces.hh"
12c86877
BH
37
38StatBag::StatBag()
39{
40 d_doRings=false;
12c86877
BH
41}
42
12c86877
BH
43void StatBag::exists(const string &key)
44{
e903706d 45 if(!d_keyDescrips.count(key))
12c86877 46 {
3f81d239 47 throw PDNSException("Trying to deposit into unknown StatBag key '"+key+"'");
12c86877
BH
48 }
49}
50
f3245c8c 51string StatBag::directory()
12c86877
BH
52{
53 string dir;
54 ostringstream o;
1566533a 55
cb167afd 56 for(const auto& i: d_stats) {
f3245c8c 57 if (d_blacklist.find(i.first) != d_blacklist.end())
28c3cc11 58 continue;
cb167afd
CHB
59 o<<i.first<<"="<<*(i.second)<<",";
60 }
1566533a 61
e903706d 62
ef7cd021 63 for(const funcstats_t::value_type& val : d_funcstats) {
f3245c8c 64 if (d_blacklist.find(val.first) != d_blacklist.end())
28c3cc11 65 continue;
e903706d 66 o << val.first<<"="<<val.second(val.first)<<",";
67 }
12c86877
BH
68 dir=o.str();
69 return dir;
70}
71
72
73vector<string>StatBag::getEntries()
74{
75 vector<string> ret;
1566533a 76
cb167afd 77 for(const auto& i: d_stats) {
f3245c8c
OM
78 if (d_blacklist.find(i.first) != d_blacklist.end())
79 continue;
80 ret.push_back(i.first);
cb167afd 81 }
12c86877 82
ef7cd021 83 for(const funcstats_t::value_type& val : d_funcstats) {
f3245c8c
OM
84 if (d_blacklist.find(val.first) != d_blacklist.end())
85 continue;
e903706d 86 ret.push_back(val.first);
87 }
88
1566533a 89
12c86877
BH
90 return ret;
91
92}
93
94string StatBag::getDescrip(const string &item)
95{
1566533a 96 exists(item);
97 return d_keyDescrips[item];
12c86877
BH
98}
99
100void StatBag::declare(const string &key, const string &descrip)
101{
c2826d2e
RG
102 auto i=make_unique<AtomicCounter>(0);
103 d_stats[key]=std::move(i);
12c86877 104 d_keyDescrips[key]=descrip;
12c86877
BH
105}
106
e903706d 107void StatBag::declare(const string &key, const string &descrip, StatBag::func_t func)
108{
109
110 d_funcstats[key]=func;
111 d_keyDescrips[key]=descrip;
112}
12c86877
BH
113
114
ac0995bb 115void StatBag::set(const string &key, unsigned long value)
12c86877 116{
12c86877 117 exists(key);
ac0995bb 118 d_stats[key]->store(value);
12c86877
BH
119}
120
ac0995bb 121unsigned long StatBag::read(const string &key)
12c86877 122{
1566533a 123 exists(key);
3b433571 124 funcstats_t::const_iterator iter = d_funcstats.find(key);
125 if(iter != d_funcstats.end())
126 return iter->second(iter->first);
1566533a 127 return *d_stats[key];
12c86877
BH
128}
129
ac0995bb 130unsigned long StatBag::readZero(const string &key)
12c86877 131{
1566533a 132 exists(key);
ac0995bb 133 unsigned long tmp=*d_stats[key];
12c86877 134 d_stats[key]=0;
12c86877
BH
135 return tmp;
136}
137
138
139string StatBag::getValueStr(const string &key)
140{
141 ostringstream o;
142 o<<read(key);
143 return o.str();
144}
145
146string StatBag::getValueStrZero(const string &key)
147{
148 ostringstream o;
149 o<<readZero(key);
150 return o.str();
151}
152
1566533a 153AtomicCounter *StatBag::getPointer(const string &key)
12c86877
BH
154{
155 exists(key);
c2826d2e 156 return d_stats[key].get();
12c86877
BH
157}
158
159StatBag::~StatBag()
160{
12c86877
BH
161}
162
4eb26e0f 163template<typename T, typename Comp>
164StatRing<T,Comp>::StatRing(unsigned int size)
12c86877 165{
4eb26e0f 166 d_items.set_capacity(size);
12c86877
BH
167}
168
f979b818
OM
169template<typename T, typename Comp>
170StatRing<T,Comp>::StatRing(const StatRing<T,Comp> &arg)
171{
172 std::lock_guard<std::mutex> thislock(d_lock);
173 std::lock_guard<std::mutex> arglock(arg.d_lock);
174
175 d_items = arg.d_items;
176 d_help = arg.d_help;
177}
178
4eb26e0f 179template<typename T, typename Comp>
180void StatRing<T,Comp>::account(const T& t)
12c86877 181{
92b91988 182 std::lock_guard<std::mutex> l(d_lock);
4eb26e0f 183 d_items.push_back(t);
184}
12c86877 185
4eb26e0f 186template<typename T, typename Comp>
74e38357 187uint64_t StatRing<T,Comp>::getSize() const
4eb26e0f 188{
92b91988 189 std::lock_guard<std::mutex> l(d_lock);
4eb26e0f 190 return d_items.capacity();
12c86877 191}
975bee12 192
74e38357
RG
193template<typename T, typename Comp>
194uint64_t StatRing<T,Comp>::getEntriesCount() const
195{
196 std::lock_guard<std::mutex> l(d_lock);
197 return d_items.size();
198}
199
4eb26e0f 200template<typename T, typename Comp>
201void StatRing<T,Comp>::resize(unsigned int newsize)
12c86877 202{
92b91988 203 std::lock_guard<std::mutex> l(d_lock);
4eb26e0f 204 d_items.set_capacity(newsize);
12c86877
BH
205}
206
4eb26e0f 207template<typename T, typename Comp>
208void StatRing<T,Comp>::setHelp(const string &str)
12c86877
BH
209{
210 d_help=str;
211}
212
4eb26e0f 213template<typename T, typename Comp>
214string StatRing<T,Comp>::getHelp()
12c86877
BH
215{
216 return d_help;
217}
218
12c86877 219
4eb26e0f 220template<typename T, typename Comp>
221vector<pair<T, unsigned int> >StatRing<T,Comp>::get() const
12c86877 222{
92b91988 223 std::lock_guard<std::mutex> l(d_lock);
4eb26e0f 224 map<T,unsigned int, Comp> res;
225 for(typename boost::circular_buffer<T>::const_iterator i=d_items.begin();i!=d_items.end();++i) {
226 res[*i]++;
12c86877
BH
227 }
228
4eb26e0f 229 vector<pair<T ,unsigned int> > tmp;
230 for(typename map<T, unsigned int>::const_iterator i=res.begin();i!=res.end();++i)
12c86877
BH
231 tmp.push_back(*i);
232
233 sort(tmp.begin(),tmp.end(),popisort);
234
235 return tmp;
236}
237
74e38357
RG
238void StatBag::registerRingStats(const string& name)
239{
240 declare("ring-" + name + "-size", "Number of entries in the " + name + " ring", [this,name](const std::string&) { return static_cast<uint64_t>(getRingEntriesCount(name)); });
241 declare("ring-" + name + "-capacity", "Maximum number of entries in the " + name + " ring", [this,name](const std::string&) { return static_cast<uint64_t>(getRingSize(name)); });
242}
243
12c86877
BH
244void StatBag::declareRing(const string &name, const string &help, unsigned int size)
245{
92b91988 246 d_rings.emplace(name, size);
12c86877 247 d_rings[name].setHelp(help);
74e38357 248 registerRingStats(name);
12c86877
BH
249}
250
4eb26e0f 251void StatBag::declareComboRing(const string &name, const string &help, unsigned int size)
12c86877 252{
ef2ea4bf
JS
253 d_comboRings.emplace(name, size);
254 d_comboRings[name].setHelp(help);
74e38357 255 registerRingStats(name);
12c86877
BH
256}
257
f2b2f3ad
PL
258void StatBag::declareDNSNameQTypeRing(const string &name, const string &help, unsigned int size)
259{
92b91988 260 d_dnsnameqtyperings.emplace(name, size);
f2b2f3ad 261 d_dnsnameqtyperings[name].setHelp(help);
74e38357 262 registerRingStats(name);
f2b2f3ad
PL
263}
264
4eb26e0f 265vector<pair<string, unsigned int> > StatBag::getRing(const string &name)
12c86877 266{
f2b2f3ad 267 if(d_rings.count(name)) {
4eb26e0f 268 return d_rings[name].get();
f2b2f3ad
PL
269 }
270 vector<pair<string, unsigned int> > ret;
271
ef2ea4bf 272 if (d_comboRings.count(name)) {
662d5441 273 typedef pair<SComboAddress, unsigned int> stor_t;
ef2ea4bf 274 vector<stor_t> raw =d_comboRings[name].get();
ef7cd021 275 for(const stor_t& stor : raw) {
662d5441 276 ret.push_back(make_pair(stor.first.ca.toString(), stor.second));
4eb26e0f 277 }
f2b2f3ad
PL
278 } else if(d_dnsnameqtyperings.count(name)) {
279 auto raw = d_dnsnameqtyperings[name].get();
280 for (auto const &e : raw) {
281 ret.push_back(make_pair(std::get<0>(e.first).toLogString() + "/" + std::get<1>(e.first).getName(), e.second));
282 }
12c86877 283 }
f2b2f3ad 284 return ret;
4eb26e0f 285}
286
287template<typename T, typename Comp>
288void StatRing<T,Comp>::reset()
289{
92b91988 290 std::lock_guard<std::mutex> l(d_lock);
4eb26e0f 291 d_items.clear();
12c86877
BH
292}
293
294void StatBag::resetRing(const string &name)
295{
4eb26e0f 296 if(d_rings.count(name))
297 d_rings[name].reset();
ef2ea4bf
JS
298 if(d_comboRings.count(name))
299 d_comboRings[name].reset();
f2b2f3ad
PL
300 if(d_dnsnameqtyperings.count(name))
301 d_dnsnameqtyperings[name].reset();
12c86877
BH
302}
303
bb3c3f50 304void StatBag::resizeRing(const string &name, unsigned int newsize)
12c86877 305{
4eb26e0f 306 if(d_rings.count(name))
307 d_rings[name].resize(newsize);
ef2ea4bf
JS
308 if(d_comboRings.count(name))
309 d_comboRings[name].resize(newsize);
f2b2f3ad
PL
310 if(d_dnsnameqtyperings.count(name))
311 return d_dnsnameqtyperings[name].resize(newsize);
12c86877
BH
312}
313
314
74e38357 315uint64_t StatBag::getRingSize(const string &name)
12c86877 316{
4eb26e0f 317 if(d_rings.count(name))
318 return d_rings[name].getSize();
ef2ea4bf
JS
319 if(d_comboRings.count(name))
320 return d_comboRings[name].getSize();
f2b2f3ad
PL
321 if(d_dnsnameqtyperings.count(name))
322 return d_dnsnameqtyperings[name].getSize();
323 return 0;
12c86877
BH
324}
325
74e38357
RG
326uint64_t StatBag::getRingEntriesCount(const string &name)
327{
328 if(d_rings.count(name))
329 return d_rings[name].getEntriesCount();
ef2ea4bf
JS
330 if(d_comboRings.count(name))
331 return d_comboRings[name].getEntriesCount();
74e38357
RG
332 if(d_dnsnameqtyperings.count(name))
333 return d_dnsnameqtyperings[name].getEntriesCount();
334 return 0;
335}
336
12c86877
BH
337string StatBag::getRingTitle(const string &name)
338{
4eb26e0f 339 if(d_rings.count(name))
340 return d_rings[name].getHelp();
ef2ea4bf
JS
341 if(d_comboRings.count(name))
342 return d_comboRings[name].getHelp();
f2b2f3ad
PL
343 if(d_dnsnameqtyperings.count(name))
344 return d_dnsnameqtyperings[name].getHelp();
345 return "";
12c86877
BH
346}
347
348vector<string>StatBag::listRings()
349{
350 vector<string> ret;
fadd04cc 351 for(auto i=d_rings.begin();i!=d_rings.end();++i)
4eb26e0f 352 ret.push_back(i->first);
ef2ea4bf 353 for(auto i=d_comboRings.begin();i!=d_comboRings.end();++i)
12c86877 354 ret.push_back(i->first);
f2b2f3ad
PL
355 for(const auto &i : d_dnsnameqtyperings)
356 ret.push_back(i.first);
4eb26e0f 357
12c86877
BH
358 return ret;
359}
360
ef1439ff
KM
361bool StatBag::ringExists(const string &name)
362{
ef2ea4bf 363 return d_rings.count(name) || d_comboRings.count(name) || d_dnsnameqtyperings.count(name);
ef1439ff 364}
4eb26e0f 365
f3245c8c
OM
366void StatBag::blacklist(const string& str) {
367 d_blacklist.insert(str);
368}
369
fadd04cc 370template class StatRing<std::string, CIStringCompare>;
662d5441 371template class StatRing<SComboAddress>;
f2b2f3ad 372template class StatRing<std::tuple<DNSName, QType> >;