]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/statbag.hh
Limit the number of queries sent out to get NS addresses per query.
[thirdparty/pdns.git] / pdns / statbag.hh
CommitLineData
12c86877 1/*
12471842
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 */
e8c59f2d 22#pragma once
12c86877
BH
23#include <pthread.h>
24#include <map>
92b91988 25#include <mutex>
4eb26e0f 26#include <functional>
12c86877
BH
27#include <string>
28#include <vector>
29#include "lock.hh"
10f4eea8 30#include "namespaces.hh"
4eb26e0f 31#include "iputils.hh"
9f6a31ff 32#include "circular_buffer.hh"
12c86877 33
662d5441 34
4eb26e0f 35template<typename T, typename Comp=std::less<T> >
12c86877
BH
36class StatRing
37{
38public:
bb3c3f50 39 StatRing(unsigned int size=10000);
ef2ea4bf 40 // Some older C++ libs have trouble emplacing without a copy-constructor, so provide one
f979b818 41 StatRing(const StatRing &);
cf54d848 42 StatRing & operator=(const StatRing &) = delete;
f979b818 43
4eb26e0f 44 void account(const T &item);
12c86877 45
74e38357
RG
46 uint64_t getSize() const;
47 uint64_t getEntriesCount() const;
bb3c3f50 48 void resize(unsigned int newsize);
12c86877
BH
49 void reset();
50 void setHelp(const string &str);
51 string getHelp();
4eb26e0f 52
53 vector<pair<T, unsigned int> > get() const;
12c86877 54private:
4eb26e0f 55 static bool popisort(const pair<T,int> &a, const pair<T,int> &b)
56 {
57 return (a.second > b.second);
58 }
59
60 boost::circular_buffer<T> d_items;
92b91988 61 mutable std::mutex d_lock;
12c86877
BH
62 string d_help;
63};
64
65
66//! use this to gather and query statistics
67class StatBag
68{
c2826d2e 69 map<string, std::unique_ptr<AtomicCounter>> d_stats;
12c86877 70 map<string, string> d_keyDescrips;
fadd04cc 71 map<string,StatRing<string, CIStringCompare> >d_rings;
ef2ea4bf 72 map<string,StatRing<SComboAddress> >d_comboRings;
f2b2f3ad 73 map<string,StatRing<std::tuple<DNSName, QType> > >d_dnsnameqtyperings;
e903706d 74 typedef boost::function<uint64_t(const std::string&)> func_t;
75 typedef map<string, func_t> funcstats_t;
76 funcstats_t d_funcstats;
12c86877 77 bool d_doRings;
f3245c8c 78 std::set<string> d_blacklist;
12c86877 79
74e38357
RG
80 void registerRingStats(const string& name);
81
12c86877
BH
82public:
83 StatBag(); //!< Naked constructor. You need to declare keys before this class becomes useful
84 ~StatBag();
85 void declare(const string &key, const string &descrip=""); //!< Before you can store or access a key, you need to declare it
e903706d 86 void declare(const string &key, const string &descrip, func_t func); //!< Before you can store or access a key, you need to declare it
12c86877
BH
87
88 void declareRing(const string &name, const string &title, unsigned int size=10000);
4eb26e0f 89 void declareComboRing(const string &name, const string &help, unsigned int size=10000);
f2b2f3ad 90 void declareDNSNameQTypeRing(const string &name, const string &help, unsigned int size=10000);
bb3c3f50 91 vector<pair<string, unsigned int> >getRing(const string &name);
12c86877 92 string getRingTitle(const string &name);
4eb26e0f 93 void ringAccount(const char* name, const string &item)
12c86877 94 {
4eb26e0f 95 if(d_doRings) {
96 if(!d_rings.count(name))
75d28357 97 throw runtime_error("Attempting to account to non-existent ring '"+std::string(name)+"'");
4eb26e0f 98
12c86877 99 d_rings[name].account(item);
4eb26e0f 100 }
12c86877 101 }
4eb26e0f 102 void ringAccount(const char* name, const ComboAddress &item)
103 {
104 if(d_doRings) {
ef2ea4bf
JS
105 if(!d_comboRings.count(name))
106 throw runtime_error("Attempting to account to non-existent comboRing '"+std::string(name)+"'");
107 d_comboRings[name].account(item);
4eb26e0f 108 }
109 }
f2b2f3ad
PL
110 void ringAccount(const char* name, const DNSName &dnsname, const QType &qtype)
111 {
112 if(d_doRings) {
113 if(!d_dnsnameqtyperings.count(name))
114 throw runtime_error("Attempting to account to non-existent dnsname+qtype ring '"+std::string(name)+"'");
115 d_dnsnameqtyperings[name].account(std::make_tuple(dnsname, qtype));
116 }
117 }
4eb26e0f 118
12c86877
BH
119 void doRings()
120 {
121 d_doRings=true;
122 }
123
124 vector<string>listRings();
ef1439ff 125 bool ringExists(const string &name);
12c86877 126 void resetRing(const string &name);
bb3c3f50 127 void resizeRing(const string &name, unsigned int newsize);
74e38357
RG
128 uint64_t getRingSize(const string &name);
129 uint64_t getRingEntriesCount(const string &name);
12c86877 130
f3245c8c 131 string directory(); //!< Returns a list of all data stored
12c86877
BH
132 vector<string> getEntries(); //!< returns a vector with datums (items)
133 string getDescrip(const string &item); //!< Returns the description of this datum/item
134 void exists(const string &key); //!< call this function to throw an exception in case a key does not exist
135 inline void deposit(const string &key, int value); //!< increment the statistics behind this key by value amount
136 inline void inc(const string &key); //!< increase this key's value by one
ac0995bb 137 void set(const string &key, unsigned long value); //!< set this key's value
138 unsigned long read(const string &key); //!< read the value behind this key
139 unsigned long readZero(const string &key); //!< read the value behind this key, and zero it afterwards
1566533a 140 AtomicCounter *getPointer(const string &key); //!< get a direct pointer to the value behind a key. Use this for high performance increments
12c86877
BH
141 string getValueStr(const string &key); //!< read a value behind a key, and return it as a string
142 string getValueStrZero(const string &key); //!< read a value behind a key, and return it as a string, and zero afterwards
f3245c8c 143 void blacklist(const string &str);
12c86877
BH
144};
145
146inline void StatBag::deposit(const string &key, int value)
147{
12c86877
BH
148 exists(key);
149
150 *d_stats[key]+=value;
12c86877
BH
151}
152
153inline void StatBag::inc(const string &key)
154{
155 deposit(key,1);
156}