source: nscp/modules/NSCAAgent/NSCAThread.cpp @ d76af81

0.4.00.4.10.4.2stable
Last change on this file since d76af81 was d76af81, checked in by Michael Medin <michael@…>, 5 years ago
  • Added some more error mesages to the NSCA module
    • Added support for srguments to LUA module. syntax: function debug (command, args) -- args is a table with all arguments
  • Property mode set to 100644
File size: 7.4 KB
Line 
1//////////////////////////////////////////////////////////////////////////
2// PDH Collector
3//
4// Functions from this file collects data from the PDH subsystem and stores
5// it for later use
6// *NOTICE* that this is done in a separate thread so threading issues has
7// to be handled. I handle threading issues in the CounterListener's get/
8// set accessors.
9//
10// Copyright (c) 2004 MySolutions NORDIC (http://www.medin.nu)
11//
12// Date: 2004-03-13
13// Author: Michael Medin - <michael@medin.name>
14//
15// This software is provided "AS IS", without a warranty of any kind.
16// You are free to use/modify this code but leave this header intact.
17//
18//////////////////////////////////////////////////////////////////////////
19
20#include "stdafx.h"
21#include "NSCAThread.h"
22#include <Settings.h>
23
24
25NSCAThread::NSCAThread() : hStopEvent_(NULL) {
26        checkIntervall_ = NSCModuleHelper::getSettingsInt(NSCA_AGENT_SECTION_TITLE, NSCA_INTERVAL, NSCA_INTERVAL_DEFAULT);
27        hostname_ = NSCModuleHelper::getSettingsString(NSCA_AGENT_SECTION_TITLE, NSCA_HOSTNAME, NSCA_HOSTNAME_DEFAULT);
28        nscahost_ = NSCModuleHelper::getSettingsString(NSCA_AGENT_SECTION_TITLE, NSCA_SERVER, NSCA_SERVER_DEFAULT);
29        nscaport_ = NSCModuleHelper::getSettingsInt(NSCA_AGENT_SECTION_TITLE, NSCA_PORT, NSCA_PORT_DEFAULT);
30        encryption_method_ = NSCModuleHelper::getSettingsInt(NSCA_AGENT_SECTION_TITLE, NSCA_ENCRYPTION, NSCA_ENCRYPTION_DEFAULT);
31        password_ = strEx::wstring_to_string(NSCModuleHelper::getSettingsString(NSCA_AGENT_SECTION_TITLE, NSCA_PASSWORD, NSCA_PASSWORD_DEFAULT));
32        std::list<std::wstring> items = NSCModuleHelper::getSettingsSection(NSCA_CMD_SECTION_TITLE);
33        for (std::list<std::wstring>::const_iterator cit = items.begin(); cit != items.end(); ++cit) {
34                addCommand(*cit);
35        }
36        if (hostname_.empty()) {
37                TCHAR *buf = new TCHAR[MAX_COMPUTERNAME_LENGTH + 2];
38                DWORD size = MAX_COMPUTERNAME_LENGTH+1;
39                if (!GetComputerName(buf, &size)) {
40                        NSC_LOG_ERROR(_T("Failed to get computer name: setting it to <unknown>"));
41                        hostname_ = _T("<unknown>");
42                } else {
43                        buf[size] = 0;
44                        hostname_ = buf;
45                        NSC_DEBUG_MSG_STD(_T("Autodetected hostname: ") + hostname_);
46                }
47                delete[] buf;
48        }
49}
50
51NSCAThread::~NSCAThread()
52{
53        if (hStopEvent_)
54                CloseHandle(hStopEvent_);
55}
56Command::Result Command::execute(std::wstring host) const {
57        Result result(host);
58        std::wstring msg;
59        std::wstring perf;
60        NSCAPI::nagiosReturn ret = NSCModuleHelper::InjectCommand(cmd_.c_str(), args_.getLen(), args_.get(), msg, perf);
61        result.service = alias_;
62        if (ret == NSCAPI::returnIgnored) {
63                result.result = _T("Command was not found: ") + cmd_;
64                result.code = NSCAPI::returnUNKNOWN;
65        } else if (ret == NSCAPI::returnInvalidBufferLen) {
66                result.result = _T("Result was to long: ") + cmd_;
67                result.code = NSCAPI::returnUNKNOWN;
68        } else {
69                result.result = msg + _T("|") + perf;
70                result.code = conv_code(ret);
71                if (result.result.length() >= NSCA_MAX_PLUGINOUTPUT_LENGTH) {
72                        NSC_LOG_ERROR(_T("NSCA return data truncated"));
73                        result.result = result.result.substr(0, NSCA_MAX_PLUGINOUTPUT_LENGTH-1);
74                }
75        }
76        return result;
77}
78
79
80void NSCAThread::addCommand(std::wstring key) {
81        std::wstring value = NSCModuleHelper::getSettingsString(NSCA_CMD_SECTION_TITLE, key, _T(""));
82        if ((key.length() > 4) && (key.substr(0,4) == _T("host")))
83                commands_.push_back(Command(_T(""), value));
84        else
85                commands_.push_back(Command(key, value));
86}
87
88
89/**
90* Thread that collects the data every "CHECK_INTERVAL" seconds.
91*
92* @param lpParameter Not used
93* @return thread exit status
94*
95* @author mickem
96*
97* @date 03-13-2004               
98*
99* @bug If we have "custom named" counters ?
100* @bug This whole concept needs work I think.
101*
102*/
103DWORD NSCAThread::threadProc(LPVOID lpParameter) {
104        hStopEvent_ = CreateEvent(NULL, TRUE, FALSE, NULL);
105        if (!hStopEvent_) {
106                NSC_LOG_ERROR_STD(_T("Create StopEvent failed: ") + error::lookup::last_error());
107                return 0;
108        }
109
110        srand( reinterpret_cast<int>(lpParameter) );
111
112        DWORD waitStatus = 0;
113        int drift = (checkIntervall_*rand())/RAND_MAX ;
114        NSC_DEBUG_MSG_STD(_T("Drifting: ") + strEx::itos(drift));
115        waitStatus = WaitForSingleObject(hStopEvent_, drift*1000);
116        if (waitStatus != WAIT_TIMEOUT)  {
117                NSC_LOG_ERROR_STD(_T("Drift failed... strange..."));
118        }
119        int remain = checkIntervall_;
120        while (((waitStatus = WaitForSingleObject(hStopEvent_, remain*1000)) == WAIT_TIMEOUT)) {
121                MutexLock mutex(mutexHandler);
122                if (!mutex.hasMutex())
123                        NSC_LOG_ERROR(_T("Failed to get Mutex!"));
124                else {
125                        __int64 start, stop;
126                        _time64( &start );
127
128                        std::list<Command::Result> results;
129                        for (std::list<Command>::const_iterator cit = commands_.begin(); cit != commands_.end(); ++cit) {
130                                results.push_back((*cit).execute(hostname_));
131                        }
132                        send(results);
133                        _time64( &stop );
134                        __int64 elapsed = stop-start;
135                        remain = checkIntervall_-static_cast<int>(elapsed);
136                        if (remain < 0)
137                                remain = 0;
138                }
139        }
140
141        if (waitStatus != WAIT_OBJECT_0) {
142                NSC_LOG_ERROR(_T("Something odd happened, terminating NSCA submission thread!"));
143        }
144
145        {
146                MutexLock mutex(mutexHandler);
147                if (!mutex.hasMutex()) {
148                        NSC_LOG_ERROR(_T("Failed to get Mute when closing thread!"));
149                }
150
151                if (!CloseHandle(hStopEvent_)) {
152                        NSC_LOG_ERROR_STD(_T("Failed to close stopEvent handle: ") + error::lookup::last_error());
153                } else
154                        hStopEvent_ = NULL;
155        }
156        return 0;
157}
158void NSCAThread::send(const std::list<Command::Result> &results) {
159        try {
160                nsca_encrypt crypt_inst;
161                simpleSocket::Socket socket(true);
162                simpleSocket::DataBuffer inc;
163                if (socket.connect(nscahost_, nscaport_) == SOCKET_ERROR) {
164                        NSC_LOG_ERROR_STD(_T("<<< Could not connect to: ") + nscahost_ + _T(":") + strEx::itos(nscaport_) + _T(" ") + socket.getLastError());
165                        return;
166                }
167                if (!socket.readAll(inc, sizeof(NSCAPacket::init_packet_struct), sizeof(NSCAPacket::init_packet_struct))) {
168                        NSC_LOG_ERROR_STD(_T("<<< Failed to read header from: ") + nscahost_ + _T(":") + strEx::itos(nscaport_) + _T(" ") + socket.getLastError());
169                        return;
170                }
171                NSCAPacket::init_packet_struct *packet_in = (NSCAPacket::init_packet_struct*) inc.getBuffer();
172                try {
173                        crypt_inst.encrypt_init(password_.c_str(),encryption_method_,reinterpret_cast<unsigned char*>(packet_in->iv));
174                } catch (nsca_encrypt::encryption_exception &e) {
175                        NSC_LOG_ERROR_STD(_T("<<< Failed to initalize encryption header: ") + e.getMessage());
176                        return;
177                } catch (...) {
178                        NSC_LOG_ERROR_STD(_T("<<< Failed to initalize encryption header!"));
179                        return;
180                }
181
182                try {
183                        for (std::list<Command::Result>::const_iterator cit = results.begin(); cit != results.end(); ++cit) {
184                                try {
185                                        socket.send((*cit).getBuffer(crypt_inst));
186                                } catch (NSCAPacket::NSCAException &e) {
187                                        NSC_LOG_ERROR_STD(_T("Failed to make command: ") + e.getMessage() );
188                                }
189                        }
190                } catch (nsca_encrypt::encryption_exception &e) {
191                        NSC_LOG_ERROR_STD(_T("<<< Failed to encrypt packet: ") + e.getMessage());
192                        return;
193                } catch (...) {
194                        NSC_LOG_ERROR_STD(_T("<<< Failed to encrypt packet!"));
195                        return;
196                }
197                socket.close();
198        } catch (...) {
199                NSC_LOG_ERROR_STD(_T("<<< Failed to initalize encryption header!"));
200                return;
201        }
202}
203
204
205
206/**
207* Request termination of the thread (waiting for thread termination is not handled)
208*/
209void NSCAThread::exitThread(void) {
210        if (hStopEvent_ == NULL) {
211                NSC_LOG_ERROR(_T("Stop event is not created!"));
212        } else {
213                if (!SetEvent(hStopEvent_)) {
214                        NSC_LOG_ERROR_STD(_T("SetStopEvent failed"));
215                }
216        }
217}
Note: See TracBrowser for help on using the repository browser.