source: nscp/modules/NSCAAgent/NSCAThread.cpp @ 9df626c

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

+ Added to NSCA truncates output when to long.

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