]>
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> | |
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" |
32 | #include <boost/circular_buffer.hpp> | |
12c86877 | 33 | |
662d5441 | 34 | |
35 | ||
4eb26e0f | 36 | template<typename T, typename Comp=std::less<T> > |
12c86877 BH |
37 | class StatRing |
38 | { | |
39 | public: | |
bb3c3f50 | 40 | StatRing(unsigned int size=10000); |
4eb26e0f | 41 | void account(const T &item); |
12c86877 | 42 | |
4eb26e0f | 43 | unsigned int getSize(); |
bb3c3f50 | 44 | void resize(unsigned int newsize); |
12c86877 BH |
45 | void reset(); |
46 | void setHelp(const string &str); | |
47 | string getHelp(); | |
4eb26e0f | 48 | |
49 | vector<pair<T, unsigned int> > get() const; | |
12c86877 | 50 | private: |
4eb26e0f | 51 | static bool popisort(const pair<T,int> &a, const pair<T,int> &b) |
52 | { | |
53 | return (a.second > b.second); | |
54 | } | |
55 | ||
56 | boost::circular_buffer<T> d_items; | |
57 | mutable pthread_mutex_t d_lock; | |
12c86877 BH |
58 | string d_help; |
59 | }; | |
60 | ||
61 | ||
62 | //! use this to gather and query statistics | |
63 | class StatBag | |
64 | { | |
1566533a | 65 | map<string, AtomicCounter *> d_stats; |
12c86877 | 66 | map<string, string> d_keyDescrips; |
4eb26e0f | 67 | map<string,StatRing<string> >d_rings; |
662d5441 | 68 | map<string,StatRing<SComboAddress> >d_comborings; |
e903706d | 69 | typedef boost::function<uint64_t(const std::string&)> func_t; |
70 | typedef map<string, func_t> funcstats_t; | |
71 | funcstats_t d_funcstats; | |
12c86877 | 72 | bool d_doRings; |
12c86877 BH |
73 | |
74 | public: | |
75 | StatBag(); //!< Naked constructor. You need to declare keys before this class becomes useful | |
76 | ~StatBag(); | |
77 | void declare(const string &key, const string &descrip=""); //!< Before you can store or access a key, you need to declare it | |
e903706d | 78 | 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 |
79 | |
80 | void declareRing(const string &name, const string &title, unsigned int size=10000); | |
4eb26e0f | 81 | void declareComboRing(const string &name, const string &help, unsigned int size=10000); |
bb3c3f50 | 82 | vector<pair<string, unsigned int> >getRing(const string &name); |
12c86877 | 83 | string getRingTitle(const string &name); |
4eb26e0f | 84 | void ringAccount(const char* name, const string &item) |
12c86877 | 85 | { |
4eb26e0f | 86 | if(d_doRings) { |
87 | if(!d_rings.count(name)) | |
75d28357 | 88 | throw runtime_error("Attempting to account to non-existent ring '"+std::string(name)+"'"); |
4eb26e0f | 89 | |
12c86877 | 90 | d_rings[name].account(item); |
4eb26e0f | 91 | } |
12c86877 | 92 | } |
4eb26e0f | 93 | void ringAccount(const char* name, const ComboAddress &item) |
94 | { | |
95 | if(d_doRings) { | |
96 | if(!d_comborings.count(name)) | |
75d28357 | 97 | throw runtime_error("Attempting to account to non-existent comboring '"+std::string(name)+"'"); |
4eb26e0f | 98 | d_comborings[name].account(item); |
99 | } | |
100 | } | |
101 | ||
12c86877 BH |
102 | void doRings() |
103 | { | |
104 | d_doRings=true; | |
105 | } | |
106 | ||
107 | vector<string>listRings(); | |
ef1439ff | 108 | bool ringExists(const string &name); |
12c86877 | 109 | void resetRing(const string &name); |
bb3c3f50 BH |
110 | void resizeRing(const string &name, unsigned int newsize); |
111 | unsigned int getRingSize(const string &name); | |
12c86877 BH |
112 | |
113 | string directory(); //!< Returns a list of all data stored | |
114 | vector<string> getEntries(); //!< returns a vector with datums (items) | |
115 | string getDescrip(const string &item); //!< Returns the description of this datum/item | |
116 | void exists(const string &key); //!< call this function to throw an exception in case a key does not exist | |
117 | inline void deposit(const string &key, int value); //!< increment the statistics behind this key by value amount | |
118 | inline void inc(const string &key); //!< increase this key's value by one | |
ac0995bb | 119 | void set(const string &key, unsigned long value); //!< set this key's value |
120 | unsigned long read(const string &key); //!< read the value behind this key | |
121 | unsigned long readZero(const string &key); //!< read the value behind this key, and zero it afterwards | |
1566533a | 122 | AtomicCounter *getPointer(const string &key); //!< get a direct pointer to the value behind a key. Use this for high performance increments |
12c86877 BH |
123 | string getValueStr(const string &key); //!< read a value behind a key, and return it as a string |
124 | string getValueStrZero(const string &key); //!< read a value behind a key, and return it as a string, and zero afterwards | |
12c86877 BH |
125 | }; |
126 | ||
127 | inline void StatBag::deposit(const string &key, int value) | |
128 | { | |
12c86877 BH |
129 | exists(key); |
130 | ||
131 | *d_stats[key]+=value; | |
12c86877 BH |
132 | } |
133 | ||
134 | inline void StatBag::inc(const string &key) | |
135 | { | |
136 | deposit(key,1); | |
137 | } | |
138 | ||
139 | ||
140 | #endif /* STATBAG_HH */ |