]>
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 | */ | |
e8c59f2d | 22 | #pragma once |
12c86877 | 23 | #include <map> |
4eb26e0f | 24 | #include <functional> |
12c86877 BH |
25 | #include <string> |
26 | #include <vector> | |
27 | #include "lock.hh" | |
10f4eea8 | 28 | #include "namespaces.hh" |
4eb26e0f | 29 | #include "iputils.hh" |
9f6a31ff | 30 | #include "circular_buffer.hh" |
12c86877 | 31 | |
4eb26e0f | 32 | template<typename T, typename Comp=std::less<T> > |
12c86877 BH |
33 | class StatRing |
34 | { | |
35 | public: | |
bb3c3f50 | 36 | StatRing(unsigned int size=10000); |
42b8372c RG |
37 | StatRing(const StatRing&) = delete; |
38 | StatRing& operator=(const StatRing&) = delete; | |
39 | StatRing& operator=(StatRing&&) = delete; | |
40 | StatRing(StatRing&&) = default; | |
6f7df50a | 41 | |
4eb26e0f | 42 | void account(const T &item); |
12c86877 | 43 | |
74e38357 RG |
44 | uint64_t getSize() const; |
45 | uint64_t getEntriesCount() const; | |
6f7df50a | 46 | void resize(unsigned int newsize); |
12c86877 BH |
47 | void reset(); |
48 | void setHelp(const string &str); | |
42b8372c | 49 | string getHelp() const; |
4eb26e0f | 50 | |
51 | vector<pair<T, unsigned int> > get() const; | |
12c86877 | 52 | private: |
6f7df50a | 53 | static bool popisort(const pair<T,int> &a, const pair<T,int> &b) |
4eb26e0f | 54 | { |
55 | return (a.second > b.second); | |
56 | } | |
57 | ||
58 | boost::circular_buffer<T> d_items; | |
12c86877 BH |
59 | string d_help; |
60 | }; | |
61 | ||
dec69610 MTH |
62 | enum class StatType : uint8_t { |
63 | counter = 1, | |
64 | gauge = 2, | |
65 | }; | |
12c86877 BH |
66 | |
67 | //! use this to gather and query statistics | |
68 | class StatBag | |
69 | { | |
c2826d2e | 70 | map<string, std::unique_ptr<AtomicCounter>> d_stats; |
06f46d0a | 71 | map<string, string> d_keyDescriptions; |
dec69610 | 72 | map<string, StatType> d_statTypes; |
42b8372c RG |
73 | map<string, LockGuarded<StatRing<string, CIStringCompare> > > d_rings; |
74 | map<string, LockGuarded<StatRing<SComboAddress> > > d_comboRings; | |
75 | map<string, LockGuarded<StatRing<std::tuple<DNSName, QType> > > > d_dnsnameqtyperings; | |
f4319769 | 76 | typedef std::function<uint64_t(const std::string&)> func_t; |
e903706d | 77 | typedef map<string, func_t> funcstats_t; |
78 | funcstats_t d_funcstats; | |
12c86877 | 79 | bool d_doRings; |
dbbe10c3 | 80 | |
f3245c8c | 81 | std::set<string> d_blacklist; |
12c86877 | 82 | |
74e38357 RG |
83 | void registerRingStats(const string& name); |
84 | ||
12c86877 BH |
85 | public: |
86 | StatBag(); //!< Naked constructor. You need to declare keys before this class becomes useful | |
87 | ~StatBag(); | |
33b222ed | 88 | void declare(const string &key, const string &descrip="", StatType statType=StatType::counter); //!< Before you can store or access a key, you need to declare it |
dec69610 | 89 | void declare(const string &key, const string &descrip, func_t func, StatType statType); //!< Before you can store or access a key, you need to declare it |
12c86877 BH |
90 | |
91 | void declareRing(const string &name, const string &title, unsigned int size=10000); | |
4eb26e0f | 92 | void declareComboRing(const string &name, const string &help, unsigned int size=10000); |
f2b2f3ad | 93 | void declareDNSNameQTypeRing(const string &name, const string &help, unsigned int size=10000); |
bb3c3f50 | 94 | vector<pair<string, unsigned int> >getRing(const string &name); |
12c86877 | 95 | string getRingTitle(const string &name); |
4eb26e0f | 96 | void ringAccount(const char* name, const string &item) |
12c86877 | 97 | { |
42b8372c RG |
98 | if (d_doRings) { |
99 | auto it = d_rings.find(name); | |
100 | if (it == d_rings.end()) { | |
e746a2f6 | 101 | throw runtime_error("Attempting to account to nonexistent ring '"+std::string(name)+"'"); |
42b8372c | 102 | } |
4eb26e0f | 103 | |
42b8372c | 104 | it->second.lock()->account(item); |
4eb26e0f | 105 | } |
12c86877 | 106 | } |
4eb26e0f | 107 | void ringAccount(const char* name, const ComboAddress &item) |
108 | { | |
42b8372c RG |
109 | if (d_doRings) { |
110 | auto it = d_comboRings.find(name); | |
111 | if (it == d_comboRings.end()) { | |
e746a2f6 | 112 | throw runtime_error("Attempting to account to nonexistent comboRing '"+std::string(name)+"'"); |
42b8372c RG |
113 | } |
114 | it->second.lock()->account(item); | |
4eb26e0f | 115 | } |
116 | } | |
f2b2f3ad PL |
117 | void ringAccount(const char* name, const DNSName &dnsname, const QType &qtype) |
118 | { | |
42b8372c RG |
119 | if (d_doRings) { |
120 | auto it = d_dnsnameqtyperings.find(name); | |
121 | if (it == d_dnsnameqtyperings.end()) { | |
e746a2f6 | 122 | throw runtime_error("Attempting to account to nonexistent dnsname+qtype ring '"+std::string(name)+"'"); |
42b8372c | 123 | } |
0b0882f5 | 124 | it->second.lock()->account(std::tuple(dnsname, qtype)); |
f2b2f3ad PL |
125 | } |
126 | } | |
4eb26e0f | 127 | |
12c86877 BH |
128 | void doRings() |
129 | { | |
130 | d_doRings=true; | |
131 | } | |
132 | ||
42b8372c RG |
133 | vector<string>listRings() const; |
134 | bool ringExists(const string &name) const; | |
12c86877 | 135 | void resetRing(const string &name); |
bb3c3f50 | 136 | void resizeRing(const string &name, unsigned int newsize); |
74e38357 RG |
137 | uint64_t getRingSize(const string &name); |
138 | uint64_t getRingEntriesCount(const string &name); | |
12c86877 | 139 | |
3ef5fc26 | 140 | string directory(const string &prefix = ""); //!< Returns a list of all data stored. If prefix is given, only stats named with this prefix are returned. |
12c86877 BH |
141 | vector<string> getEntries(); //!< returns a vector with datums (items) |
142 | string getDescrip(const string &item); //!< Returns the description of this datum/item | |
dec69610 | 143 | StatType getStatType(const string &item); //!< Returns the stats type for the metrics endpoint |
12c86877 BH |
144 | void exists(const string &key); //!< call this function to throw an exception in case a key does not exist |
145 | inline void deposit(const string &key, int value); //!< increment the statistics behind this key by value amount | |
146 | inline void inc(const string &key); //!< increase this key's value by one | |
ac0995bb | 147 | void set(const string &key, unsigned long value); //!< set this key's value |
148 | unsigned long read(const string &key); //!< read the value behind this key | |
1566533a | 149 | AtomicCounter *getPointer(const string &key); //!< get a direct pointer to the value behind a key. Use this for high performance increments |
12c86877 | 150 | string getValueStr(const string &key); //!< read a value behind a key, and return it as a string |
f3245c8c | 151 | void blacklist(const string &str); |
dbbe10c3 PD |
152 | |
153 | bool d_allowRedeclare; // only set this true during tests, never in production code | |
12c86877 BH |
154 | }; |
155 | ||
156 | inline void StatBag::deposit(const string &key, int value) | |
157 | { | |
12c86877 BH |
158 | exists(key); |
159 | ||
160 | *d_stats[key]+=value; | |
12c86877 BH |
161 | } |
162 | ||
163 | inline void StatBag::inc(const string &key) | |
164 | { | |
42b8372c | 165 | deposit(key, 1); |
12c86877 | 166 | } |