]>
Commit | Line | Data |
---|---|---|
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 | |
38 | StatBag::StatBag() | |
39 | { | |
40 | d_doRings=false; | |
12c86877 BH |
41 | } |
42 | ||
12c86877 BH |
43 | void 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 | 51 | string 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 | ||
73 | vector<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 | ||
94 | string StatBag::getDescrip(const string &item) | |
95 | { | |
1566533a | 96 | exists(item); |
97 | return d_keyDescrips[item]; | |
12c86877 BH |
98 | } |
99 | ||
100 | void StatBag::declare(const string &key, const string &descrip) | |
101 | { | |
1566533a | 102 | AtomicCounter *i=new AtomicCounter(0); |
12c86877 BH |
103 | d_stats[key]=i; |
104 | d_keyDescrips[key]=descrip; | |
12c86877 BH |
105 | } |
106 | ||
e903706d | 107 | void 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 | 115 | void 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 | 121 | unsigned 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 | 130 | unsigned 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 | ||
139 | string StatBag::getValueStr(const string &key) | |
140 | { | |
141 | ostringstream o; | |
142 | o<<read(key); | |
143 | return o.str(); | |
144 | } | |
145 | ||
146 | string StatBag::getValueStrZero(const string &key) | |
147 | { | |
148 | ostringstream o; | |
149 | o<<readZero(key); | |
150 | return o.str(); | |
151 | } | |
152 | ||
1566533a | 153 | AtomicCounter *StatBag::getPointer(const string &key) |
12c86877 BH |
154 | { |
155 | exists(key); | |
156 | return d_stats[key]; | |
157 | } | |
158 | ||
159 | StatBag::~StatBag() | |
160 | { | |
cb167afd CHB |
161 | for(const auto& i: d_stats) { |
162 | delete i.second; | |
163 | } | |
12c86877 BH |
164 | |
165 | } | |
166 | ||
4eb26e0f | 167 | template<typename T, typename Comp> |
168 | StatRing<T,Comp>::StatRing(unsigned int size) | |
12c86877 | 169 | { |
4eb26e0f | 170 | d_items.set_capacity(size); |
171 | pthread_mutex_init(&d_lock, 0); | |
12c86877 BH |
172 | } |
173 | ||
4eb26e0f | 174 | template<typename T, typename Comp> |
175 | void StatRing<T,Comp>::account(const T& t) | |
12c86877 | 176 | { |
4eb26e0f | 177 | Lock l(&d_lock); |
178 | d_items.push_back(t); | |
179 | } | |
12c86877 | 180 | |
4eb26e0f | 181 | template<typename T, typename Comp> |
182 | unsigned int StatRing<T,Comp>::getSize() | |
183 | { | |
184 | Lock l(&d_lock); | |
185 | return d_items.capacity(); | |
12c86877 | 186 | } |
975bee12 | 187 | |
4eb26e0f | 188 | template<typename T, typename Comp> |
189 | void StatRing<T,Comp>::resize(unsigned int newsize) | |
12c86877 | 190 | { |
4eb26e0f | 191 | Lock l(&d_lock); |
192 | d_items.set_capacity(newsize); | |
12c86877 BH |
193 | } |
194 | ||
4eb26e0f | 195 | |
196 | template<typename T, typename Comp> | |
197 | void StatRing<T,Comp>::setHelp(const string &str) | |
12c86877 BH |
198 | { |
199 | d_help=str; | |
200 | } | |
201 | ||
4eb26e0f | 202 | template<typename T, typename Comp> |
203 | string StatRing<T,Comp>::getHelp() | |
12c86877 BH |
204 | { |
205 | return d_help; | |
206 | } | |
207 | ||
12c86877 | 208 | |
4eb26e0f | 209 | template<typename T, typename Comp> |
210 | vector<pair<T, unsigned int> >StatRing<T,Comp>::get() const | |
12c86877 | 211 | { |
4eb26e0f | 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]++; | |
12c86877 BH |
216 | } |
217 | ||
4eb26e0f | 218 | vector<pair<T ,unsigned int> > tmp; |
219 | for(typename map<T, unsigned int>::const_iterator i=res.begin();i!=res.end();++i) | |
12c86877 BH |
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 | { | |
fadd04cc | 229 | d_rings[name]=StatRing<string, CIStringCompare>(size); |
12c86877 BH |
230 | d_rings[name].setHelp(help); |
231 | } | |
232 | ||
4eb26e0f | 233 | void StatBag::declareComboRing(const string &name, const string &help, unsigned int size) |
12c86877 | 234 | { |
662d5441 | 235 | d_comborings[name]=StatRing<SComboAddress>(size); |
4eb26e0f | 236 | d_comborings[name].setHelp(help); |
12c86877 BH |
237 | } |
238 | ||
f2b2f3ad PL |
239 | void StatBag::declareDNSNameQTypeRing(const string &name, const string &help, unsigned int size) |
240 | { | |
241 | d_dnsnameqtyperings[name] = StatRing<std::tuple<DNSName, QType> >(size); | |
242 | d_dnsnameqtyperings[name].setHelp(help); | |
243 | } | |
244 | ||
4eb26e0f | 245 | |
246 | vector<pair<string, unsigned int> > StatBag::getRing(const string &name) | |
12c86877 | 247 | { |
f2b2f3ad | 248 | if(d_rings.count(name)) { |
4eb26e0f | 249 | return d_rings[name].get(); |
f2b2f3ad PL |
250 | } |
251 | vector<pair<string, unsigned int> > ret; | |
252 | ||
253 | if (d_comborings.count(name)) { | |
662d5441 | 254 | typedef pair<SComboAddress, unsigned int> stor_t; |
4eb26e0f | 255 | vector<stor_t> raw =d_comborings[name].get(); |
ef7cd021 | 256 | for(const stor_t& stor : raw) { |
662d5441 | 257 | ret.push_back(make_pair(stor.first.ca.toString(), stor.second)); |
4eb26e0f | 258 | } |
f2b2f3ad PL |
259 | } else if(d_dnsnameqtyperings.count(name)) { |
260 | auto raw = d_dnsnameqtyperings[name].get(); | |
261 | for (auto const &e : raw) { | |
262 | ret.push_back(make_pair(std::get<0>(e.first).toLogString() + "/" + std::get<1>(e.first).getName(), e.second)); | |
263 | } | |
12c86877 | 264 | } |
f2b2f3ad | 265 | return ret; |
4eb26e0f | 266 | } |
267 | ||
268 | template<typename T, typename Comp> | |
269 | void StatRing<T,Comp>::reset() | |
270 | { | |
271 | Lock l(&d_lock); | |
272 | d_items.clear(); | |
12c86877 BH |
273 | } |
274 | ||
275 | void StatBag::resetRing(const string &name) | |
276 | { | |
4eb26e0f | 277 | if(d_rings.count(name)) |
278 | d_rings[name].reset(); | |
f2b2f3ad | 279 | if(d_comborings.count(name)) |
4eb26e0f | 280 | d_comborings[name].reset(); |
f2b2f3ad PL |
281 | if(d_dnsnameqtyperings.count(name)) |
282 | d_dnsnameqtyperings[name].reset(); | |
12c86877 BH |
283 | } |
284 | ||
bb3c3f50 | 285 | void StatBag::resizeRing(const string &name, unsigned int newsize) |
12c86877 | 286 | { |
4eb26e0f | 287 | if(d_rings.count(name)) |
288 | d_rings[name].resize(newsize); | |
f2b2f3ad | 289 | if(d_comborings.count(name)) |
4eb26e0f | 290 | d_comborings[name].resize(newsize); |
f2b2f3ad PL |
291 | if(d_dnsnameqtyperings.count(name)) |
292 | return d_dnsnameqtyperings[name].resize(newsize); | |
12c86877 BH |
293 | } |
294 | ||
295 | ||
bb3c3f50 | 296 | unsigned int StatBag::getRingSize(const string &name) |
12c86877 | 297 | { |
4eb26e0f | 298 | if(d_rings.count(name)) |
299 | return d_rings[name].getSize(); | |
f2b2f3ad | 300 | if(d_comborings.count(name)) |
4eb26e0f | 301 | return d_comborings[name].getSize(); |
f2b2f3ad PL |
302 | if(d_dnsnameqtyperings.count(name)) |
303 | return d_dnsnameqtyperings[name].getSize(); | |
304 | return 0; | |
12c86877 BH |
305 | } |
306 | ||
12c86877 BH |
307 | string StatBag::getRingTitle(const string &name) |
308 | { | |
4eb26e0f | 309 | if(d_rings.count(name)) |
310 | return d_rings[name].getHelp(); | |
f2b2f3ad | 311 | if(d_comborings.count(name)) |
4eb26e0f | 312 | return d_comborings[name].getHelp(); |
f2b2f3ad PL |
313 | if(d_dnsnameqtyperings.count(name)) |
314 | return d_dnsnameqtyperings[name].getHelp(); | |
315 | return ""; | |
12c86877 BH |
316 | } |
317 | ||
318 | vector<string>StatBag::listRings() | |
319 | { | |
320 | vector<string> ret; | |
fadd04cc | 321 | for(auto i=d_rings.begin();i!=d_rings.end();++i) |
4eb26e0f | 322 | ret.push_back(i->first); |
fadd04cc | 323 | for(auto i=d_comborings.begin();i!=d_comborings.end();++i) |
12c86877 | 324 | ret.push_back(i->first); |
f2b2f3ad PL |
325 | for(const auto &i : d_dnsnameqtyperings) |
326 | ret.push_back(i.first); | |
4eb26e0f | 327 | |
12c86877 BH |
328 | return ret; |
329 | } | |
330 | ||
ef1439ff KM |
331 | bool StatBag::ringExists(const string &name) |
332 | { | |
f2b2f3ad | 333 | return d_rings.count(name) || d_comborings.count(name) || d_dnsnameqtyperings.count(name); |
ef1439ff | 334 | } |
4eb26e0f | 335 | |
f3245c8c OM |
336 | void StatBag::blacklist(const string& str) { |
337 | d_blacklist.insert(str); | |
338 | } | |
339 | ||
fadd04cc | 340 | template class StatRing<std::string, CIStringCompare>; |
662d5441 | 341 | template class StatRing<SComboAddress>; |
f2b2f3ad | 342 | template class StatRing<std::tuple<DNSName, QType> >; |