source: nscp/modules/NSCAAgent/NSCAThread.cpp @ 65ec1fa

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

+ Added hostname setting to [NSCA] section (must have been braindead when I did not add it before)

  • Property mode set to 100644
File size: 6.6 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        result.code = conv_code(ret);
63        if (ret == NSCAPI::returnIgnored) {
64                result.result = _T("Command was not found: ") + cmd_;
65        } else if (ret == NSCAPI::returnInvalidBufferLen) {
66                result.result = _T("Result was to long: ") + cmd_;
67        } else {
68                result.result = msg + _T("|") + perf;
69        }
70        NSC_LOG_MESSAGE_STD(_T("Result: ") + result.toString());
71        return result;
72}
73
74
75void NSCAThread::addCommand(std::wstring key) {
76        std::wstring value = NSCModuleHelper::getSettingsString(NSCA_CMD_SECTION_TITLE, key, _T(""));
77        commands_.push_back(Command(key, value));
78}
79
80
81/**
82* Thread that collects the data every "CHECK_INTERVAL" seconds.
83*
84* @param lpParameter Not used
85* @return thread exit status
86*
87* @author mickem
88*
89* @date 03-13-2004               
90*
91* @bug If we have "custom named" counters ?
92* @bug This whole concept needs work I think.
93*
94*/
95DWORD NSCAThread::threadProc(LPVOID lpParameter) {
96        hStopEvent_ = CreateEvent(NULL, TRUE, FALSE, NULL);
97        if (!hStopEvent_) {
98                NSC_LOG_ERROR_STD(_T("Create StopEvent failed: ") + error::lookup::last_error());
99                return 0;
100        }
101
102        DWORD waitStatus = 0;
103        int remain = checkIntervall_;
104        while (((waitStatus = WaitForSingleObject(hStopEvent_, remain*1000)) == WAIT_TIMEOUT)) {
105                MutexLock mutex(mutexHandler);
106                if (!mutex.hasMutex())
107                        NSC_LOG_ERROR(_T("Failed to get Mutex!"));
108                else {
109                        __int64 start, stop;
110                        _time64( &start );
111
112                        std::list<Command::Result> results;
113                        for (std::list<Command>::const_iterator cit = commands_.begin(); cit != commands_.end(); ++cit) {
114                                results.push_back((*cit).execute(hostname_));
115                        }
116                        send(results);
117                        _time64( &stop );
118                        __int64 elapsed = stop-start;
119                        remain = checkIntervall_-static_cast<int>(elapsed);
120                        if (remain < 0)
121                                remain = 0;
122                }
123        }
124
125        if (waitStatus != WAIT_OBJECT_0) {
126                NSC_LOG_ERROR(_T("Something odd happened, terminating NSCA submission thread!"));
127        }
128
129        {
130                MutexLock mutex(mutexHandler);
131                if (!mutex.hasMutex()) {
132                        NSC_LOG_ERROR(_T("Failed to get Mute when closing thread!"));
133                }
134
135                if (!CloseHandle(hStopEvent_)) {
136                        NSC_LOG_ERROR_STD(_T("Failed to close stopEvent handle: ") + error::lookup::last_error());
137                } else
138                        hStopEvent_ = NULL;
139        }
140        return 0;
141}
142void NSCAThread::send(const std::list<Command::Result> &results) {
143        try {
144                nsca_encrypt crypt_inst;
145                simpleSocket::Socket socket(true);
146                simpleSocket::DataBuffer inc;
147                if (socket.connect(nscahost_, nscaport_) == SOCKET_ERROR) {
148                        NSC_LOG_ERROR_STD(_T("<<< Could not connect to: ") + nscahost_ + _T(":") + strEx::itos(nscaport_));
149                        return;
150                }
151                if (!socket.readAll(inc, sizeof(NSCAPacket::init_packet_struct), sizeof(NSCAPacket::init_packet_struct))) {
152                        NSC_LOG_ERROR_STD(_T("<<< Failed to read header from: ") + nscahost_ + _T(":") + strEx::itos(nscaport_));
153                        return;
154                }
155                NSCAPacket::init_packet_struct *packet_in = (NSCAPacket::init_packet_struct*) inc.getBuffer();
156                try {
157                        crypt_inst.encrypt_init(password_.c_str(),encryption_method_,reinterpret_cast<unsigned char*>(packet_in->iv));
158                } catch (nsca_encrypt::encryption_exception &e) {
159                        NSC_LOG_ERROR_STD(_T("<<< Failed to initalize encryption header: ") + e.getMessage());
160                        return;
161                } catch (...) {
162                        NSC_LOG_ERROR_STD(_T("<<< Failed to initalize encryption header!"));
163                        return;
164                }
165
166                try {
167                        for (std::list<Command::Result>::const_iterator cit = results.begin(); cit != results.end(); ++cit) {
168                                socket.send((*cit).getBuffer(crypt_inst));
169                        }
170                } catch (nsca_encrypt::encryption_exception &e) {
171                        NSC_LOG_ERROR_STD(_T("<<< Failed to encrypt packet: ") + e.getMessage());
172                        return;
173                } catch (...) {
174                        NSC_LOG_ERROR_STD(_T("<<< Failed to encrypt packet!"));
175                        return;
176                }
177                socket.close();
178        } catch (...) {
179                NSC_LOG_ERROR_STD(_T("<<< Failed to initalize encryption header!"));
180                return;
181        }
182}
183
184
185
186/**
187* Request termination of the thread (waiting for thread termination is not handled)
188*/
189void NSCAThread::exitThread(void) {
190        if (hStopEvent_ == NULL) {
191                NSC_LOG_ERROR(_T("Stop event is not created!"));
192        } else {
193                if (!SetEvent(hStopEvent_)) {
194                        NSC_LOG_ERROR_STD(_T("SetStopEvent failed"));
195                }
196        }
197}
Note: See TracBrowser for help on using the repository browser.