Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
Executable
+160
@@ -0,0 +1,160 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
|
||||
INCLUDE(MacroRTIDDSGen)
|
||||
INCLUDE(MacroCodeGenIdl)
|
||||
|
||||
SET(xml_FILE cmo_service.xml)
|
||||
|
||||
#
|
||||
# --- Library svcCmoCommon --------------------------------------------------------------------------------
|
||||
#
|
||||
SET(SRCS_common
|
||||
cmo_export.h
|
||||
logger.cpp
|
||||
logger.h
|
||||
)
|
||||
|
||||
# Generate cmo_enums.idl / cmo.idl
|
||||
CODEGEN_IDL_SVC(SRCS_common ${xml_FILE})
|
||||
# Generate cmo_db_impl.cpp/.h, cmo_db.h
|
||||
CODEGEN_DATABASE(SRCS_common ${xml_FILE})
|
||||
|
||||
# Generate *.cpp/*.hpp from idl
|
||||
RTIDDSGEN(SRCS_common cmo_enums.idl)
|
||||
RTIDDSGEN(SRCS_common cmo.idl)
|
||||
|
||||
# Generate cmo_dt[s,c]_types.h, cmo_ft[s,c]_types.h
|
||||
CODEGEN_TOPIC_TYPEDEFS(SRCS_common ${xml_FILE})
|
||||
# Generate cmo_[d|f]tc.h
|
||||
CODEGEN_CLIENT_TOPICS_IFC(SRCS_common ${xml_FILE})
|
||||
|
||||
NGL_ADD_LIBRARY(SV WS svcCmoCommon SHARED ${SRCS_common})
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(svcCmoCommon
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../
|
||||
)
|
||||
NGL_TARGET_LINK_LIBRARIES(svcCmoCommon
|
||||
PRIVATE
|
||||
RTI::nddscpp2
|
||||
PUBLIC
|
||||
Qt5::Core
|
||||
ddscore
|
||||
ngldb
|
||||
NGLLogger
|
||||
)
|
||||
NGL_INSTALL_TARGET(svcCmoCommon)
|
||||
|
||||
#
|
||||
# --- Library svcCmoClient --------------------------------------------------------------------------------
|
||||
#
|
||||
SET(SRCS_client
|
||||
cmo_export.h
|
||||
)
|
||||
# generate cmo_[d|f]tc.h, cmo_[d|f]tc_impl.[cpp|h]
|
||||
CODEGEN_CLIENT_TOPICS_IMPL(SRCS_client ${xml_FILE})
|
||||
|
||||
NGL_ADD_LIBRARY(SV WS svcCmoClient SHARED ${SRCS_client})
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(svcCmoClient
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../
|
||||
)
|
||||
|
||||
NGL_TARGET_LINK_LIBRARIES(svcCmoClient
|
||||
PRIVATE
|
||||
RTI::nddscpp2
|
||||
ddsconnector
|
||||
PUBLIC
|
||||
svcCmoCommon
|
||||
ddsftc
|
||||
ngldb
|
||||
)
|
||||
NGL_INSTALL_TARGET(svcCmoClient)
|
||||
|
||||
#
|
||||
# --- Library svcCmoServer --------------------------------------------------------------------------------
|
||||
#
|
||||
SET(SRCS_server
|
||||
cmo_export.h
|
||||
)
|
||||
# generate cmo_[d|f]ts.h, cmo_[d|f]ts_impl.[cpp|h]
|
||||
CODEGEN_SERVER_TOPICS(SRCS_server ${xml_FILE})
|
||||
|
||||
NGL_ADD_LIBRARY(SV svcCmoServer SHARED ${SRCS_server})
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(svcCmoServer
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../
|
||||
)
|
||||
|
||||
NGL_TARGET_LINK_LIBRARIES(svcCmoServer
|
||||
PRIVATE
|
||||
RTI::nddscpp2
|
||||
ddsconnector
|
||||
ddsfts
|
||||
ngldb
|
||||
PUBLIC
|
||||
svcCmoCommon
|
||||
)
|
||||
NGL_INSTALL_TARGET(svcCmoServer)
|
||||
|
||||
#
|
||||
# --- Topic Type Plugin --------------------------------------------------------------
|
||||
#
|
||||
CREATE_TOPIC_TYPE_PLUGIN(${xml_FILE})
|
||||
|
||||
#
|
||||
# --- Executable svcComponentMonitor (sCMO) -------------------------------------------------
|
||||
#
|
||||
SET(SRCS_exe
|
||||
main.cpp
|
||||
main_handler.cpp
|
||||
main_handler.h
|
||||
initialization.cpp
|
||||
initialization.cpp
|
||||
dds_handler.cpp
|
||||
dds_handler.h
|
||||
settings.cpp
|
||||
settings.h
|
||||
component_status_handler.cpp
|
||||
component_status_handler.h
|
||||
checkmk_handler.cpp
|
||||
checkmk_handler.h
|
||||
checkmk_handler_schedule_check.cpp
|
||||
checkmk_handler_schedule_check.h
|
||||
${xml_FILE}
|
||||
)
|
||||
|
||||
# Generate cmo.sql, cmo.xml
|
||||
CODEGEN_SQL(SRCS_exe ${xml_FILE})
|
||||
|
||||
NGL_ADD_SVC_ICON(SRCS_exe)
|
||||
NGL_ADD_EXECUTABLE(SV svcComponentMonitor ${SRCS_exe})
|
||||
NGL_TARGET_LINK_LIBRARIES(svcComponentMonitor
|
||||
Qt5::Core
|
||||
Qt5::Network
|
||||
svcCmoCommon
|
||||
svcCmoServer
|
||||
svcCoreClient # pacemaker
|
||||
ddsconnector
|
||||
nglsettings
|
||||
ProjectConfig
|
||||
LtsCommandLineParser
|
||||
NGLLogger
|
||||
nglcoreapplication
|
||||
ngltools
|
||||
svcIsmClient
|
||||
)
|
||||
NGL_INSTALL_TARGET(svcComponentMonitor)
|
||||
NGL_INSTALL(SV FILES log4cxx_cmo.props DESTINATION bin)
|
||||
NGL_ADD_TARGET_LINK(svcComponentMonitor sCMO)
|
||||
|
||||
# Uncomment if necessary
|
||||
#ADD_SUBDIRECTORY(UnitTests)
|
||||
#ADD_SUBDIRECTORY(ModuleTests)
|
||||
|
||||
+298
@@ -0,0 +1,298 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Handler for CheckmkHandler
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Norbert Thoden, 2022-11-30
|
||||
*/
|
||||
|
||||
#include "checkmk_handler.h"
|
||||
|
||||
#include <QTimer>
|
||||
#include <QHostAddress>
|
||||
#include <QDateTime>
|
||||
|
||||
/*
|
||||
Laut Thore:
|
||||
auf deinem Rechner muss netcat (nc) installiert sein:
|
||||
zypper install netcat
|
||||
|
||||
Beispiel:
|
||||
printf "GET hosts\nColumns: name state\nOutputFormat: json\nFilter: name ~ AHTC\nFilter: name ~ REF\n" | nc 10.198.80.58 6557
|
||||
|
||||
printf "GET hosts\nColumns: name state last_check\nOutputFormat: json\n\n" | nc 10.198.80.58 6557
|
||||
|
||||
ctc@CTCAP15:~/TDS/TDS-source-fb22_09_resmgmt2.0-clean> printf "GET hosts\nColumns: name state\nOutputFormat: json\nFilter: name ~ AHTC\n\n" | nc 10.198.80.58 6557
|
||||
[["AHTC_Tetra",0],
|
||||
["ENT_AHTC_CCSAWS01",0],
|
||||
["ENT_AHTC_CCSDNS01",0],
|
||||
["ENT_AHTC_EXCAVS01",0],
|
||||
["ENT_AHTC_EXCDBS01",0],
|
||||
["ENT_AHTC_EXCTDS01",1],
|
||||
["RC_AHTC_CCSAWS01",0],
|
||||
["RC_AHTC_CCSDNS01",0],
|
||||
["RC_AHTC_EXCAVS01",0],
|
||||
["RC_AHTC_EXCDBS01",0],
|
||||
["RC_AHTC_EXCTDS01",0],
|
||||
["REF_AHTC_CCSAWS01",0],
|
||||
["REF_AHTC_CCSDNS01",0],
|
||||
["REF_AHTC_EXCAVS01",1],
|
||||
["REF_AHTC_EXCDBS01",1],
|
||||
["REF_AHTC_EXCOWS02",0],
|
||||
["REF_AHTC_EXCTDS01",1]]
|
||||
ctc@CTCAP15:~/TDS/TDS-source-fb22_09_resmgmt2.0-clean>
|
||||
|
||||
|
||||
// Logfile
|
||||
|
||||
ssh rme@10.198.80.58 !Mou…..
|
||||
|
||||
su - !Mou….
|
||||
|
||||
tail -f /omd/sites/Referenzanlagen/var/nagios/livestatus.log
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
namespace ComponentMonitor
|
||||
{
|
||||
|
||||
CheckmkHandler::CheckmkHandler()
|
||||
: QObject()
|
||||
, m_socket(new QTcpSocket(this))
|
||||
, m_logger(getLogger("CheckmkHandler"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
CheckmkHandler::~CheckmkHandler()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (m_timer)
|
||||
m_timer->stop();
|
||||
delete m_socket;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool CheckmkHandler::initialize(const QString &checkMkServerHostname, int checkMkServerPort,
|
||||
int checkIntervalSec)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " , hostname=" << checkMkServerHostname
|
||||
<< " , port=" << checkMkServerPort
|
||||
<< " , m_checkIntervalSec=" << checkIntervalSec;
|
||||
|
||||
m_checkMkHost = checkMkServerHostname;
|
||||
m_checkMkPort = checkMkServerPort;
|
||||
m_checkIntervalSec = checkIntervalSec;
|
||||
|
||||
if (!m_timer)
|
||||
{
|
||||
m_timer = new QTimer(this);
|
||||
m_timer->setInterval(m_checkIntervalSec * 1000);
|
||||
connect(m_timer, &QTimer::timeout, this, &CheckmkHandler::onTimeout);
|
||||
}
|
||||
|
||||
connect(m_socket, &QTcpSocket::stateChanged, this, &CheckmkHandler::onStateChanged);
|
||||
connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error),
|
||||
this, &CheckmkHandler::onSocketError);
|
||||
|
||||
connect(m_socket, &QTcpSocket::connected,
|
||||
this, &CheckmkHandler::onConnected);
|
||||
connect(m_socket, &QTcpSocket::readyRead, this, &CheckmkHandler::readData);
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
void CheckmkHandler::run()
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_timer->start();
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void CheckmkHandler::stop()
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_timer->stop();
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void CheckmkHandler::onTimeout()
|
||||
{
|
||||
if (m_highFrequencyCheck>=0)
|
||||
{
|
||||
--m_highFrequencyCheck;
|
||||
m_timer->setInterval(2*1000);
|
||||
} else {
|
||||
m_timer->setInterval(m_checkIntervalSec*1000);
|
||||
}
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " Timeout, m_highFrequencyCheck=" << m_highFrequencyCheck
|
||||
<< ", current Interval=" << m_timer->interval() << " [msec]";
|
||||
|
||||
if (m_socket->state() == QAbstractSocket::SocketState::ConnectedState)
|
||||
{
|
||||
writeGetStateRequest();
|
||||
} else {
|
||||
doConnect();
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckmkHandler::doConnect()
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " START, (int)m_socket->state()=" << (int)m_socket->state();
|
||||
|
||||
// weird, but most likely we have to connect every time after 'GET hosts\nColumns: name state last....'
|
||||
m_socket->connectToHost(m_checkMkHost, m_checkMkPort);
|
||||
if (!m_socket->waitForConnected(5000))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " Could not (re)open tcp destination " << m_checkMkHost << ":" << m_checkMkPort << ", error: " << m_socket->errorString();
|
||||
return false;
|
||||
}
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " (Re)openend tcp destination " << m_checkMkHost << ":" << m_checkMkPort;
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
void CheckmkHandler::onImmediateGetStateRequested()
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
// perform 3 'GET hosts ...' assuming the test results will be updated within that time (3*2000msec)
|
||||
m_highFrequencyCheck = 3;
|
||||
onTimeout();
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool CheckmkHandler::writeGetStateRequest()
|
||||
{
|
||||
if (!m_socket->isOpen())
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " socket not open";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Doku :
|
||||
// lq "GET columns\nFilter: table = hosts\nColumns: name description
|
||||
// printf "GET columns\nFilter: table = hosts\nColumns: name description\n\n" | nc 10.198.80.58 6557
|
||||
// ..
|
||||
// state;The current state of the host (0: up, 1: down, 2: unreachable)
|
||||
// ..
|
||||
// last_check;Time of the last check (Unix timestamp)
|
||||
// : Doku
|
||||
|
||||
|
||||
|
||||
// printf "GET hosts\nColumns: name state\nOutputFormat: json\nFilter: name ~ AHTC\nFilter: name ~ REF\n\n" | nc 10.198.80.58 6557
|
||||
// int bWritten = m_socket->write("GET hosts\nColumns: name state\nOutputFormat: json\n\n");
|
||||
// int bWritten = m_socket->write("GET hosts\nColumns: name state\nOutputFormat: json\nFilter: name ~ AHTC\n\n");
|
||||
// int bWritten = m_socket->write("GET hosts\nColumns: name state last_state_change\nFilter: name ~ AHTC\n\n");
|
||||
|
||||
// add 'KeepAlive' to command -> still getting RemoteHostClosedError
|
||||
// int bWritten = m_socket->write("GET hosts\nColumns: name state last_check KeepAlive on\n\n");
|
||||
|
||||
|
||||
//int bWritten = m_socket->write("GET hosts\nColumns: name state last_check\n\n");
|
||||
|
||||
// use KeepAlive AND ResponseHeader to keep the connection (avoid disconnection)
|
||||
// "Kombinieren Sie KeepAlive immer mit dem ResponseHeader, um"
|
||||
// https://docs.checkmk.com/latest/de/livestatus.html#response_header
|
||||
const char* cmdCheck = "GET hosts\nResponseHeader: fixed16\nColumns: name state last_check \nKeepAlive: on\n\n";
|
||||
int bWritten = m_socket->write(cmdCheck);
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " cmdCheck= '" << cmdCheck << "'";
|
||||
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " bWritten= " << bWritten;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CheckmkHandler::readData()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
|
||||
|
||||
while (m_socket->canReadLine())
|
||||
processLine(m_socket->readLine().trimmed());
|
||||
}
|
||||
|
||||
void CheckmkHandler::onConnected()
|
||||
{
|
||||
writeGetStateRequest();
|
||||
}
|
||||
|
||||
void CheckmkHandler::onStateChanged(const QAbstractSocket::SocketState &newState)
|
||||
{
|
||||
qDebug() << "CheckmkHandler: SocketState changed to: " << newState;
|
||||
}
|
||||
|
||||
|
||||
void CheckmkHandler::onSocketError(const QAbstractSocket::SocketError &socketError)
|
||||
{
|
||||
qCritical() << "CheckmkHandler: Error occured: " << socketError;
|
||||
}
|
||||
|
||||
bool CheckmkHandler::processLine(const QByteArray &line)
|
||||
{
|
||||
// like RC_AHTC_CCSAWS01;0
|
||||
|
||||
if (line.isEmpty())
|
||||
return false;
|
||||
|
||||
QString str = QString::fromUtf8(line);
|
||||
QStringList sl = str.split(QStringLiteral(";"));
|
||||
|
||||
if (sl.size() < 2)
|
||||
{
|
||||
if (str.startsWith(QStringLiteral("200")))
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " size to small " << sl.size()
|
||||
<< ", line='" << str << "'";
|
||||
else
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION << " size to small " << sl.size()
|
||||
<< ", line='" << str << "'";
|
||||
return false;
|
||||
}
|
||||
|
||||
QString name = sl.value(0);
|
||||
name = name.section(QLatin1Char('.'), 0, 0); // ahtcENT.defence-elec.de -> ahtcENT
|
||||
|
||||
|
||||
//#ifdef LTS_DEBUG
|
||||
// // Just for Debugging purpose (server at 10.198.80.58 6557)
|
||||
// if (name.compare(QStringLiteral("REF_GUEZ_ECVMADB01")) == 0)
|
||||
// name = QStringLiteral("UBEBSM0001"); //
|
||||
//#endif // LTS_DEBUG
|
||||
|
||||
|
||||
// state;The current state of the host (0: up, 1: down, 2: unreachable)
|
||||
// state;The current state of the host (0: up, 1: down, 2: unreachable)
|
||||
// state;The current state of the host (0: up, 1: down, 2: unreachable)
|
||||
QString stateStr = sl.value(1);
|
||||
int stateInt = stateStr.toInt();
|
||||
bool reachable = stateInt == 0;
|
||||
|
||||
long long lastCheck = 0;
|
||||
|
||||
if (sl.size() >= 3)
|
||||
{
|
||||
QString lastCheckStr = sl.value(2);
|
||||
lastCheck = lastCheckStr.toLongLong();
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " name: '" << name << "'"
|
||||
<< ", stateInt: '" << stateInt << "'"
|
||||
<< ", reachable: '" << reachable << "'"
|
||||
<< ", lastCheck: '" << lastCheck << "'"
|
||||
;
|
||||
|
||||
emit newState(name, reachable, lastCheck);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ComponentMonitor
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Handler for CheckmkHandler
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Norbert Thoden, SLSE, 2022-11-03
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "logger.h"
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <ComponentMonitor/cmo.hpp>
|
||||
#include <QTimer>
|
||||
#include <QTcpSocket>
|
||||
#include <QDataStream>
|
||||
|
||||
namespace DDSConnector
|
||||
{
|
||||
class DdsConnector;
|
||||
}
|
||||
|
||||
namespace ComponentMonitor
|
||||
{
|
||||
class DdsHandler;
|
||||
|
||||
// Maybe helpful:
|
||||
// https://docs.checkmk.com/latest/de/livestatus.html
|
||||
// https://docs.checkmk.com/latest/de/livestatus_references.html
|
||||
// https://github.com/sileht/check_mk/blob/master/livestatus/api/python/livestatus.py
|
||||
|
||||
class CheckmkHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CheckmkHandler();
|
||||
~CheckmkHandler();
|
||||
|
||||
bool initialize(const QString &checkMkServerHostname, int checkMkServerPort, int checkIntervalSec);
|
||||
|
||||
void run();
|
||||
void stop();
|
||||
bool doConnect();
|
||||
|
||||
public Q_SLOTS:
|
||||
void onImmediateGetStateRequested();
|
||||
|
||||
private:
|
||||
bool writeGetStateRequest();
|
||||
|
||||
Q_SIGNALS:
|
||||
void newState(QString hostname, bool state, long long lastCheck);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onTimeout();
|
||||
void readData();
|
||||
void onConnected();
|
||||
void onStateChanged(const QAbstractSocket::SocketState &newState);
|
||||
void onSocketError(const QAbstractSocket::SocketError &socketError);
|
||||
|
||||
|
||||
protected:
|
||||
bool processLine(const QByteArray &line);
|
||||
|
||||
private:
|
||||
// checkMkServer
|
||||
QString m_checkMkHost;
|
||||
quint16 m_checkMkPort{0};
|
||||
int m_checkIntervalSec{60};
|
||||
int m_highFrequencyCheck{-1};
|
||||
QTimer *m_timer{nullptr};
|
||||
|
||||
QTcpSocket *m_socket{nullptr};
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
|
||||
} // namespace ComponentMonitor
|
||||
@@ -0,0 +1,263 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Handler for CheckmkHandlerScheduleCheck
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Norbert Thoden, 2022-11-30
|
||||
*/
|
||||
|
||||
#include "checkmk_handler_schedule_check.h"
|
||||
|
||||
#include <QTimer>
|
||||
#include <QHostAddress>
|
||||
#include <QDateTime>
|
||||
|
||||
namespace ComponentMonitor
|
||||
{
|
||||
|
||||
CheckmkHandlerScheduleCheck::CheckmkHandlerScheduleCheck(const std::shared_ptr<DdsHandler> &ddsHandler)
|
||||
: QObject()
|
||||
, TriggerUpdateRequestHandler(ddsHandler->fts())
|
||||
, m_socket(new QTcpSocket(this))
|
||||
, m_ddsHandler(ddsHandler)
|
||||
, m_logger(getLogger("CheckmkHandlerScheduleCheck"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
CheckmkHandlerScheduleCheck::~CheckmkHandlerScheduleCheck()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (m_timer)
|
||||
m_timer->stop();
|
||||
delete m_socket;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool CheckmkHandlerScheduleCheck::initialize(const QString &checkMkServerHostname, int checkMkServerPort)
|
||||
{
|
||||
NOTICE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< " , hostname=" << checkMkServerHostname
|
||||
<< " , port=" << checkMkServerPort;
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " ddsHandler referenced";
|
||||
|
||||
m_checkMkHost = checkMkServerHostname;
|
||||
m_checkMkPort = checkMkServerPort;
|
||||
|
||||
if (!m_timer)
|
||||
{
|
||||
m_timer = new QTimer(this);
|
||||
m_timer->setSingleShot(true);
|
||||
connect(m_timer, &QTimer::timeout, this, &CheckmkHandlerScheduleCheck::onTimeout);
|
||||
}
|
||||
|
||||
connect(m_socket, &QTcpSocket::stateChanged, this, &CheckmkHandlerScheduleCheck::onStateChanged);
|
||||
connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error),
|
||||
this, &CheckmkHandlerScheduleCheck::onSocketError);
|
||||
|
||||
connect(m_socket, &QTcpSocket::connected,
|
||||
this, &CheckmkHandlerScheduleCheck::onConnected);
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
void CheckmkHandlerScheduleCheck::run(int timoutMsec)
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " START, timoutMsec=" << timoutMsec;
|
||||
m_timer->start(timoutMsec);
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void CheckmkHandlerScheduleCheck::stop()
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_timer->stop();
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void CheckmkHandlerScheduleCheck::onTimeout()
|
||||
{
|
||||
if (m_socket->state() == QAbstractSocket::SocketState::ConnectedState)
|
||||
{
|
||||
writeScheduleUpdateRequest();
|
||||
} else {
|
||||
doConnect();
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckmkHandlerScheduleCheck::doConnect()
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " START, (int)m_socket->state()=" << (int)m_socket->state();
|
||||
|
||||
// (for 'COMMAND [%1] SCHEDULE_FORCED_HOST_CHECK...' the socket connection should not be closed)
|
||||
// But maybe the CheckMk-Server ist restarted:
|
||||
|
||||
m_socket->connectToHost(m_checkMkHost, m_checkMkPort);
|
||||
if (!m_socket->waitForConnected(5000))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " Could not (re)open tcp destination " << m_checkMkHost << ":" << m_checkMkPort << ", error: " << m_socket->errorString();
|
||||
return false;
|
||||
}
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " (Re)openend tcp destination " << m_checkMkHost << ":" << m_checkMkPort;
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
void CheckmkHandlerScheduleCheck::addScheduleCheckHostnames(const QStringList &hostnames)
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " hostnames: " << hostnames.join(QStringLiteral(";"));
|
||||
m_scheduleCheckHostnames += hostnames;
|
||||
}
|
||||
|
||||
bool CheckmkHandlerScheduleCheck::writeScheduleUpdateRequest()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " state " << (int)m_socket->state()
|
||||
<< ", isOpen " << m_socket->isOpen();
|
||||
|
||||
if (!m_socket->isOpen() || (m_socket->state() != QAbstractSocket::SocketState::ConnectedState))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " socket not open or connected "
|
||||
<< " host/port: " << m_checkMkHost << ":" << m_checkMkPort;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_scheduleCheckHostnames.isEmpty())
|
||||
return false;
|
||||
|
||||
// avoid duplicates:
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
const QSet<QString> hosts = QSet<QString>::fromList(m_scheduleCheckHostnames);
|
||||
#else
|
||||
const QSet<QString> hosts(m_scheduleCheckHostnames.begin(), m_scheduleCheckHostnames.end());
|
||||
#endif // QT_VERSION
|
||||
|
||||
int bWrittenAll = 0;
|
||||
for (const QString &hostname : qAsConst(hosts))
|
||||
{
|
||||
qint64 now = QDateTime::currentSecsSinceEpoch();
|
||||
// CheckMK is is configured with <HOSTNAME> -> toUpper()
|
||||
const QString cmd = QString(QStringLiteral("COMMAND [%1] SCHEDULE_FORCED_HOST_CHECK;%2;%3")).arg(now).arg(hostname.toUpper()).arg(now);
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " cmd= '" << cmd << "'";
|
||||
int bWritten = m_socket->write(cmd.toUtf8()) + m_socket->write("\n\n");
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " bWritten= " << bWritten;
|
||||
bWrittenAll += bWritten;
|
||||
} // for
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " bWrittenAll= " << bWrittenAll;
|
||||
|
||||
// avoid scheduling more than once -> clear
|
||||
m_scheduleCheckHostnames.clear();
|
||||
|
||||
//
|
||||
// avoid hanging application, since slot (CheckmkHandler::onImmediateGetStateRequested
|
||||
// most likely has to reconnect...
|
||||
QTimer::singleShot(100, this, [this](){
|
||||
emit newCheckScheduled();
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CheckmkHandlerScheduleCheck::onConnected()
|
||||
{
|
||||
writeScheduleUpdateRequest();
|
||||
}
|
||||
|
||||
void CheckmkHandlerScheduleCheck::onStateChanged(const QAbstractSocket::SocketState &newState)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " SocketState changed to: " << newState;
|
||||
qInfo() << " CheckmkHandlerScheduleCheck: SocketState changed to: " << newState;
|
||||
}
|
||||
|
||||
|
||||
void CheckmkHandlerScheduleCheck::onSocketError(const QAbstractSocket::SocketError &socketError)
|
||||
{
|
||||
qCritical() << "CheckmkHandlerScheduleCheck: Error occured: " << socketError;
|
||||
}
|
||||
|
||||
void CheckmkHandlerScheduleCheck::onTriggerUpdateRequest(const rti::core::SampleIdentity &cookie, const TriggerUpdate &request)
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " request=" << request;
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " m_socket->state=" << (int)m_socket->state();
|
||||
|
||||
|
||||
// if ((m_socket->state() != QAbstractSocket::SocketState::ConnectedState))
|
||||
// {
|
||||
// ERROR_LOG(m_logger) << LOGFUNCTION << " not connected";
|
||||
// Core::FunctionReplyObject ret(0); // no request.id()
|
||||
// ret.setId(-1);
|
||||
// ret.setStr(tr_lts("dds", "No Connection to CheckMK"));
|
||||
// if (m_ddsHandler && m_ddsHandler->fts())
|
||||
// m_ddsHandler->fts()->triggerUpdateReply(cookie, ret);
|
||||
// return;
|
||||
// }
|
||||
|
||||
const std::vector< std::string >& hostnames = request.hostnames();
|
||||
|
||||
QStringList sl;
|
||||
sl.reserve(hostnames.size());
|
||||
|
||||
QString temp;
|
||||
for (const std::string &str : qAsConst(hostnames))
|
||||
{
|
||||
temp = QString::fromStdString(str);
|
||||
if (!sl.contains(temp))
|
||||
sl.push_back(temp);
|
||||
} // for
|
||||
|
||||
// add to list
|
||||
addScheduleCheckHostnames(sl);
|
||||
|
||||
|
||||
// updateLastCheckTimeDirect :
|
||||
// BEFORE writeScheduleUpdateRequest to avoid race condition!
|
||||
|
||||
const qint64 now = QDateTime::currentSecsSinceEpoch();
|
||||
emit updateLastCheckTimeDirect(sl, now);
|
||||
|
||||
// : updateLastCheckTimeDirect
|
||||
|
||||
|
||||
Core::FunctionReplyObject ret(0); // no request.id()
|
||||
const bool connected = m_socket->state() == QAbstractSocket::SocketState::ConnectedState;
|
||||
if (connected)
|
||||
{
|
||||
bool writeOk = writeScheduleUpdateRequest();
|
||||
if (!writeOk)
|
||||
{
|
||||
ret.setId(-1);
|
||||
ret.setStr(tr_lts("dds", "WriteError on CheckMk"));
|
||||
}
|
||||
} else {
|
||||
// GUEZE-1653 MsgBox 'cmd queued due to lost connection to CheckMk' vermeiden
|
||||
WARNING_LOG(m_logger) << LOGFUNCTION << " socket not connected"
|
||||
<< ", (int)m_socket->state()=" << (int)m_socket->state()
|
||||
<< ", destination " << m_checkMkHost << ":" << m_checkMkPort
|
||||
<< ", -> queued cmd/request: " << request;
|
||||
// ret.setId(-1);
|
||||
// ret.setStr(tr_lts("dds", "cmd queued due to lost connection to CheckMk"));
|
||||
}
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " m_ddsHandler = " << m_ddsHandler;
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " m_ddsHandler->fts() = " << m_ddsHandler->fts();
|
||||
|
||||
if (m_ddsHandler && m_ddsHandler->fts())
|
||||
m_ddsHandler->fts()->triggerUpdateReply(cookie, ret);
|
||||
else
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no m_ddsHandler or m_ddsHandler->fts()";
|
||||
|
||||
|
||||
if (!connected)
|
||||
doConnect();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ComponentMonitor
|
||||
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Handler for CheckmkHandlerScheduleCheck
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Norbert Thoden, SLSE, 2022-11-03
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "dds_handler.h"
|
||||
#include "logger.h"
|
||||
#include <ComponentMonitor/cmo_fts.h>
|
||||
#include <ComponentMonitor/cmo.hpp>
|
||||
#include <QTimer>
|
||||
#include <QTcpSocket>
|
||||
#include <QDataStream>
|
||||
|
||||
namespace DDSConnector
|
||||
{
|
||||
class DdsConnector;
|
||||
}
|
||||
|
||||
namespace ComponentMonitor
|
||||
{
|
||||
class DdsHandler;
|
||||
|
||||
// Maybe helpful:
|
||||
// https://docs.checkmk.com/latest/de/livestatus.html
|
||||
// https://docs.checkmk.com/latest/de/livestatus_references.html
|
||||
// https://github.com/sileht/check_mk/blob/master/livestatus/api/python/livestatus.py
|
||||
|
||||
class CheckmkHandlerScheduleCheck : public QObject
|
||||
, protected Interface::Fts::TriggerUpdateRequestHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CheckmkHandlerScheduleCheck(const std::shared_ptr<DdsHandler> &ddsHandler);
|
||||
~CheckmkHandlerScheduleCheck();
|
||||
|
||||
bool initialize(const QString &checkMkServerHostname, int checkMkServerPort);
|
||||
|
||||
void run(int timoutMsec = 100);
|
||||
void stop();
|
||||
bool doConnect();
|
||||
void addScheduleCheckHostnames(const QStringList &hostnames);
|
||||
|
||||
private:
|
||||
bool writeScheduleUpdateRequest();
|
||||
|
||||
Q_SIGNALS:
|
||||
void newCheckScheduled();
|
||||
void updateLastCheckTimeDirect(QStringList hostnamesForLastCheckTime, qint64 lastCheckSec);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onTimeout();
|
||||
void onConnected();
|
||||
void onStateChanged(const QAbstractSocket::SocketState &newState);
|
||||
void onSocketError(const QAbstractSocket::SocketError &socketError);
|
||||
|
||||
private:
|
||||
void onTriggerUpdateRequest(const rti::core::SampleIdentity &cookie,
|
||||
const TriggerUpdate &request) override;
|
||||
|
||||
|
||||
protected:
|
||||
bool processLine(const QByteArray &line);
|
||||
|
||||
private:
|
||||
// checkMkServer
|
||||
QString m_checkMkHost;
|
||||
quint16 m_checkMkPort{0};
|
||||
QTimer *m_timer{nullptr};
|
||||
|
||||
QStringList m_scheduleCheckHostnames;
|
||||
|
||||
QTcpSocket *m_socket{nullptr};
|
||||
|
||||
std::shared_ptr<DdsHandler> m_ddsHandler;
|
||||
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
|
||||
} // namespace ComponentMonitor
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Export definitions
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2015-08-04
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#ifndef CMO_COMMON_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define CMO_COMMON_EXPORT
|
||||
# else
|
||||
# if defined(MAKE_SVCCMOCOMMON_LIB)
|
||||
# define CMO_COMMON_EXPORT Q_DECL_EXPORT
|
||||
# ifndef WIN32
|
||||
# ifdef NDDSUSERDllExport
|
||||
# undef NDDSUSERDllExport
|
||||
# endif
|
||||
# define NDDSUSERDllExport Q_DECL_EXPORT
|
||||
# endif
|
||||
# else
|
||||
# define CMO_COMMON_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef CMO_CLIENT_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define CMO_CLIENT_EXPORT
|
||||
# else
|
||||
# if defined(MAKE_SVCCMOCLIENT_LIB)
|
||||
# define CMO_CLIENT_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define CMO_CLIENT_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef CMO_SERVER_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define CMO_SERVER_EXPORT
|
||||
# else
|
||||
# if defined(MAKE_SVCCMOSERVER_LIB)
|
||||
# define CMO_SERVER_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define CMO_SERVER_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<service namespace="ComponentMonitor" abbreviation="CMO" procNames="ComponentMonitor" exerciseDependency="Global" groups="Core" prio="3">
|
||||
<rcs>
|
||||
<Id Id="$Id$"/>
|
||||
<HeadURL HeadURL="$HeadURL$"/>
|
||||
<Author Author="$Author$"/>
|
||||
</rcs>
|
||||
<topicTypes>
|
||||
<topicType name="ComponentStatus" isDataObject="1" autosubscribe="1" routeToClient="1" routeToServer="0" routeInReplay="0" baseValueType="Core::BaseEntity">
|
||||
<column name="hostname" idlType="string"/>
|
||||
<column name="state" idlType="ComponentState"/>
|
||||
<column name="last_check" idlType="long long"/>
|
||||
</topicType>
|
||||
<topicType name="TriggerUpdate">
|
||||
<column name="hostnames" idlType="sequence<string>"/>
|
||||
</topicType>
|
||||
</topicTypes>
|
||||
<functionTopics>
|
||||
<functionTopic name="TriggerUpdate" requestTopicType="TriggerUpdate" replyTopicType="Core::FunctionReply" requestTopicName="TriggerUpdateRequest" replyTopicName="TriggerUpdateReply" routeInReplay="0"/>
|
||||
</functionTopics>
|
||||
<tables/>
|
||||
<views/>
|
||||
<enumerations>
|
||||
<enumeration name="ComponentState">
|
||||
<attribute key="Undefined" value="0"/>
|
||||
<attribute key="Reachable" value="1"/>
|
||||
<attribute key="Unreachable" value="2"/>
|
||||
</enumeration>
|
||||
</enumerations>
|
||||
</service>
|
||||
+297
@@ -0,0 +1,297 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Handler for ComponentStatus
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Iuliana Ojog, SLSE, 2017-04-03
|
||||
*/
|
||||
|
||||
#include "component_status_handler.h"
|
||||
#include "dds_handler.h"
|
||||
#include <ComponentMonitor/cmo.hpp>
|
||||
#include <ComponentMonitor/cmo_dts.h>
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
namespace ComponentMonitor
|
||||
{
|
||||
|
||||
ComponentStatusHandler::ComponentStatusHandler()
|
||||
: QObject()
|
||||
, m_logger(getLogger("ComponentStatusHandler"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
ComponentStatusHandler::~ComponentStatusHandler()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_ddsHandler = nullptr;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool ComponentStatusHandler::initialize(const std::shared_ptr<DdsHandler> &ddsHandler)
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " START initialize ComponentStatusHandler";
|
||||
|
||||
// initialize database
|
||||
// empty / not required at CMO
|
||||
|
||||
// initialize DDS
|
||||
m_ddsHandler = ddsHandler;
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " ddsHandler referenced";
|
||||
|
||||
m_ismDtc = m_ddsHandler->ismDtc();
|
||||
if (!m_ismDtc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " Failure: no ismDtc";
|
||||
return false;
|
||||
}
|
||||
|
||||
// should be enabled earlier, but be sure:
|
||||
m_ismDtc->enableInstrumentationAsset();
|
||||
m_ismDtc->waitForHistoricalDataInstrumentationAsset(2000);
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " instrumentationAssets-size = " << m_ismDtc->instrumentationAssets().size();
|
||||
|
||||
// get all instrumentation assets and keep them up-to-date:
|
||||
// InstrumentationAssetState may change (mounted, notMounted..)
|
||||
connect(m_ismDtc.get(), &InfrastructureManagement::Interface::Dtc::instrumentationAssetChanged,
|
||||
this, &ComponentStatusHandler::onInstrumentationAssetChanged);
|
||||
// get:
|
||||
m_ismDtc->instrumentationAssets([this](const InfrastructureManagement::InstrumentationAsset & iAsset)
|
||||
{
|
||||
onInstrumentationAssetChanged(iAsset, DataModification::eAdded);
|
||||
});
|
||||
|
||||
|
||||
// with a delay, dump state of each entry
|
||||
QTimer::singleShot(35000, this, &ComponentStatusHandler::dump);
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << "initialize succesful, statusMapSize=" << statusMapSize();
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " END initialize ComponentStatusHandler, statusMapSize=" << statusMapSize();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::string> ComponentStatusHandler::getHostnames() const
|
||||
{
|
||||
std::vector<std::string> ret;
|
||||
ret.reserve(m_statusMap.size());
|
||||
|
||||
for (CONST_ITERATOR_T it = m_statusMap.cbegin(); it != m_statusMap.cend(); ++it)
|
||||
ret.push_back(it->hostname());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ComponentStatusHandler::onInstrumentationAssetChanged(const InfrastructureManagement::InstrumentationAsset &iAsset,
|
||||
DataModification dataMod)
|
||||
{
|
||||
const InfrastructureManagement::MountingPointType_def::type mpType = iAsset.mountingPointTypeId().underlying();
|
||||
if ((mpType != InfrastructureManagement::MountingPointType_def::IndoorCamera) &&
|
||||
(mpType != InfrastructureManagement::MountingPointType_def::OutdoorCamera) &&
|
||||
(mpType != InfrastructureManagement::MountingPointType_def::EffectGenerationControlUnit) &&
|
||||
(mpType != InfrastructureManagement::MountingPointType_def::BuildingSensorModule)
|
||||
)
|
||||
return; // [GUEZE-1489]: just IndoorCamera, OutdoorCamera, EGCU, BSM
|
||||
|
||||
static int assetChangedCounter = 0;
|
||||
|
||||
const int iAssetId = iAsset.id();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< ", iAssetId=" << iAssetId
|
||||
<< " (assetChangedCounter=" << ++assetChangedCounter << ")";
|
||||
|
||||
// Only mounted assets should be monitored:
|
||||
const bool bIsMounted = iAsset.assetStateId() == InfrastructureManagement::InstrumentationAssetState_def::Mounted;
|
||||
if (!bIsMounted)
|
||||
dataMod = DataModification::eRemoved;
|
||||
|
||||
// hostname ist empty?
|
||||
const bool bNoHostname = iAsset.hostname().empty();
|
||||
if (bNoHostname)
|
||||
dataMod = DataModification::eRemoved;
|
||||
|
||||
ITERATOR_T it = m_statusMap.find(iAssetId);
|
||||
|
||||
switch (dataMod)
|
||||
{
|
||||
case DataModification::eAdded:
|
||||
case DataModification::eModified:
|
||||
{
|
||||
ComponentStatus cs;
|
||||
cs.id(iAssetId);
|
||||
cs.hostname(iAsset.hostname());
|
||||
cs.state(ComponentMonitor::ComponentState::Undefined);
|
||||
|
||||
addUpdateInstrumentationAsset(it, cs);
|
||||
}
|
||||
break;
|
||||
case DataModification::eRemoved:
|
||||
{
|
||||
// remove only, if in internal map
|
||||
if (it != m_statusMap.end())
|
||||
removeInstrumentationAsset(it);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// empty
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ComponentStatusHandler::dump()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " +++++++++++++++++++++++++++++++++++++++++++++";
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " +++++++++++++++++++++++++++++++++++++++++++++";
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " DUMP START";
|
||||
|
||||
int counter = 0;
|
||||
|
||||
// 1) write all Reachable:
|
||||
counter = 0;
|
||||
DEBUG_LOG(m_logger) << " +++++++++++++++++++++++++++++++++++++++++++++";
|
||||
DEBUG_LOG(m_logger) << " REACHABLE:";
|
||||
for (const ComponentStatus &status : qAsConst(m_statusMap))
|
||||
{
|
||||
if (status.state().underlying() == ComponentState_def::Reachable)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << " id=" << status.id() << ", host '" << status.hostname().c_str() << " -> Reachable";
|
||||
++counter;
|
||||
}
|
||||
} // for
|
||||
DEBUG_LOG(m_logger) << " REACHABLE hostCounter = " << counter;
|
||||
|
||||
// 2) write all UnReachable:
|
||||
counter = 0;
|
||||
DEBUG_LOG(m_logger) << " +++++++++++++++++++++++++++++++++++++++++++++";
|
||||
DEBUG_LOG(m_logger) << " UNREACHABLE:";
|
||||
for (const ComponentStatus &status : qAsConst(m_statusMap))
|
||||
{
|
||||
if (status.state().underlying() == ComponentState_def::Unreachable)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << " id=" << status.id() << ", host '" << status.hostname().c_str() << " -> Unreachable";
|
||||
++counter;
|
||||
}
|
||||
} // for
|
||||
DEBUG_LOG(m_logger) << " UNREACHABLE hostCounter = " << counter;
|
||||
|
||||
// 3) write all Undefined:
|
||||
counter = 0;
|
||||
DEBUG_LOG(m_logger) << " +++++++++++++++++++++++++++++++++++++++++++++";
|
||||
DEBUG_LOG(m_logger) << " UNDEFINED:";
|
||||
for (const ComponentStatus &status : qAsConst(m_statusMap))
|
||||
{
|
||||
if (status.state().underlying() == ComponentState_def::Undefined)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << " id=" << status.id() << ", host '" << status.hostname().c_str() << " -> Undefined";
|
||||
++counter;
|
||||
}
|
||||
} // for
|
||||
DEBUG_LOG(m_logger) << " UNDEFINED hostCounter = " << counter;
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " DUMP END";
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " +++++++++++++++++++++++++++++++++++++++++++++";
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " +++++++++++++++++++++++++++++++++++++++++++++";
|
||||
}
|
||||
|
||||
void ComponentStatusHandler::onNewState(const QString &hostname, bool reachable, long long lastCheckSec)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " hostname=" << hostname
|
||||
<< ", reachable=" << reachable
|
||||
<< ", lastCheckSec=" << lastCheckSec;
|
||||
|
||||
if (hostname.isEmpty())
|
||||
return;
|
||||
|
||||
for (ITERATOR_T it = m_statusMap.begin(); it != m_statusMap.end(); ++it)
|
||||
{
|
||||
const QString hname = QString::fromStdString(it->hostname());
|
||||
if (hname.compare(hostname, Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
ComponentState_def::type newStateInner = reachable ? ComponentState_def::Reachable : ComponentState_def::Unreachable;
|
||||
|
||||
ComponentStatus newCs = (*it);
|
||||
newCs.state(newStateInner);
|
||||
newCs.last_check(lastCheckSec);
|
||||
|
||||
addUpdateInstrumentationAsset(it, newCs);
|
||||
}
|
||||
} // for
|
||||
}
|
||||
|
||||
void ComponentStatusHandler::onUpdateLastCheckTimeDirect(const QStringList &hostnamesForUpdateLastCheckTime, qint64 lastCheckSec)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START hostnamesForLastCheckTime=" << hostnamesForUpdateLastCheckTime.join(QStringLiteral(";"));
|
||||
|
||||
for (ITERATOR_T it = m_statusMap.begin(); it != m_statusMap.end(); ++it)
|
||||
{
|
||||
ComponentStatus &cs = *it;
|
||||
const QString &curHostname = QString::fromStdString(cs.hostname());
|
||||
if (!hostnamesForUpdateLastCheckTime.contains(curHostname, Qt::CaseInsensitive))
|
||||
continue;
|
||||
|
||||
// do not step backwards:
|
||||
if (lastCheckSec <= cs.last_check())
|
||||
continue;
|
||||
|
||||
const ComponentState_def::type curState = cs.state().underlying();
|
||||
if ((curState == ComponentState_def::Reachable) ||
|
||||
(curState == ComponentState_def::Unreachable))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " updateLastCheckTimeDirect"
|
||||
<< " host: '" << curHostname << "'"
|
||||
<< " newLastCheck= " << lastCheckSec;
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " DIFF_2a (*it) " << (*it);
|
||||
cs.last_check(lastCheckSec);
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " DIFF_2b (*it) " << (*it);
|
||||
m_ddsHandler->dts()->publish(cs);
|
||||
}
|
||||
} // for
|
||||
}
|
||||
|
||||
bool ComponentStatusHandler::addUpdateInstrumentationAsset(ComponentStatusHandler::ITERATOR_T it,
|
||||
const ComponentStatus &cs)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START add/Update: cs=" << cs
|
||||
<< ", curSize=" << m_statusMap.size() << ")";
|
||||
const int id = cs.id();
|
||||
|
||||
if (it != m_statusMap.end())
|
||||
{
|
||||
// real update?
|
||||
// (avoid publishing the same data)
|
||||
if ((*it) != cs)
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " DIFF (*it) " << (*it);
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " DIFF cs " << cs;
|
||||
|
||||
(*it) = cs; // m_statusMap.insert(id, cs);
|
||||
m_ddsHandler->dts()->publish(cs);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// insert and publish:
|
||||
m_statusMap.insert(id, cs);
|
||||
m_ddsHandler->dts()->publish(cs);
|
||||
}
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END add/Update: cs=" << cs
|
||||
<< ", curSize=" << m_statusMap.size() << ")";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ComponentStatusHandler::removeInstrumentationAsset(ComponentStatusHandler::ITERATOR_T it)
|
||||
{
|
||||
const int id = it.value().id();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " remove: id=" << id;
|
||||
m_statusMap.remove(id);
|
||||
m_ddsHandler->dts()->removeComponentStatusByKey(id);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ComponentMonitor
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Handler for ComponentStatus
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Norbert Thoden, SLSE, 2022-11-03
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "logger.h"
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <ComponentMonitor/cmo.hpp>
|
||||
#include <QObject>
|
||||
#include <memory>
|
||||
|
||||
namespace DDSConnector
|
||||
{
|
||||
class DdsConnector;
|
||||
}
|
||||
|
||||
namespace ComponentMonitor
|
||||
{
|
||||
class DdsHandler;
|
||||
|
||||
// Class ComponentStatusHandler is created for publishing ComponentStatus.
|
||||
|
||||
class ComponentStatusHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using CONT_T = QMap<int, ComponentStatus>; // (instrumentationAsset)Id <-> ComponentStatus
|
||||
using ITERATOR_T = QMap<int, ComponentStatus>::iterator;
|
||||
using CONST_ITERATOR_T = QMap<int, ComponentStatus>::ConstIterator;
|
||||
|
||||
public:
|
||||
ComponentStatusHandler();
|
||||
~ComponentStatusHandler();
|
||||
|
||||
bool initialize(const std::shared_ptr<DdsHandler> &ddsHandler);
|
||||
|
||||
long statusMapSize() const { return m_statusMap.size(); }
|
||||
std::vector<std::string> getHostnames() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void onNewState(const QString &hostname, bool reachable, long long lastCheckSec);
|
||||
|
||||
// UpdateLastCheckTimeDirect:
|
||||
void onUpdateLastCheckTimeDirect(const QStringList &hostnamesForUpdateLastCheckTime, qint64 lastCheckSec);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onInstrumentationAssetChanged(const InfrastructureManagement::InstrumentationAsset &iAsset, DataModification dataMod);
|
||||
|
||||
void dump();
|
||||
|
||||
protected:
|
||||
bool addUpdateInstrumentationAsset(ITERATOR_T it, const ComponentStatus &cs);
|
||||
bool removeInstrumentationAsset(ITERATOR_T it);
|
||||
|
||||
private:
|
||||
std::shared_ptr<DdsHandler> m_ddsHandler;
|
||||
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
|
||||
CONT_T m_statusMap; // lookupTable for checkmk and publishing
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
|
||||
} // namespace ComponentMonitor
|
||||
Executable
+79
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* DdsHandler for DDS
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2015-09-02
|
||||
*/
|
||||
|
||||
#include "dds_handler.h"
|
||||
|
||||
#include "cmo_dts.h"
|
||||
#include "cmo_fts.h"
|
||||
|
||||
#include <DDS/DTS/generic_dts_impl.h>
|
||||
#include <DDS/Core/pacemaker.h>
|
||||
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
|
||||
namespace ComponentMonitor
|
||||
{
|
||||
|
||||
DdsHandler::DdsHandler(int domainId, int exerciseId)
|
||||
: m_ddsConnector(std::make_shared<DDSConnector::DdsConnector>(domainId, IDL::PartitionType::Global, exerciseId))
|
||||
, m_logger(getLogger("DdsHandler"))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "DdsHandler(" << domainId << ") for partition: " << m_ddsConnector->getDefaultPartition();
|
||||
}
|
||||
|
||||
DdsHandler::~DdsHandler()
|
||||
{}
|
||||
|
||||
bool DdsHandler::init(const QStringList &qosFileList)
|
||||
{
|
||||
if (!m_ddsConnector->init(qosFileList))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error initializing dds connections - aborting";
|
||||
return false;
|
||||
}
|
||||
|
||||
// default initialize Publisher and Subscriber
|
||||
m_ddsConnector->initPublisherSubscriber();
|
||||
|
||||
// Pacemaker
|
||||
m_dtsCurrentRunningState.reset(m_ddsConnector->createDTS<DTS::CurrentRunningStateImpl>());
|
||||
assert(m_dtsCurrentRunningState.get());
|
||||
|
||||
// Pacemaker
|
||||
m_pacemaker = std::make_shared<Core::Pacemaker>(m_ddsConnector);
|
||||
|
||||
m_ddsDts = ComponentMonitor::Interface::Dts::create(m_ddsConnector);
|
||||
m_ddsFts = ComponentMonitor::Interface::Fts::create(m_ddsConnector);
|
||||
|
||||
bool bRet = m_ddsDts->enableAll();
|
||||
INFO_LOG(m_logger) << "Dts initialised";
|
||||
|
||||
bRet &= m_ddsFts->enableAll();
|
||||
INFO_LOG(m_logger) << "Fts initialised";
|
||||
|
||||
m_ismDtc = InfrastructureManagement::Interface::Dtc::create(m_ddsConnector);
|
||||
|
||||
// TODO: call at the end of main_handler init:
|
||||
//m_ddsHandler->pacemaker()->setNewState(Core::RunningState::Running);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
void DdsHandler::enableDtcs()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START Enable DTCs(" << m_ddsConnector->getDomainId() << ") for partition: " << m_ddsConnector->getDefaultPartition();
|
||||
m_ismDtc->enableInstrumentationAsset();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END Enable DTCs(" << m_ddsConnector->getDomainId() << ") for partition: " << m_ddsConnector->getDefaultPartition();
|
||||
}
|
||||
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> DdsHandler::ismDtc() const
|
||||
{
|
||||
return m_ismDtc;
|
||||
}
|
||||
|
||||
} // Namespace PDM
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* DdsHandler for DDS
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna E. Rathje, SLSE, 2015-09-02
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
#include <DDS/Core/core_dts_types.h>
|
||||
|
||||
#include <ComponentMonitor/cmo_dts.h>
|
||||
#include <ComponentMonitor/cmo_fts.h>
|
||||
#include "logger.h"
|
||||
|
||||
namespace Core
|
||||
{
|
||||
class Pacemaker;
|
||||
}
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace ComponentMonitor
|
||||
{
|
||||
class DdsHandler final
|
||||
{
|
||||
public:
|
||||
DdsHandler(int domainId, int exerciseId);
|
||||
~DdsHandler();
|
||||
|
||||
bool init(const QStringList &qosFileList = QStringList());
|
||||
|
||||
void enableDtcs();
|
||||
|
||||
|
||||
std::shared_ptr<Core::Pacemaker> pacemaker() const
|
||||
{
|
||||
return m_pacemaker;
|
||||
}
|
||||
|
||||
std::shared_ptr<ComponentMonitor::Interface::Dts> dts() const
|
||||
{
|
||||
return m_ddsDts;
|
||||
}
|
||||
std::shared_ptr<ComponentMonitor::Interface::Fts> fts() const
|
||||
{
|
||||
return m_ddsFts;
|
||||
}
|
||||
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> ismDtc() const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
|
||||
std::shared_ptr<DTS::CurrentRunningState> m_dtsCurrentRunningState;
|
||||
std::shared_ptr<Core::Pacemaker> m_pacemaker;
|
||||
|
||||
std::shared_ptr<ComponentMonitor::Interface::Dts> m_ddsDts;
|
||||
std::shared_ptr<ComponentMonitor::Interface::Fts> m_ddsFts;
|
||||
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
|
||||
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
} // namespace ComponentMonitor
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/bin/sh
|
||||
# This is a sample shell script showing how you can submit the SCHEDULE_FORCED_HOST_CHECK command
|
||||
# to Nagios. Adjust variables to fit your environment as necessary.
|
||||
|
||||
now=`date +%s`
|
||||
#commandfile='/usr/local/nagios/var/rw/nagios.cmd'
|
||||
|
||||
#/bin/printf "[%lu] SCHEDULE_FORCED_HOST_CHECK;host1;1110741500\n" $now > $commandfile
|
||||
|
||||
echo $now
|
||||
date -d @$now
|
||||
|
||||
#printf "$now SCHEDULE_FORCED_HOST_CHECK;ENT_AHTC_EXCTDS01;$now\n\n" | nc 10.198.80.58 6557
|
||||
|
||||
#printf "$now SCHEDULE_HOST_CHECK;ENT_AHTC_EXCTDS01;$now\n\n" | nc 10.198.80.58 6557
|
||||
|
||||
# Thore:
|
||||
# Hier sind zwei "\n" wichtig!!!
|
||||
#printf "COMMAND [$now] SCHEDULE_FORCED_HOST_CHECK;REF_GUEZ_ECVMAVS01;$now\n\n" | nc 10.198.80.58 6557
|
||||
#printf "COMMAND [$now] SCHEDULE_FORCED_HOST_CHECK;REF_GUEZ_ECVMAVS01;$now\n\n" | nc 10.198.80.58 6557
|
||||
#printf "COMMAND [$now] SCHEDULE_FORCED_HOST_CHECK;REF_GUEZ_ECVMAVS01;$now\n\n" | nc 10.198.80.58 6557
|
||||
|
||||
printf "COMMAND [$now] SCHEDULE_FORCED_HOST_CHECK;REF_GUEZ_ECVMAVS01;$now\n\n\n" | nc 10.198.80.58 6557
|
||||
printf "COMMAND [$now] SCHEDULE_FORCED_HOST_CHECK;REF_GUEZ_ECVMADB01;$now\n\n\n" | nc 10.198.80.58 6557
|
||||
|
||||
printf "COMMAND [$now] SCHEDULE_FORCED_HOST_CHECK;UBEBSM0001;$now\n\n\n" | nc 10.198.80.58 6557
|
||||
|
||||
|
||||
echo "end"
|
||||
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Initialization for FileManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Iuliana Ojog, SLSE, 2017-04-03
|
||||
*/
|
||||
|
||||
#include "initialization.h"
|
||||
#include "dds_handler.h"
|
||||
#include <ComponentMonitor/cmo.hpp>
|
||||
#include <ComponentMonitor/cmo_dts.h>
|
||||
#include <ComponentMonitor/settings.h>
|
||||
#include <QTimer>
|
||||
|
||||
namespace ComponentMonitor
|
||||
{
|
||||
|
||||
Initialization::Initialization()
|
||||
: m_logger(getLogger("Initialization"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
Initialization::~Initialization()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_checkmkHandler = nullptr;
|
||||
m_componentStatusHandler = nullptr;
|
||||
m_ddsHandler = nullptr;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool Initialization::initialize(const std::shared_ptr<DdsHandler> &ddsHandler)
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
// initialize database
|
||||
// empty / not required at CMO
|
||||
|
||||
// initialize DDS
|
||||
m_ddsHandler = ddsHandler;
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << "ddsHandler referenced";
|
||||
|
||||
//
|
||||
// setup ComponentStatusHandler
|
||||
//
|
||||
m_componentStatusHandler = std::make_shared<ComponentStatusHandler>();
|
||||
|
||||
// FIRST enable DTCs
|
||||
// DTCs could get samples...
|
||||
m_ddsHandler->enableDtcs();
|
||||
|
||||
// SECOND DELAYED real start
|
||||
// all dtd::XY_changed (from enabling dtcs) should not be emitted anymore
|
||||
QTimer::singleShot(5000, nullptr, [this]()
|
||||
{
|
||||
this->delayedInit();
|
||||
});
|
||||
|
||||
// DO NOT initialize
|
||||
|
||||
|
||||
//
|
||||
// initialize CheckMk (Nagios)
|
||||
//
|
||||
m_checkmkHandler = std::make_shared<CheckmkHandler>();
|
||||
|
||||
const QString host = Settings::checkMkHost();
|
||||
const int port = Settings::checkMkPort();
|
||||
const int intervalSec = Settings::checkMkIntervalSec();
|
||||
|
||||
|
||||
//
|
||||
// Nov 2021, Thore Poggenburg:
|
||||
// CheckMk prueft alle 5 min.
|
||||
//
|
||||
if (!m_checkmkHandler->initialize(host, port, intervalSec))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " CheckmkHandler::initialize failed";
|
||||
return false;
|
||||
}
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " CheckmkHandler:initialize succesful";
|
||||
|
||||
QObject::connect(m_checkmkHandler.get(), &CheckmkHandler::newState,
|
||||
m_componentStatusHandler.get(), &ComponentStatusHandler::onNewState, Qt::UniqueConnection);
|
||||
|
||||
|
||||
//
|
||||
// TriggerUpdate via COMMAND 'SCHEDULE_FORCED_HOST_CHECK'
|
||||
//
|
||||
m_checkmkHandlerScheduleCheck = std::make_shared<CheckmkHandlerScheduleCheck>(m_ddsHandler);
|
||||
if (!m_checkmkHandlerScheduleCheck->initialize(host, port))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " CheckmkHandlerScheduleCheck::initialize failed";
|
||||
return false;
|
||||
}
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " CheckmkHandlerScheduleCheck:initialize succesful";
|
||||
|
||||
|
||||
#ifdef LTS_DEBUG
|
||||
//
|
||||
// debug purpose:
|
||||
//
|
||||
QTimer::singleShot(20000, m_checkmkHandlerScheduleCheck.get(), [this](){
|
||||
qCritical() << " trigger Update";
|
||||
// REF_GUEZ_ECVMAVS01, REF_GUEZ_ECVMADB01, REF_GUEZ_ECMAPWS11
|
||||
m_checkmkHandlerScheduleCheck->addScheduleCheckHostnames({QStringLiteral("REF_GUEZ_ECVMAVS01")});
|
||||
m_checkmkHandlerScheduleCheck->addScheduleCheckHostnames({QStringLiteral("REF_GUEZ_ECVMADB01")});
|
||||
m_checkmkHandlerScheduleCheck->addScheduleCheckHostnames({QStringLiteral("REF_GUEZ_ECMAPWS11")});
|
||||
|
||||
m_checkmkHandlerScheduleCheck->run(1000); // msec
|
||||
});
|
||||
#endif // LTS_DEBUG
|
||||
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Initialization::delayedInit()
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
bool success = true;
|
||||
if (!m_componentStatusHandler->initialize(m_ddsHandler))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " initialize failed for ComponentStatusHandler";
|
||||
success = false;
|
||||
}
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " ComponentStatusHandler, statusMapSize=" << m_componentStatusHandler->getHostnames().size();
|
||||
|
||||
m_checkmkHandler->run();
|
||||
|
||||
// after schedules check(s), get new status list:
|
||||
QObject::connect(m_checkmkHandlerScheduleCheck.get(), &CheckmkHandlerScheduleCheck::newCheckScheduled,
|
||||
m_checkmkHandler.get(), &CheckmkHandler::onImmediateGetStateRequested, Qt::UniqueConnection);
|
||||
|
||||
// UpdateLastCheckTimeDirect :
|
||||
const bool updateLastCheckTimeDirect = Settings::updateLastCheckTimeDirect();
|
||||
NOTICE_LOG(m_logger) << LOGFUNCTION << " updateLastCheckTimeDirect [bool] = " << updateLastCheckTimeDirect;
|
||||
if (updateLastCheckTimeDirect)
|
||||
{
|
||||
NOTICE_LOG(m_logger) << LOGFUNCTION << " updateLastCheckTimeDirect is enabled";
|
||||
QObject::connect(m_checkmkHandlerScheduleCheck.get(), &CheckmkHandlerScheduleCheck::updateLastCheckTimeDirect,
|
||||
m_componentStatusHandler.get(), &ComponentStatusHandler::onUpdateLastCheckTimeDirect, Qt::DirectConnection);
|
||||
}
|
||||
// UpdateLastCheckTimeDirect :
|
||||
|
||||
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return success;
|
||||
}
|
||||
|
||||
} // namespace ComponentMonitor
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Initialization for ComponentMonitor
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Norbert Thoden, SLSE, 2022-11-03
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "logger.h"
|
||||
#include "component_status_handler.h"
|
||||
#include "checkmk_handler.h"
|
||||
#include "checkmk_handler_schedule_check.h"
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <ComponentMonitor/cmo.hpp>
|
||||
#include <QObject>
|
||||
#include <memory>
|
||||
|
||||
namespace DDSConnector
|
||||
{
|
||||
class DdsConnector;
|
||||
}
|
||||
|
||||
namespace ComponentMonitor
|
||||
{
|
||||
class DdsHandler;
|
||||
|
||||
class Initialization
|
||||
{
|
||||
|
||||
public:
|
||||
Initialization();
|
||||
~Initialization();
|
||||
|
||||
bool initialize(const std::shared_ptr<DdsHandler> &ddsHandler);
|
||||
|
||||
|
||||
std::shared_ptr<DdsHandler> dds() const { return m_ddsHandler; }
|
||||
// std::shared_ptr<DatabaseInterface> db() const;
|
||||
|
||||
bool delayedInit();
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
std::shared_ptr<DdsHandler> m_ddsHandler;
|
||||
std::shared_ptr<ComponentStatusHandler> m_componentStatusHandler;
|
||||
std::shared_ptr<CheckmkHandler> m_checkmkHandler;
|
||||
std::shared_ptr<CheckmkHandlerScheduleCheck> m_checkmkHandlerScheduleCheck;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace ComponentMonitor
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
log4j.reset=true
|
||||
log4j.rootLogger=WARN, file, stdout
|
||||
|
||||
# Service/Proxie: ComponentMonitor
|
||||
###########################################################
|
||||
|
||||
#log4j.logger.CMO=DEBUG
|
||||
#log4j.logger.CMO.main=DEBUG
|
||||
#log4j.logger.CMO.DdsHandler=DEBUG
|
||||
#log4j.logger.CMO.MainHandler=DEBUG
|
||||
#log4j.logger.CMO.Initialization=DEBUG
|
||||
|
||||
#log4j.logger.CMO.ComponentStatusHandler=INFO
|
||||
#log4j.logger.CMO.CheckmkHandler=INFO
|
||||
#log4j.logger.CMO.CheckmkHandlerScheduleCheck=DEBUG
|
||||
|
||||
|
||||
# File
|
||||
###########################################################
|
||||
log4j.appender.file=Lts::RollingFileAppender
|
||||
log4j.appender.file.MaxFileSize=10MB
|
||||
log4j.appender.file.MaxBackupIndex=9
|
||||
log4j.appender.file.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.file.layout.ConversionPattern=%d %-5p %c |#| %m (%.50F:%L) %n
|
||||
|
||||
|
||||
# Appnd_Console
|
||||
###########################################################
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern= %d %-5p %-30c |#| %m (%-.30F:%L) %n
|
||||
|
||||
|
||||
|
||||
# Appnd_Syslog
|
||||
###########################################################
|
||||
log4j.appender.syslog=org.apache.log4j.SyslogAppender
|
||||
log4j.appender.syslog.Threshold=ERROR
|
||||
log4j.appender.syslog.SysLogHost=localhost
|
||||
log4j.appender.syslog.Facility=LOCAL7
|
||||
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.syslog.layout.ConversionPattern= %-4r %-5p %c %x - %m
|
||||
log4j.appender.syslog.LevelRangeFilter.AcceptOnMatch=true
|
||||
log4j.appender.syslog.LevelRangeFilter.LevelMin=DEBUG
|
||||
log4j.appender.syslog.LevelRangeFilter.LevelMax=FATAL
|
||||
|
||||
|
||||
###########################################################
|
||||
###########################################################
|
||||
###########################################################
|
||||
# 1) Available Levels in LOG4CXX Version 0.10.0:
|
||||
# TRACE,
|
||||
# DEBUG,
|
||||
# INFO,
|
||||
# WARN,
|
||||
# ERROR
|
||||
# FATAL
|
||||
#
|
||||
# d = date/time
|
||||
# p = priority (Level)
|
||||
# c = category/channel
|
||||
# m = message
|
||||
# F = file
|
||||
# L = line
|
||||
# n = platform dependent line separator character or characters.
|
||||
# ....
|
||||
#
|
||||
# Examples for console:
|
||||
# a)
|
||||
# %d %p %c #%m# (%.50F:%L)%n
|
||||
# date/time
|
||||
# priority
|
||||
# category/channel
|
||||
# #message#
|
||||
# (Maximal 50Character des Filename von rechts:Line)
|
||||
# line separator
|
||||
#
|
||||
# b)
|
||||
# %d (%.15F:%L) %-5p %c |#| %m%n
|
||||
# date/time
|
||||
# (Maximal 15Character des Filename von rechts:Line)
|
||||
# priority, Right pad with spaces if the priority name is less than 5 characters long.
|
||||
# category/channel
|
||||
# message
|
||||
# line separator
|
||||
#
|
||||
# Examples for files:
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Building Config - logging facility
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
namespace ComponentMonitor
|
||||
{
|
||||
|
||||
LOGGER_T getLogger(const char *name)
|
||||
{
|
||||
static const char ns[] = "CMO.";
|
||||
std::string loggerName;
|
||||
const size_t len = strlen(name);
|
||||
loggerName.reserve(sizeof(ns) + len);
|
||||
loggerName.append(ns, sizeof(ns) - 1);
|
||||
loggerName.append(name, len);
|
||||
|
||||
try
|
||||
{
|
||||
return NGL::NGLLoggerBootstrap::getNGLRootLogger().
|
||||
getNGLLogger(loggerName);
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
fprintf(stderr, "Error retrieving logger: %s", ex.what());
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ComponentMonitor
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Logging for ComponentMonitor
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
#include "cmo_export.h"
|
||||
|
||||
namespace ComponentMonitor
|
||||
{
|
||||
using LOGGER_T = NGL::INGLLogger &;
|
||||
|
||||
CMO_COMMON_EXPORT LOGGER_T getLogger(const char *name);
|
||||
inline LOGGER_T getLogger(const QString &loggerName)
|
||||
{
|
||||
return getLogger(loggerName.toUtf8().constData());
|
||||
}
|
||||
} // namespace ComponentMonitor
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* main for ComponentMonitor
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include <nglapplication/nglcoreapplication.h>
|
||||
#include <LtsCommandLineParser/LtsCommandLineParser.h>
|
||||
|
||||
#include "main_handler.h"
|
||||
#include "logger.h"
|
||||
#include "settings.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
NGLCoreApplication app(argc, argv);
|
||||
|
||||
LtsCommandLineParser::LtsCommandLineParser options;
|
||||
if (!options.init())
|
||||
return -1;
|
||||
app.createLogger("CMO", options.exerciseId());
|
||||
|
||||
ComponentMonitor::Settings::setIniFile(options.iniFile());
|
||||
|
||||
int iRet = -3;
|
||||
{
|
||||
std::unique_ptr<ComponentMonitor::MainHandler> mainHandler(new ComponentMonitor::MainHandler);
|
||||
|
||||
if (!mainHandler->init(options.domainId()))
|
||||
return iRet;
|
||||
|
||||
STARTUP_LOG(app.baseLogger());
|
||||
|
||||
iRet = app.exec();
|
||||
|
||||
SHUTDOWN_LOG(app.baseLogger());
|
||||
}
|
||||
|
||||
return iRet;
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* MainHandler for AssetManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include "main_handler.h"
|
||||
#include "initialization.h"
|
||||
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
#include <ngldb/db_service_handler.h>
|
||||
#include <DDS/Core/pacemaker.h>
|
||||
|
||||
namespace ComponentMonitor
|
||||
{
|
||||
|
||||
MainHandler::MainHandler(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_logger(getLogger("MainHandler"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
MainHandler::~MainHandler()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_cmoService = nullptr;
|
||||
m_ddsHandler = nullptr;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool MainHandler::init(int domainId)
|
||||
{
|
||||
// initialize DDS
|
||||
const int excerciseId = 0;
|
||||
m_ddsHandler = std::make_shared<DdsHandler>(domainId, excerciseId);
|
||||
if (!m_ddsHandler->init())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Initialisation ddsHandler failed.";
|
||||
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::StartingError);
|
||||
return false;
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "Initialisation ddsHandler succesful.";
|
||||
|
||||
// Initialization:
|
||||
// Keep in mind: ComponentMonitor::Initialization::run() is executed with a delay
|
||||
m_cmoService = std::make_shared<ComponentMonitor::Initialization>();
|
||||
if (!m_cmoService->initialize(m_ddsHandler))
|
||||
{
|
||||
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::StartingError);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::Running);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ComponentMonitor
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* MainHandler for AereaEffectSimulation
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <memory>
|
||||
#include "dds_handler.h"
|
||||
#include "cmo_db.h"
|
||||
#include "logger.h"
|
||||
|
||||
namespace ComponentMonitor
|
||||
{
|
||||
// Forward
|
||||
class Initialization;
|
||||
|
||||
class MainHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MainHandler(QObject *parent = nullptr);
|
||||
~MainHandler();
|
||||
|
||||
bool init(int domainId);
|
||||
|
||||
std::shared_ptr<DdsHandler> dds() const { return m_ddsHandler; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<DdsHandler> m_ddsHandler;
|
||||
std::shared_ptr<ComponentMonitor::Initialization> m_cmoService;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
} // namespace ComponentMonitor
|
||||
Executable
+69
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* Settings for ComponentMonitor
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
#include <QtCore/QSettings>
|
||||
#include <nglsettings/nglsettings_settings.h>
|
||||
#include <ngltools/ngltools_filesystem.h>
|
||||
|
||||
namespace ComponentMonitor
|
||||
{
|
||||
class NGLSettingsClass : public NGL::Settings
|
||||
{
|
||||
public:
|
||||
NGLSettingsClass()
|
||||
: NGL::Settings(s_iniFile.isEmpty() ? NGL::findProjectConfigFile() : s_iniFile)
|
||||
{}
|
||||
static void setIniFile(const QString &fn)
|
||||
{
|
||||
s_iniFile = fn;
|
||||
}
|
||||
static QString s_iniFile;
|
||||
};
|
||||
QString NGLSettingsClass::s_iniFile;
|
||||
Q_GLOBAL_STATIC(NGLSettingsClass, s)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
NGL::Settings *Settings::settings()
|
||||
{
|
||||
return s();
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
void Settings::setIniFile(const QString &ini)
|
||||
{
|
||||
NGLSettingsClass::setIniFile(ini);
|
||||
}
|
||||
|
||||
QString Settings::checkMkHost()
|
||||
{
|
||||
// 10.7.144.20 -> TGVMMON03 // laut Thore, 2023-02-02
|
||||
return s()->settings()->value(QStringLiteral("CMO/checkMkHost"), QStringLiteral("TGVMMON03")).toString();
|
||||
|
||||
// < Convenience function for settings()->value([int], [def]).toString()
|
||||
// return s()->settings()->getString(QStringLiteral("CMO"), QStringLiteral("checkMkHost"));
|
||||
}
|
||||
int Settings::checkMkPort()
|
||||
{
|
||||
return s()->settings()->value(QStringLiteral("CMO/checkMkPort"), 6557).toInt();
|
||||
}
|
||||
|
||||
int Settings::checkMkIntervalSec()
|
||||
{
|
||||
return s()->settings()->value(QStringLiteral("CMO/checkMkInterval"), 60).toInt();
|
||||
}
|
||||
|
||||
bool Settings::updateLastCheckTimeDirect()
|
||||
{
|
||||
return s()->settings()->value(QStringLiteral("CMO/updateLastCheckTimeDirect"), false).toBool();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
} // namespace ComponentMonitor
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Settings for ComponentMonitor
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <QString>
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class Settings;
|
||||
}
|
||||
|
||||
namespace ComponentMonitor
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
NGL::Settings *settings();
|
||||
void setIniFile(const QString &ini);
|
||||
|
||||
QString checkMkHost();
|
||||
int checkMkPort();
|
||||
|
||||
int checkMkIntervalSec();
|
||||
bool updateLastCheckTimeDirect();
|
||||
}
|
||||
|
||||
} // namespace ComponentMonitor
|
||||
Reference in new issue
Block a user