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