]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/statbag.cc
dnsdist: Add more TCP metrics
[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
51string StatBag::directory()
52{
53 string dir;
54 ostringstream o;
1566533a 55
cb167afd
CHB
56 for(const auto& i: d_stats) {
57 o<<i.first<<"="<<*(i.second)<<",";
58 }
1566533a 59
e903706d 60
ef7cd021 61 for(const funcstats_t::value_type& val : d_funcstats) {
e903706d 62 o << val.first<<"="<<val.second(val.first)<<",";
63 }
12c86877
BH
64 dir=o.str();
65 return dir;
66}
67
68
69vector<string>StatBag::getEntries()
70{
71 vector<string> ret;
1566533a 72
cb167afd
CHB
73 for(const auto& i: d_stats) {
74 ret.push_back(i.first);
75 }
12c86877 76
ef7cd021 77 for(const funcstats_t::value_type& val : d_funcstats) {
e903706d 78 ret.push_back(val.first);
79 }
80
1566533a 81
12c86877
BH
82 return ret;
83
84}
85
86string StatBag::getDescrip(const string &item)
87{
1566533a 88 exists(item);
89 return d_keyDescrips[item];
12c86877
BH
90}
91
92void StatBag::declare(const string &key, const string &descrip)
93{
1566533a 94 AtomicCounter *i=new AtomicCounter(0);
12c86877
BH
95 d_stats[key]=i;
96 d_keyDescrips[key]=descrip;
12c86877
BH
97}
98
e903706d 99void StatBag::declare(const string &key, const string &descrip, StatBag::func_t func)
100{
101
102 d_funcstats[key]=func;
103 d_keyDescrips[key]=descrip;
104}
12c86877
BH
105
106
ac0995bb 107void StatBag::set(const string &key, unsigned long value)
12c86877 108{
12c86877 109 exists(key);
ac0995bb 110 d_stats[key]->store(value);
12c86877
BH
111}
112
ac0995bb 113unsigned long StatBag::read(const string &key)
12c86877 114{
1566533a 115 exists(key);
3b433571 116 funcstats_t::const_iterator iter = d_funcstats.find(key);
117 if(iter != d_funcstats.end())
118 return iter->second(iter->first);
1566533a 119 return *d_stats[key];
12c86877
BH
120}
121
ac0995bb 122unsigned long StatBag::readZero(const string &key)
12c86877 123{
1566533a 124 exists(key);
ac0995bb 125 unsigned long tmp=*d_stats[key];
12c86877 126 d_stats[key]=0;
12c86877
BH
127 return tmp;
128}
129
130
131string StatBag::getValueStr(const string &key)
132{
133 ostringstream o;
134 o<<read(key);
135 return o.str();
136}
137
138string StatBag::getValueStrZero(const string &key)
139{
140 ostringstream o;
141 o<<readZero(key);
142 return o.str();
143}
144
1566533a 145AtomicCounter *StatBag::getPointer(const string &key)
12c86877
BH
146{
147 exists(key);
148 return d_stats[key];
149}
150
151StatBag::~StatBag()
152{
cb167afd
CHB
153 for(const auto& i: d_stats) {
154 delete i.second;
155 }
12c86877
BH
156
157}
158
4eb26e0f 159template<typename T, typename Comp>
160StatRing<T,Comp>::StatRing(unsigned int size)
12c86877 161{
4eb26e0f 162 d_items.set_capacity(size);
163 pthread_mutex_init(&d_lock, 0);
12c86877
BH
164}
165
4eb26e0f 166template<typename T, typename Comp>
167void StatRing<T,Comp>::account(const T& t)
12c86877 168{
4eb26e0f 169 Lock l(&d_lock);
170 d_items.push_back(t);
171}
12c86877 172
4eb26e0f 173template<typename T, typename Comp>
174unsigned int StatRing<T,Comp>::getSize()
175{
176 Lock l(&d_lock);
177 return d_items.capacity();
12c86877 178}
975bee12 179
4eb26e0f 180template<typename T, typename Comp>
181void StatRing<T,Comp>::resize(unsigned int newsize)
12c86877 182{
4eb26e0f 183 Lock l(&d_lock);
184 d_items.set_capacity(newsize);
12c86877
BH
185}
186
4eb26e0f 187
188template<typename T, typename Comp>
189void StatRing<T,Comp>::setHelp(const string &str)
12c86877
BH
190{
191 d_help=str;
192}
193
4eb26e0f 194template<typename T, typename Comp>
195string StatRing<T,Comp>::getHelp()
12c86877
BH
196{
197 return d_help;
198}
199
12c86877 200
4eb26e0f 201template<typename T, typename Comp>
202vector<pair<T, unsigned int> >StatRing<T,Comp>::get() const
12c86877 203{
4eb26e0f 204 Lock l(&d_lock);
205 map<T,unsigned int, Comp> res;
206 for(typename boost::circular_buffer<T>::const_iterator i=d_items.begin();i!=d_items.end();++i) {
207 res[*i]++;
12c86877
BH
208 }
209
4eb26e0f 210 vector<pair<T ,unsigned int> > tmp;
211 for(typename map<T, unsigned int>::const_iterator i=res.begin();i!=res.end();++i)
12c86877
BH
212 tmp.push_back(*i);
213
214 sort(tmp.begin(),tmp.end(),popisort);
215
216 return tmp;
217}
218
219void StatBag::declareRing(const string &name, const string &help, unsigned int size)
220{
fadd04cc 221 d_rings[name]=StatRing<string, CIStringCompare>(size);
12c86877
BH
222 d_rings[name].setHelp(help);
223}
224
4eb26e0f 225void StatBag::declareComboRing(const string &name, const string &help, unsigned int size)
12c86877 226{
662d5441 227 d_comborings[name]=StatRing<SComboAddress>(size);
4eb26e0f 228 d_comborings[name].setHelp(help);
12c86877
BH
229}
230
f2b2f3ad
PL
231void StatBag::declareDNSNameQTypeRing(const string &name, const string &help, unsigned int size)
232{
233 d_dnsnameqtyperings[name] = StatRing<std::tuple<DNSName, QType> >(size);
234 d_dnsnameqtyperings[name].setHelp(help);
235}
236
4eb26e0f 237
238vector<pair<string, unsigned int> > StatBag::getRing(const string &name)
12c86877 239{
f2b2f3ad 240 if(d_rings.count(name)) {
4eb26e0f 241 return d_rings[name].get();
f2b2f3ad
PL
242 }
243 vector<pair<string, unsigned int> > ret;
244
245 if (d_comborings.count(name)) {
662d5441 246 typedef pair<SComboAddress, unsigned int> stor_t;
4eb26e0f 247 vector<stor_t> raw =d_comborings[name].get();
ef7cd021 248 for(const stor_t& stor : raw) {
662d5441 249 ret.push_back(make_pair(stor.first.ca.toString(), stor.second));
4eb26e0f 250 }
f2b2f3ad
PL
251 } else if(d_dnsnameqtyperings.count(name)) {
252 auto raw = d_dnsnameqtyperings[name].get();
253 for (auto const &e : raw) {
254 ret.push_back(make_pair(std::get<0>(e.first).toLogString() + "/" + std::get<1>(e.first).getName(), e.second));
255 }
12c86877 256 }
f2b2f3ad 257 return ret;
4eb26e0f 258}
259
260template<typename T, typename Comp>
261void StatRing<T,Comp>::reset()
262{
263 Lock l(&d_lock);
264 d_items.clear();
12c86877
BH
265}
266
267void StatBag::resetRing(const string &name)
268{
4eb26e0f 269 if(d_rings.count(name))
270 d_rings[name].reset();
f2b2f3ad 271 if(d_comborings.count(name))
4eb26e0f 272 d_comborings[name].reset();
f2b2f3ad
PL
273 if(d_dnsnameqtyperings.count(name))
274 d_dnsnameqtyperings[name].reset();
12c86877
BH
275}
276
bb3c3f50 277void StatBag::resizeRing(const string &name, unsigned int newsize)
12c86877 278{
4eb26e0f 279 if(d_rings.count(name))
280 d_rings[name].resize(newsize);
f2b2f3ad 281 if(d_comborings.count(name))
4eb26e0f 282 d_comborings[name].resize(newsize);
f2b2f3ad
PL
283 if(d_dnsnameqtyperings.count(name))
284 return d_dnsnameqtyperings[name].resize(newsize);
12c86877
BH
285}
286
287
bb3c3f50 288unsigned int StatBag::getRingSize(const string &name)
12c86877 289{
4eb26e0f 290 if(d_rings.count(name))
291 return d_rings[name].getSize();
f2b2f3ad 292 if(d_comborings.count(name))
4eb26e0f 293 return d_comborings[name].getSize();
f2b2f3ad
PL
294 if(d_dnsnameqtyperings.count(name))
295 return d_dnsnameqtyperings[name].getSize();
296 return 0;
12c86877
BH
297}
298
12c86877
BH
299string StatBag::getRingTitle(const string &name)
300{
4eb26e0f 301 if(d_rings.count(name))
302 return d_rings[name].getHelp();
f2b2f3ad 303 if(d_comborings.count(name))
4eb26e0f 304 return d_comborings[name].getHelp();
f2b2f3ad
PL
305 if(d_dnsnameqtyperings.count(name))
306 return d_dnsnameqtyperings[name].getHelp();
307 return "";
12c86877
BH
308}
309
310vector<string>StatBag::listRings()
311{
312 vector<string> ret;
fadd04cc 313 for(auto i=d_rings.begin();i!=d_rings.end();++i)
4eb26e0f 314 ret.push_back(i->first);
fadd04cc 315 for(auto i=d_comborings.begin();i!=d_comborings.end();++i)
12c86877 316 ret.push_back(i->first);
f2b2f3ad
PL
317 for(const auto &i : d_dnsnameqtyperings)
318 ret.push_back(i.first);
4eb26e0f 319
12c86877
BH
320 return ret;
321}
322
ef1439ff
KM
323bool StatBag::ringExists(const string &name)
324{
f2b2f3ad 325 return d_rings.count(name) || d_comborings.count(name) || d_dnsnameqtyperings.count(name);
ef1439ff 326}
4eb26e0f 327
fadd04cc 328template class StatRing<std::string, CIStringCompare>;
662d5441 329template class StatRing<SComboAddress>;
f2b2f3ad 330template class StatRing<std::tuple<DNSName, QType> >;