]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/statbag.cc
Include config.h only in .cc files
[thirdparty/pdns.git] / pdns / statbag.cc
1 /*
2 PowerDNS Versatile Database Driven Nameserver
3 Copyright (C) 2002 - 2014 PowerDNS.COM BV
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2
7 as published by the Free Software Foundation
8
9 Additionally, the license of this program contains a special
10 exception which allows to distribute the program in binary form when
11 it is linked against OpenSSL.
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 St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 #include "utility.hh"
27 #include "statbag.hh"
28 #include "pdnsexception.hh"
29 #include <iostream>
30 #include <sstream>
31 #include <algorithm>
32 #include "arguments.hh"
33 #include "lock.hh"
34 #include "iputils.hh"
35 #include <boost/foreach.hpp>
36
37 #include "namespaces.hh"
38
39 StatBag::StatBag()
40 {
41 d_doRings=false;
42 }
43
44 void StatBag::exists(const string &key)
45 {
46 if(!d_keyDescrips.count(key))
47 {
48 throw PDNSException("Trying to deposit into unknown StatBag key '"+key+"'");
49 }
50 }
51
52 string StatBag::directory()
53 {
54 string dir;
55 ostringstream o;
56
57 for(map<string, AtomicCounter *>::const_iterator i=d_stats.begin();
58 i!=d_stats.end();
59 i++)
60 {
61 o<<i->first<<"="<<*(i->second)<<",";
62 }
63
64
65 BOOST_FOREACH(const funcstats_t::value_type& val, d_funcstats) {
66 o << val.first<<"="<<val.second(val.first)<<",";
67 }
68 dir=o.str();
69 return dir;
70 }
71
72
73 vector<string>StatBag::getEntries()
74 {
75 vector<string> ret;
76
77 for(map<string, AtomicCounter *>::const_iterator i=d_stats.begin();
78 i!=d_stats.end();
79 i++)
80 ret.push_back(i->first);
81
82 BOOST_FOREACH(const funcstats_t::value_type& val, d_funcstats) {
83 ret.push_back(val.first);
84 }
85
86
87 return ret;
88
89 }
90
91 string StatBag::getDescrip(const string &item)
92 {
93 exists(item);
94 return d_keyDescrips[item];
95 }
96
97 void StatBag::declare(const string &key, const string &descrip)
98 {
99 AtomicCounter *i=new AtomicCounter(0);
100 d_stats[key]=i;
101 d_keyDescrips[key]=descrip;
102 }
103
104 void StatBag::declare(const string &key, const string &descrip, StatBag::func_t func)
105 {
106
107 d_funcstats[key]=func;
108 d_keyDescrips[key]=descrip;
109 }
110
111
112 void StatBag::set(const string &key, AtomicCounter::native_t value)
113 {
114 exists(key);
115 *d_stats[key]=AtomicCounter(value);
116 }
117
118 AtomicCounter::native_t StatBag::read(const string &key)
119 {
120 exists(key);
121 funcstats_t::const_iterator iter = d_funcstats.find(key);
122 if(iter != d_funcstats.end())
123 return iter->second(iter->first);
124 return *d_stats[key];
125 }
126
127 AtomicCounter::native_t StatBag::readZero(const string &key)
128 {
129 exists(key);
130 AtomicCounter::native_t tmp=*d_stats[key];
131 d_stats[key]=0;
132 return tmp;
133 }
134
135
136 string StatBag::getValueStr(const string &key)
137 {
138 ostringstream o;
139 o<<read(key);
140 return o.str();
141 }
142
143 string StatBag::getValueStrZero(const string &key)
144 {
145 ostringstream o;
146 o<<readZero(key);
147 return o.str();
148 }
149
150 AtomicCounter *StatBag::getPointer(const string &key)
151 {
152 exists(key);
153 return d_stats[key];
154 }
155
156 StatBag::~StatBag()
157 {
158 for(map<string, AtomicCounter *>::const_iterator i=d_stats.begin();
159 i!=d_stats.end();
160 i++)
161 {
162 delete i->second;
163 }
164
165 }
166
167 template<typename T, typename Comp>
168 StatRing<T,Comp>::StatRing(unsigned int size)
169 {
170 d_items.set_capacity(size);
171 pthread_mutex_init(&d_lock, 0);
172 }
173
174 template<typename T, typename Comp>
175 void StatRing<T,Comp>::account(const T& t)
176 {
177 Lock l(&d_lock);
178 d_items.push_back(t);
179 }
180
181 template<typename T, typename Comp>
182 unsigned int StatRing<T,Comp>::getSize()
183 {
184 Lock l(&d_lock);
185 return d_items.capacity();
186 }
187
188 template<typename T, typename Comp>
189 void StatRing<T,Comp>::resize(unsigned int newsize)
190 {
191 Lock l(&d_lock);
192 d_items.set_capacity(newsize);
193 }
194
195
196 template<typename T, typename Comp>
197 void StatRing<T,Comp>::setHelp(const string &str)
198 {
199 d_help=str;
200 }
201
202 template<typename T, typename Comp>
203 string StatRing<T,Comp>::getHelp()
204 {
205 return d_help;
206 }
207
208
209 template<typename T, typename Comp>
210 vector<pair<T, unsigned int> >StatRing<T,Comp>::get() const
211 {
212 Lock l(&d_lock);
213 map<T,unsigned int, Comp> res;
214 for(typename boost::circular_buffer<T>::const_iterator i=d_items.begin();i!=d_items.end();++i) {
215 res[*i]++;
216 }
217
218 vector<pair<T ,unsigned int> > tmp;
219 for(typename map<T, unsigned int>::const_iterator i=res.begin();i!=res.end();++i)
220 tmp.push_back(*i);
221
222 sort(tmp.begin(),tmp.end(),popisort);
223
224 return tmp;
225 }
226
227 void StatBag::declareRing(const string &name, const string &help, unsigned int size)
228 {
229 d_rings[name]=StatRing<string>(size);
230 d_rings[name].setHelp(help);
231 }
232
233 void StatBag::declareComboRing(const string &name, const string &help, unsigned int size)
234 {
235 d_comborings[name]=StatRing<SComboAddress>(size);
236 d_comborings[name].setHelp(help);
237 }
238
239
240 vector<pair<string, unsigned int> > StatBag::getRing(const string &name)
241 {
242 if(d_rings.count(name))
243 return d_rings[name].get();
244 else {
245 typedef pair<SComboAddress, unsigned int> stor_t;
246 vector<stor_t> raw =d_comborings[name].get();
247 vector<pair<string, unsigned int> > ret;
248 BOOST_FOREACH(const stor_t& stor, raw) {
249 ret.push_back(make_pair(stor.first.ca.toString(), stor.second));
250 }
251 return ret;
252 }
253
254 }
255
256 template<typename T, typename Comp>
257 void StatRing<T,Comp>::reset()
258 {
259 Lock l(&d_lock);
260 d_items.clear();
261 }
262
263 void StatBag::resetRing(const string &name)
264 {
265 if(d_rings.count(name))
266 d_rings[name].reset();
267 else
268 d_comborings[name].reset();
269 }
270
271 void StatBag::resizeRing(const string &name, unsigned int newsize)
272 {
273 if(d_rings.count(name))
274 d_rings[name].resize(newsize);
275 else
276 d_comborings[name].resize(newsize);
277 }
278
279
280 unsigned int StatBag::getRingSize(const string &name)
281 {
282 if(d_rings.count(name))
283 return d_rings[name].getSize();
284 else
285 return d_comborings[name].getSize();
286 }
287
288 string StatBag::getRingTitle(const string &name)
289 {
290 if(d_rings.count(name))
291 return d_rings[name].getHelp();
292 else
293 return d_comborings[name].getHelp();
294 }
295
296 vector<string>StatBag::listRings()
297 {
298 vector<string> ret;
299 for(map<string,StatRing<string> >::const_iterator i=d_rings.begin();i!=d_rings.end();++i)
300 ret.push_back(i->first);
301 for(map<string,StatRing<SComboAddress> >::const_iterator i=d_comborings.begin();i!=d_comborings.end();++i)
302 ret.push_back(i->first);
303
304 return ret;
305 }
306
307 bool StatBag::ringExists(const string &name)
308 {
309 return d_rings.count(name) || d_comborings.count(name);
310 }
311
312 template class StatRing<std::string>;
313 template class StatRing<SComboAddress>;