source: nscp/trunk/include/PDHCounter.h @ e0705d4

Last change on this file since e0705d4 was e0705d4, checked in by Michael Medin <michael@…>, 8 years ago

Initial release

  • Property mode set to 100644
File size: 3.5 KB
Line 
1#pragma once
2
3#include <list>
4#include <pdh.h>
5#include <pdhmsg.h>
6#include <assert.h>
7
8
9namespace PDH {
10        class PDHException {
11        private:
12                std::string str_;
13                int errCode_;
14        public:
15                PDHException(std::string str, int errCode = 0) : str_(str), errCode_(errCode) {
16                }
17        };
18
19        class PDHCounter;
20        class PDHCounterListener {
21        public:
22                virtual void collect(const PDHCounter &counter) = 0;
23                virtual void attach(const PDHCounter &counter) = 0;
24                virtual void detach(const PDHCounter &counter) = 0;
25        };
26
27        class PDHCounter
28        {
29        private:
30                HCOUNTER hCounter_;
31                std::string name_;
32                PDH_FMT_COUNTERVALUE data_;
33                PDHCounterListener *listener_;
34
35        public:
36
37                PDHCounter(std::string name, PDHCounterListener *listener) : name_(name), listener_(listener), hCounter_(NULL){
38                }
39                virtual ~PDHCounter(void) {
40                        if (hCounter_ != NULL)
41                                remove();
42                }
43                const HCOUNTER getCounter() const {
44                        return hCounter_;
45                }
46                const std::string getName() const {
47                        return name_;
48                }
49                void addToQuery(HQUERY hQuery) {
50                        PDH_STATUS status;
51                        assert(hQuery != NULL);
52                        assert(hCounter_ == NULL);
53                        if (listener_)
54                                listener_->attach(*this);
55                        if ((status = PdhAddCounter(hQuery, name_.c_str(), 0, &hCounter_)) != ERROR_SUCCESS)
56                                throw PDHException("PdhOpenQuery failed", status);
57                        assert(hCounter_ != NULL);
58                }
59                void remove() {
60                        assert(hCounter_ != NULL);
61                        PDH_STATUS status;
62                        if (listener_)
63                                listener_->detach(*this);
64                        if ((status = PdhRemoveCounter(hCounter_)) != ERROR_SUCCESS)
65                                throw PDHException("PdhRemoveCounter failed", status);
66                        hCounter_ = NULL;
67                }
68                void collect() {
69                        assert(hCounter_ != NULL);
70                        PDH_STATUS status;
71                        if ((status = PdhGetFormattedCounterValue(hCounter_, PDH_FMT_LARGE , NULL, &data_)) != ERROR_SUCCESS)
72                                throw PDHException("PdhGetFormattedCounterValue failed", status);
73                        if (listener_)
74                                listener_->collect(*this);
75                }
76                __int64 getInt64Value() const {
77                        return data_.largeValue;
78                }
79                std::string getStringValue() const {
80                        return data_.AnsiStringValue;
81                }
82        };
83
84        class PDHQuery
85        {
86        private:
87                typedef std::list<PDHCounter*> CounterList;
88                CounterList counters_;
89                HQUERY hQuery_;
90        public:
91                PDHQuery() : hQuery_(NULL) {
92                }
93                virtual ~PDHQuery(void) {
94                        if (hQuery_)
95                                close();
96                        for (CounterList::iterator it = counters_.begin(); it != counters_.end(); it++) {
97                                delete (*it);
98                        }
99                        counters_.clear();
100                }
101
102                void addCounter(std::string name, PDHCounterListener *listener) {
103                        PDHCounter *counter = new PDHCounter(name, listener);
104                        counters_.push_back(counter);
105                }
106
107                void open() {
108                        assert(hQuery_ == NULL);
109                        PDH_STATUS status;
110                        if( (status = PdhOpenQuery( NULL, 0, &hQuery_ )) != ERROR_SUCCESS)
111                                throw PDHException("PdhOpenQuery failed", status);
112                        for (CounterList::iterator it = counters_.begin(); it != counters_.end(); it++) {
113                                (*it)->addToQuery(getQueryHandle());
114                        }
115                }
116
117                void close() {
118                        assert(hQuery_ != NULL);
119                        DWORD x = PDH_INVALID_HANDLE;
120                        PDH_STATUS status;
121                        for (CounterList::iterator it = counters_.begin(); it != counters_.end(); it++) {
122                                (*it)->remove();
123                        }
124                        if( (status = PdhCloseQuery(hQuery_)) != ERROR_SUCCESS)
125                                throw PDHException("PdhCloseQuery failed", status);
126                        hQuery_ = NULL;
127                }
128
129                void collect() {
130                        PDH_STATUS status;
131                        if ((status = PdhCollectQueryData(hQuery_)) != ERROR_SUCCESS)
132                                throw PDHException("PdhCollectQueryData failed: ", status);
133                        for (CounterList::iterator it = counters_.begin(); it != counters_.end(); it++) {
134                                (*it)->collect();
135                        }
136                }
137
138                HQUERY getQueryHandle() const {
139                        return hQuery_;
140                }
141        };
142
143
144}
Note: See TracBrowser for help on using the repository browser.