]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/statbag.hh
Sphinx 1.8.0 seems broken, use any other version available instead
[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 */
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 36template<typename T, typename Comp=std::less<T> >
12c86877
BH
37class StatRing
38{
39public:
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 50private:
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
63class 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
74public:
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
127inline void StatBag::deposit(const string &key, int value)
128{
12c86877
BH
129 exists(key);
130
131 *d_stats[key]+=value;
12c86877
BH
132}
133
134inline void StatBag::inc(const string &key)
135{
136 deposit(key,1);
137}
138
139
140#endif /* STATBAG_HH */