source: nscp/include/PDHCollectors.h @ 394f7a1

0.4.00.4.10.4.2stable
Last change on this file since 394f7a1 was 394f7a1, checked in by Michael Medin <michael@…>, 5 years ago

+ Added propper output handling to process subsystem (now you can execute programs tat return "much" data.

+ Added select support for SSL_write (now you can send "any amount of data" to the (SSL) socket.

Since check_nrpe doesn't do this it wont work in that end, but still...

  • Property mode set to 100644
File size: 9.5 KB
Line 
1/**************************************************************************
2*   Copyright (C) 2004-2007 by Michael Medin <michael@medin.name>         *
3*                                                                         *
4*   This code is part of NSClient++ - http://trac.nakednuns.org/nscp      *
5*                                                                         *
6*   This program is free software; you can redistribute it and/or modify  *
7*   it under the terms of the GNU General Public License as published by  *
8*   the Free Software Foundation; either version 2 of the License, or     *
9*   (at your option) any later version.                                   *
10*                                                                         *
11*   This program is distributed in the hope that it will be useful,       *
12*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14*   GNU General Public License for more details.                          *
15*                                                                         *
16*   You should have received a copy of the GNU General Public License     *
17*   along with this program; if not, write to the                         *
18*   Free Software Foundation, Inc.,                                       *
19*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
20***************************************************************************/
21#pragma once
22
23#include <PDHCounter.h>
24#include <Mutex.h>
25namespace PDHCollectors {
26        const int format_large = 0x00000400;
27        const int format_long = 0x00000100;
28        const int format_double = 0x00000200;
29
30        class PDHException {
31                std::wstring error_;
32        public:
33                PDHException(std::wstring error) : error_(error) {}
34                std::wstring getError() const { return error_; }
35
36        };
37        class TPDHCounterMutex {
38        public:
39                virtual void lock() = 0;
40                virtual bool hasLock(bool silent = true) = 0;
41                virtual void release() = 0;
42        };
43
44        class PDHCounterNoMutex : public TPDHCounterMutex {
45        public:
46                void lock() {}
47                bool hasLock(bool silent = true) {
48                        return true;
49                }
50                void release() {}
51        };
52        class PDHCounterNormalMutex : public TPDHCounterMutex {
53                MutexHandler mutex_;
54                ManualMutexLock lock_;
55        public:
56                PDHCounterNormalMutex() : lock_(mutex_) {}
57                void lock() {
58                        lock_.lock();
59                }
60                bool hasLock(bool silent = true) {
61                        if (!silent && !lock_.hasMutex()) {
62                                std::wcout << _T("We never got the mutex... sorry...") << std::endl;
63                        }
64                        return lock_.hasMutex();
65                }
66                void release() {
67                        lock_.release();
68                }
69        };
70        class PDHCounterMutexHandler {
71        private:
72                TPDHCounterMutex *mutex_;       // Handle to the mutex object.
73        public:
74                /**
75                * Default c-tor.
76                * Waits for the mutex object.
77                * @param mutex The mutex to use
78                * @timeout The timeout before abandoning wait
79                */
80                PDHCounterMutexHandler(TPDHCounterMutex *mutex) : mutex_(mutex) {
81                        if (mutex == NULL) {
82                                std::wcout << _T("Error in mutex lock: ") << std::endl;
83                                mutex = NULL;
84                                return;
85                        }
86                        mutex->lock();
87                }
88                /**
89                * An attempt to simplify the has mutex thingy (don't know if it works, haven't tried it since I wrote this class a few years ago :)
90                * @return true if we have a mutex lock.
91                */
92                operator bool () const {
93                        return mutex_!=NULL&&mutex_->hasLock();
94                }
95                /**
96                * Check if we actually got the mutex (might have timed out)
97                * @return
98                */
99                bool hasLock(bool silent = true) const {
100                        return mutex_!=NULL&&mutex_->hasLock(silent);
101                }
102                /**
103                * Default d-tor.
104                * Release the mutex
105                */
106                virtual ~PDHCounterMutexHandler() {
107                        mutex_->release();
108                }
109        };
110
111        template <class TType, int TCollectionFormat, class TMutextHandler = PDHCounterNoMutex>
112        class StaticPDHCounterListener {};
113
114        template <class TType, class TMutextHandler>
115        class StaticPDHCounterListener<TType, format_double, TMutextHandler> : public PDH::PDHCounterListener {
116                TType value_;
117                TMutextHandler mutex_;
118        public:
119                StaticPDHCounterListener() : value_(0) {}
120                virtual void collect(const PDH::PDHCounter &counter) {
121                        PDHCounterMutexHandler mutex(&mutex_);
122                        if (!mutex.hasLock())
123                                return;
124                        value_ = counter.getDoubleValue();
125                }
126                void attach(const PDH::PDHCounter &counter){}
127                void detach(const PDH::PDHCounter &counter){}
128                TType getValue() {
129                        PDHCounterMutexHandler mutex(&mutex_);
130                        if (!mutex.hasLock())
131                                return -1;
132                        return value_;
133                }
134                DWORD getFormat() const {
135                        return format_double;
136                }
137        };
138
139        template <class TType, class TMutextHandler>
140        class StaticPDHCounterListener<TType, format_long, TMutextHandler> : public PDH::PDHCounterListener {
141                TType value_;
142                TMutextHandler mutex_;
143        public:
144                StaticPDHCounterListener() : value_(0) {}
145                virtual void collect(const PDH::PDHCounter &counter) {
146                        PDHCounterMutexHandler mutex(&mutex_);
147                        if (!mutex.hasLock())
148                                return;
149                        value_ = counter.getIntValue();
150                }
151                void attach(const PDH::PDHCounter &counter){}
152                void detach(const PDH::PDHCounter &counter){}
153                TType getValue() {
154                        PDHCounterMutexHandler mutex(&mutex_);
155                        if (!mutex.hasLock())
156                                return -1;
157                        return value_;
158                }
159                DWORD getFormat() const {
160                        return format_long;
161                }
162        };
163
164        template <class TType, class TMutextHandler>
165        class StaticPDHCounterListener<TType, format_large, TMutextHandler> : public PDH::PDHCounterListener {
166                TMutextHandler mutex_;
167                TType value_;
168        public:
169                StaticPDHCounterListener() : value_(0) {}
170                virtual void collect(const PDH::PDHCounter &counter) {
171                        PDHCounterMutexHandler mutex(&mutex_);
172                        if (!mutex.hasLock())
173                                return;
174                        value_ = counter.getInt64Value();
175                }
176                void attach(const PDH::PDHCounter &counter){}
177                void detach(const PDH::PDHCounter &counter){}
178                TType getValue() {
179                        PDHCounterMutexHandler mutex(&mutex_);
180                        if (!mutex.hasLock())
181                                return -1;
182                        return value_;
183                }
184                DWORD getFormat() const {
185                        return format_large;
186                }
187        };
188
189
190        template <class TType, class TMutextHandler>
191        class RoundINTPDHBufferListenerImpl : public PDH::PDHCounterListener {
192                TMutextHandler mutex_;
193                unsigned int length;
194                TType *buffer;
195                unsigned int current;
196        public:
197                RoundINTPDHBufferListenerImpl() : buffer(NULL), length(0), current(0) {}
198                RoundINTPDHBufferListenerImpl(int length_) : length(length_), current(0) {
199                        PDHCounterMutexHandler mutex(mutex_);
200                        if (!mutex.hasLock())
201                                return;
202                        buffer = new int[length];
203                        for (unsigned int i=0; i<length;i++)
204                                buffer[i] = 0;
205                }
206                virtual ~RoundINTPDHBufferListenerImpl() {
207                        PDHCounterMutexHandler mutex(&mutex_);
208                        if (!mutex.hasLock())
209                                return;
210                        delete [] buffer;
211                }
212
213                /**
214                * Resize the buffer to a new length
215                *
216                * @todo Make this copy the old buffer if there is one.
217                *
218                * @param newLength The new length
219                */
220                void resize(int newLength) {
221                        PDHCounterMutexHandler mutex(&mutex_);
222                        if (!mutex.hasLock())
223                                return;
224                        delete [] buffer;
225
226                        current = 0;
227                        length = newLength;
228
229                        buffer = new TType[length];
230                        for (unsigned int i=0; i<length;i++)
231                                buffer[i] = 0;
232
233                }
234
235                virtual void collect(const PDH::PDHCounter &counter) = 0;
236
237                void attach(const PDH::PDHCounter &counter){}
238                void detach(const PDH::PDHCounter &counter){}
239                void pushValue(TType value) {
240                        PDHCounterMutexHandler mutex(&mutex_);
241                        if (!mutex.hasLock())
242                                return;
243                        if (buffer == NULL)
244                                return;
245                        if (current >= length)
246                                return;
247                        buffer[current++] = value;
248                        if (current >= length)
249                                current = 0;
250                }
251                double getAvrage(unsigned int backItems) {
252                        PDHCounterMutexHandler mutex(&mutex_);
253                        if (!mutex.hasLock(true))
254                                throw PDHException(_T("Failed to get mutex :("));
255                        if ((backItems == 0) || (backItems >= length))
256                                return -1;
257                        double ret = 0;
258                        if (current >= backItems) {
259                                // Handle "whole" list.
260                                for (unsigned int i=current-backItems; i<current;i++)
261                                        ret += buffer[i];
262                        } else {
263                                // Handle split list.
264                                for (unsigned int i=0; i<current;i++)
265                                        ret += buffer[i];
266                                for (unsigned int i=length-backItems+current; i<length;i++)
267                                        ret += buffer[i];
268                        }
269                        return (ret/backItems);
270                }
271                inline unsigned int getLength() const {
272                        return length;
273                }
274        };
275
276
277        template <class TType, DWORD TCollectionFormat, class TMutextHandler = PDHCounterNoMutex>
278        class RoundINTPDHBufferListener : public RoundINTPDHBufferListenerImpl<TType, TMutextHandler> {
279        };
280
281        template <class TType, class TMutextHandler>
282        class RoundINTPDHBufferListener<TType, format_double, TMutextHandler> : public RoundINTPDHBufferListenerImpl<TType, TMutextHandler> {
283        public:
284                RoundINTPDHBufferListener() {}
285                RoundINTPDHBufferListener(int length) : RoundINTPDHBufferListenerImpl(length) {}
286
287                virtual void collect(const PDH::PDHCounter &counter) {
288                        pushValue(counter.getDoubleValue());
289                }
290                virtual DWORD getFormat() const {
291                        return format_double;
292                }
293        };
294
295        template <class TType, class TMutextHandler>
296        class RoundINTPDHBufferListener<TType, format_long, TMutextHandler> : public RoundINTPDHBufferListenerImpl<TType, TMutextHandler> {
297        public:
298                RoundINTPDHBufferListener() {}
299                RoundINTPDHBufferListener(int length) : RoundINTPDHBufferListenerImpl(length) {}
300
301                virtual void collect(const PDH::PDHCounter &counter) {
302                        pushValue(counter.getIntValue());
303                }
304                virtual DWORD getFormat() const {
305                        return format_long;
306                }
307        };
308
309        template <class TType, class TMutextHandler>
310        class RoundINTPDHBufferListener<TType, format_large, TMutextHandler> : public RoundINTPDHBufferListenerImpl<TType, TMutextHandler> {
311        public:
312                RoundINTPDHBufferListener() {}
313                RoundINTPDHBufferListener(int length) : RoundINTPDHBufferListenerImpl(length) {}
314
315                virtual void collect(const PDH::PDHCounter &counter) {
316                        pushValue(counter.getInt64Value());
317                }
318                virtual DWORD getFormat() const {
319                        return format_large;
320                }
321        };
322}
Note: See TracBrowser for help on using the repository browser.