]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/statbag.cc
Our ringbuffers in auth were case sensitive, leading to pages FuLl of 0x20 ModUlaTed...
[thirdparty/pdns.git] / pdns / statbag.cc
1 /*
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 */
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 #include "utility.hh"
26 #include "statbag.hh"
27 #include "pdnsexception.hh"
28 #include <iostream>
29 #include <sstream>
30 #include <algorithm>
31 #include "arguments.hh"
32 #include "lock.hh"
33 #include "iputils.hh"
34
35
36 #include "namespaces.hh"
37
38 StatBag::StatBag()
39 {
40 d_doRings=false;
41 }
42
43 void StatBag::exists(const string &key)
44 {
45 if(!d_keyDescrips.count(key))
46 {
47 throw PDNSException("Trying to deposit into unknown StatBag key '"+key+"'");
48 }
49 }
50
51 string StatBag::directory()
52 {
53 string dir;
54 ostringstream o;
55
56 for(const auto& i: d_stats) {
57 o<<i.first<<"="<<*(i.second)<<",";
58 }
59
60
61 for(const funcstats_t::value_type& val : d_funcstats) {
62 o << val.first<<"="<<val.second(val.first)<<",";
63 }
64 dir=o.str();
65 return dir;
66 }
67
68
69 vector<string>StatBag::getEntries()
70 {
71 vector<string> ret;
72
73 for(const auto& i: d_stats) {
74 ret.push_back(i.first);
75 }
76
77 for(const funcstats_t::value_type& val : d_funcstats) {
78 ret.push_back(val.first);
79 }
80
81
82 return ret;
83
84 }
85
86 string StatBag::getDescrip(const string &item)
87 {
88 exists(item);
89 return d_keyDescrips[item];
90 }
91
92 void StatBag::declare(const string &key, const string &descrip)
93 {
94 AtomicCounter *i=new AtomicCounter(0);
95 d_stats[key]=i;
96 d_keyDescrips[key]=descrip;
97 }
98
99 void 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 }
105
106
107 void StatBag::set(const string &key, unsigned long value)
108 {
109 exists(key);
110 d_stats[key]->store(value);
111 }
112
113 unsigned long StatBag::read(const string &key)
114 {
115 exists(key);
116 funcstats_t::const_iterator iter = d_funcstats.find(key);
117 if(iter != d_funcstats.end())
118 return iter->second(iter->first);
119 return *d_stats[key];
120 }
121
122 unsigned long StatBag::readZero(const string &key)
123 {
124 exists(key);
125 unsigned long tmp=*d_stats[key];
126 d_stats[key]=0;
127 return tmp;
128 }
129
130
131 string StatBag::getValueStr(const string &key)
132 {
133 ostringstream o;
134 o<<read(key);
135 return o.str();
136 }
137
138 string StatBag::getValueStrZero(const string &key)
139 {
140 ostringstream o;
141 o<<readZero(key);
142 return o.str();
143 }
144
145 AtomicCounter *StatBag::getPointer(const string &key)
146 {
147 exists(key);
148 return d_stats[key];
149 }
150
151 StatBag::~StatBag()
152 {
153 for(const auto& i: d_stats) {
154 delete i.second;
155 }
156
157 }
158
159 template<typename T, typename Comp>
160 StatRing<T,Comp>::StatRing(unsigned int size)
161 {
162 d_items.set_capacity(size);
163 pthread_mutex_init(&d_lock, 0);
164 }
165
166 template<typename T, typename Comp>
167 void StatRing<T,Comp>::account(const T& t)
168 {
169 Lock l(&d_lock);
170 d_items.push_back(t);
171 }
172
173 template<typename T, typename Comp>
174 unsigned int StatRing<T,Comp>::getSize()
175 {
176 Lock l(&d_lock);
177 return d_items.capacity();
178 }
179
180 template<typename T, typename Comp>
181 void StatRing<T,Comp>::resize(unsigned int newsize)
182 {
183 Lock l(&d_lock);
184 d_items.set_capacity(newsize);
185 }
186
187
188 template<typename T, typename Comp>
189 void StatRing<T,Comp>::setHelp(const string &str)
190 {
191 d_help=str;
192 }
193
194 template<typename T, typename Comp>
195 string StatRing<T,Comp>::getHelp()
196 {
197 return d_help;
198 }
199
200
201 template<typename T, typename Comp>
202 vector<pair<T, unsigned int> >StatRing<T,Comp>::get() const
203 {
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]++;
208 }
209
210 vector<pair<T ,unsigned int> > tmp;
211 for(typename map<T, unsigned int>::const_iterator i=res.begin();i!=res.end();++i)
212 tmp.push_back(*i);
213
214 sort(tmp.begin(),tmp.end(),popisort);
215
216 return tmp;
217 }
218
219 void StatBag::declareRing(const string &name, const string &help, unsigned int size)
220 {
221 d_rings[name]=StatRing<string, CIStringCompare>(size);
222 d_rings[name].setHelp(help);
223 }
224
225 void StatBag::declareComboRing(const string &name, const string &help, unsigned int size)
226 {
227 d_comborings[name]=StatRing<SComboAddress>(size);
228 d_comborings[name].setHelp(help);
229 }
230
231
232 vector<pair<string, unsigned int> > StatBag::getRing(const string &name)
233 {
234 if(d_rings.count(name))
235 return d_rings[name].get();
236 else {
237 typedef pair<SComboAddress, unsigned int> stor_t;
238 vector<stor_t> raw =d_comborings[name].get();
239 vector<pair<string, unsigned int> > ret;
240 for(const stor_t& stor : raw) {
241 ret.push_back(make_pair(stor.first.ca.toString(), stor.second));
242 }
243 return ret;
244 }
245
246 }
247
248 template<typename T, typename Comp>
249 void StatRing<T,Comp>::reset()
250 {
251 Lock l(&d_lock);
252 d_items.clear();
253 }
254
255 void StatBag::resetRing(const string &name)
256 {
257 if(d_rings.count(name))
258 d_rings[name].reset();
259 else
260 d_comborings[name].reset();
261 }
262
263 void StatBag::resizeRing(const string &name, unsigned int newsize)
264 {
265 if(d_rings.count(name))
266 d_rings[name].resize(newsize);
267 else
268 d_comborings[name].resize(newsize);
269 }
270
271
272 unsigned int StatBag::getRingSize(const string &name)
273 {
274 if(d_rings.count(name))
275 return d_rings[name].getSize();
276 else
277 return d_comborings[name].getSize();
278 }
279
280 string StatBag::getRingTitle(const string &name)
281 {
282 if(d_rings.count(name))
283 return d_rings[name].getHelp();
284 else
285 return d_comborings[name].getHelp();
286 }
287
288 vector<string>StatBag::listRings()
289 {
290 vector<string> ret;
291 for(auto i=d_rings.begin();i!=d_rings.end();++i)
292 ret.push_back(i->first);
293 for(auto i=d_comborings.begin();i!=d_comborings.end();++i)
294 ret.push_back(i->first);
295
296 return ret;
297 }
298
299 bool StatBag::ringExists(const string &name)
300 {
301 return d_rings.count(name) || d_comborings.count(name);
302 }
303
304 template class StatRing<std::string, CIStringCompare>;
305 template class StatRing<SComboAddress>;