New upstream version 8.1.0
This commit is contained in:
324
mon/source/app/App.cpp
Normal file
324
mon/source/app/App.cpp
Normal file
@@ -0,0 +1,324 @@
|
||||
#include "App.h"
|
||||
|
||||
#include <app/SignalHandler.h>
|
||||
#include <common/components/ComponentInitException.h>
|
||||
#include <common/components/worker/DummyWork.h>
|
||||
#include <misc/Cassandra.h>
|
||||
#include <misc/InfluxDB.h>
|
||||
|
||||
|
||||
App::App(int argc, char** argv) :
|
||||
argc(argc), argv(argv)
|
||||
{}
|
||||
|
||||
void App::run()
|
||||
{
|
||||
try
|
||||
{
|
||||
cfg = boost::make_unique<Config>(argc,argv);
|
||||
runNormal();
|
||||
appResult = AppCode::NO_ERROR;
|
||||
}
|
||||
catch (const InvalidConfigException& e)
|
||||
{
|
||||
std::ostringstream err;
|
||||
err << "Config error: " << e.what() << std::endl
|
||||
<< "[BeeGFS Mon Version: " << BEEGFS_VERSION << std::endl
|
||||
<< "Refer to the default config file (/etc/beegfs/beegfs-mon.conf)" << std::endl
|
||||
<< "or visit http://www.beegfs.com to find out about configuration options.]";
|
||||
printOrLogError(err.str());
|
||||
appResult = AppCode::INVALID_CONFIG;
|
||||
}
|
||||
catch (const ComponentInitException& e)
|
||||
{
|
||||
printOrLogError("Component initialization error: " + std::string(e.what()));
|
||||
appResult = AppCode::INITIALIZATION_ERROR;
|
||||
}
|
||||
catch (const std::runtime_error& e)
|
||||
{
|
||||
printOrLogError("Runtime error: " + std::string(e.what()));
|
||||
appResult = AppCode::RUNTIME_ERROR;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
printOrLogError("Generic error: " + std::string(e.what()));
|
||||
appResult = AppCode::RUNTIME_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
void App::printOrLogError(const std::string& text) const
|
||||
{
|
||||
if (Logger::isInitialized())
|
||||
LOG(GENERAL, ERR, text);
|
||||
else
|
||||
std::cerr << std::endl << text << std::endl << std::endl;
|
||||
}
|
||||
|
||||
void App::runNormal()
|
||||
{
|
||||
Logger::createLogger(cfg->getLogLevel(), cfg->getLogType(), cfg->getLogNoDate(),
|
||||
cfg->getLogStdFile(), cfg->getLogNumLines(), cfg->getLogNumRotatedFiles());
|
||||
|
||||
pidFileLockFD = createAndLockPIDFile(cfg->getPIDFile());
|
||||
initDataObjects();
|
||||
SignalHandler::registerSignalHandler(this);
|
||||
initLocalNodeInfo();
|
||||
initWorkers();
|
||||
initComponents();
|
||||
|
||||
RDMASocket::rdmaForkInitOnce();
|
||||
|
||||
|
||||
if (cfg->getRunDaemonized())
|
||||
daemonize();
|
||||
|
||||
logInfos();
|
||||
|
||||
// make sure components don't receive SIGINT/SIGTERM (blocked signals are inherited)
|
||||
PThread::blockInterruptSignals();
|
||||
startWorkers();
|
||||
startComponents();
|
||||
PThread::unblockInterruptSignals();
|
||||
|
||||
joinComponents();
|
||||
joinWorkers();
|
||||
}
|
||||
|
||||
void App::initLocalNodeInfo()
|
||||
{
|
||||
bool useRDMA = cfg->getConnUseRDMA();
|
||||
unsigned portUDP = cfg->getConnMonPort();
|
||||
|
||||
StringList allowedInterfaces;
|
||||
std::string interfacesFilename = cfg->getConnInterfacesFile();
|
||||
if (interfacesFilename.length() )
|
||||
cfg->loadStringListFile(interfacesFilename.c_str(), allowedInterfaces);
|
||||
|
||||
NetworkInterfaceCard::findAll(&allowedInterfaces, useRDMA, &localNicList);
|
||||
|
||||
if (localNicList.empty() )
|
||||
throw InvalidConfigException("Couldn't find any usable NIC");
|
||||
|
||||
localNicList.sort(NetworkInterfaceCard::NicAddrComp{&allowedInterfaces});
|
||||
NetworkInterfaceCard::supportedCapabilities(&localNicList, &localNicCaps);
|
||||
|
||||
noDefaultRouteNets = std::make_shared<NetVector>();
|
||||
if(!initNoDefaultRouteList(noDefaultRouteNets.get()))
|
||||
throw InvalidConfigException("Failed to parse connNoDefaultRoute");
|
||||
|
||||
initRoutingTable();
|
||||
updateRoutingTable();
|
||||
|
||||
std::string nodeID = System::getHostname();
|
||||
|
||||
// TODO add a Mon nodetype at some point
|
||||
localNode = std::make_shared<LocalNode>(NODETYPE_Client, nodeID, NumNodeID(1), portUDP, 0, localNicList);
|
||||
}
|
||||
|
||||
void App::initDataObjects()
|
||||
{
|
||||
netFilter = boost::make_unique<NetFilter>(cfg->getConnNetFilterFile());
|
||||
tcpOnlyFilter = boost::make_unique<NetFilter>(cfg->getConnTcpOnlyFilterFile());
|
||||
netMessageFactory = boost::make_unique<NetMessageFactory>();
|
||||
workQueue = boost::make_unique<MultiWorkQueue>();
|
||||
|
||||
targetMapper = boost::make_unique<TargetMapper>();
|
||||
|
||||
metaNodes = boost::make_unique<NodeStoreMetaEx>();
|
||||
storageNodes = boost::make_unique<NodeStoreStorageEx>();
|
||||
mgmtNodes = boost::make_unique<NodeStoreMgmtEx>();
|
||||
|
||||
metaBuddyGroupMapper = boost::make_unique<MirrorBuddyGroupMapper>();
|
||||
storageBuddyGroupMapper = boost::make_unique<MirrorBuddyGroupMapper>();
|
||||
|
||||
|
||||
if (cfg->getDbType() == Config::DbTypes::CASSANDRA)
|
||||
{
|
||||
Cassandra::Config cassandraConfig;
|
||||
cassandraConfig.host = cfg->getDbHostName();
|
||||
cassandraConfig.port = cfg->getDbHostPort();
|
||||
cassandraConfig.database = cfg->getDbDatabase();
|
||||
cassandraConfig.maxInsertsPerBatch = cfg->getCassandraMaxInsertsPerBatch();
|
||||
cassandraConfig.TTLSecs = cfg->getCassandraTTLSecs();
|
||||
|
||||
tsdb = boost::make_unique<Cassandra>(std::move(cassandraConfig));
|
||||
}
|
||||
else // Config::DbTypes::INFLUXDB OR Config::DbTypes::INFLUXDB2
|
||||
{
|
||||
InfluxDB::Config influxdbConfig;
|
||||
influxdbConfig.host = cfg->getDbHostName();
|
||||
influxdbConfig.port = cfg->getDbHostPort();
|
||||
influxdbConfig.maxPointsPerRequest = cfg->getInfluxdbMaxPointsPerRequest();
|
||||
influxdbConfig.httpTimeout = cfg->getHttpTimeout();
|
||||
influxdbConfig.curlCheckSSLCertificates = cfg->getCurlCheckSSLCertificates();
|
||||
if (cfg->getDbType() == Config::DbTypes::INFLUXDB2)
|
||||
{
|
||||
influxdbConfig.bucket = cfg->getDbBucket();
|
||||
influxdbConfig.organization = cfg->getDbAuthOrg();
|
||||
influxdbConfig.token = cfg->getDbAuthToken();
|
||||
influxdbConfig.dbVersion = INFLUXDB2;
|
||||
}
|
||||
else
|
||||
{
|
||||
influxdbConfig.database = cfg->getDbDatabase();
|
||||
influxdbConfig.setRetentionPolicy = cfg->getInfluxDbSetRetentionPolicy();
|
||||
influxdbConfig.retentionDuration = cfg->getInfluxDbRetentionDuration();
|
||||
influxdbConfig.username = cfg->getDbAuthUsername();
|
||||
influxdbConfig.password = cfg->getDbAuthPassword();
|
||||
influxdbConfig.dbVersion = INFLUXDB;
|
||||
}
|
||||
tsdb = boost::make_unique<InfluxDB>(std::move(influxdbConfig));
|
||||
}
|
||||
}
|
||||
|
||||
void App::initComponents()
|
||||
{
|
||||
nodeListRequestor = boost::make_unique<NodeListRequestor>(this);
|
||||
statsCollector = boost::make_unique<StatsCollector>(this);
|
||||
cleanUp = boost::make_unique<CleanUp>(this);
|
||||
}
|
||||
|
||||
void App::startComponents()
|
||||
{
|
||||
LOG(GENERAL, DEBUG, "Starting components...");
|
||||
nodeListRequestor->start();
|
||||
statsCollector->start();
|
||||
cleanUp->start();
|
||||
LOG(GENERAL, DEBUG, "Components running.");
|
||||
}
|
||||
|
||||
void App::stopComponents()
|
||||
{
|
||||
if (nodeListRequestor)
|
||||
nodeListRequestor->selfTerminate();
|
||||
if (statsCollector)
|
||||
statsCollector->selfTerminate();
|
||||
if (cleanUp)
|
||||
cleanUp->selfTerminate();
|
||||
|
||||
stopWorkers();
|
||||
selfTerminate();
|
||||
}
|
||||
|
||||
void App::joinComponents()
|
||||
{
|
||||
LOG(GENERAL, DEBUG, "Joining Component threads...");
|
||||
nodeListRequestor->join();
|
||||
statsCollector->join();
|
||||
cleanUp->join();
|
||||
LOG(GENERAL, CRITICAL, "All components stopped. Exiting now.");
|
||||
}
|
||||
|
||||
void App::initWorkers()
|
||||
{
|
||||
const unsigned numDirectWorkers = 1;
|
||||
const unsigned workersBufSize = 1024*1024;
|
||||
|
||||
unsigned numWorkers = cfg->getTuneNumWorkers();
|
||||
|
||||
for (unsigned i=0; i < numWorkers; i++)
|
||||
{
|
||||
auto worker = boost::make_unique<Worker>("Worker" + StringTk::intToStr(i+1),
|
||||
workQueue.get(), QueueWorkType_INDIRECT);
|
||||
|
||||
worker->setBufLens(workersBufSize, workersBufSize);
|
||||
workerList.push_back(std::move(worker));
|
||||
}
|
||||
|
||||
for (unsigned i=0; i < numDirectWorkers; i++)
|
||||
{
|
||||
auto worker = boost::make_unique<Worker>("DirectWorker" + StringTk::intToStr(i+1),
|
||||
workQueue.get(), QueueWorkType_DIRECT);
|
||||
|
||||
worker->setBufLens(workersBufSize, workersBufSize);
|
||||
workerList.push_back(std::move(worker));
|
||||
}
|
||||
}
|
||||
|
||||
void App::startWorkers()
|
||||
{
|
||||
for (auto worker = workerList.begin(); worker != workerList.end(); worker++)
|
||||
{
|
||||
(*worker)->start();
|
||||
}
|
||||
}
|
||||
|
||||
void App::stopWorkers()
|
||||
{
|
||||
// need two loops because we don't know if the worker that handles the work will be the same that
|
||||
// received the self-terminate-request
|
||||
for (auto worker = workerList.begin(); worker != workerList.end(); worker++)
|
||||
{
|
||||
(*worker)->selfTerminate();
|
||||
|
||||
// add dummy work to wake up the worker immediately for faster self termination
|
||||
PersonalWorkQueue* personalQ = (*worker)->getPersonalWorkQueue();
|
||||
workQueue->addPersonalWork(new DummyWork(), personalQ);
|
||||
}
|
||||
}
|
||||
|
||||
void App::joinWorkers()
|
||||
{
|
||||
|
||||
for (auto worker = workerList.begin(); worker != workerList.end(); worker++)
|
||||
{
|
||||
waitForComponentTermination((*worker).get());
|
||||
}
|
||||
}
|
||||
|
||||
void App::logInfos()
|
||||
{
|
||||
LOG(GENERAL, CRITICAL, std::string("Version: ") + BEEGFS_VERSION);
|
||||
#ifdef BEEGFS_DEBUG
|
||||
LOG(GENERAL, DEBUG, "--DEBUG VERSION--");
|
||||
#endif
|
||||
|
||||
// list usable network interfaces
|
||||
NicAddressList nicList = getLocalNicList();
|
||||
logUsableNICs(NULL, nicList);
|
||||
|
||||
// print net filters
|
||||
if (netFilter->getNumFilterEntries() )
|
||||
{
|
||||
LOG(GENERAL, WARNING, std::string("Net filters: ")
|
||||
+ StringTk::uintToStr(netFilter->getNumFilterEntries() ) );
|
||||
}
|
||||
|
||||
if (tcpOnlyFilter->getNumFilterEntries() )
|
||||
{
|
||||
LOG(GENERAL, WARNING, std::string("TCP-only filters: ")
|
||||
+ StringTk::uintToStr(tcpOnlyFilter->getNumFilterEntries() ) );
|
||||
}
|
||||
}
|
||||
|
||||
void App::daemonize()
|
||||
{
|
||||
int nochdir = 1; // 1 to keep working directory
|
||||
int noclose = 0; // 1 to keep stdin/-out/-err open
|
||||
|
||||
LOG(GENERAL, CRITICAL, "Detaching process...");
|
||||
|
||||
int detachRes = daemon(nochdir, noclose);
|
||||
if (detachRes == -1)
|
||||
throw std::runtime_error(std::string("Unable to detach process: ")
|
||||
+ System::getErrString());
|
||||
|
||||
updateLockedPIDFile(pidFileLockFD); // ignored if pidFileFD is -1
|
||||
}
|
||||
|
||||
void App::handleComponentException(std::exception& e)
|
||||
{
|
||||
LOG(GENERAL, CRITICAL, "This component encountered an unrecoverable error.", sysErr,
|
||||
("Exception", e.what()));
|
||||
|
||||
LOG(GENERAL, WARNING, "Shutting down...");
|
||||
stopComponents();
|
||||
}
|
||||
|
||||
void App::handleNetworkInterfaceFailure(const std::string& devname)
|
||||
{
|
||||
// Nothing to do. This App has no internodeSyncer that would rescan the
|
||||
// netdevs.
|
||||
LOG(GENERAL, ERR, "Network interface failure.",
|
||||
("Device", devname));
|
||||
}
|
||||
184
mon/source/app/App.h
Normal file
184
mon/source/app/App.h
Normal file
@@ -0,0 +1,184 @@
|
||||
#ifndef APP_H_
|
||||
#define APP_H_
|
||||
|
||||
#include <app/Config.h>
|
||||
#include <common/app/AbstractApp.h>
|
||||
#include <common/app/log/Logger.h>
|
||||
#include <common/Common.h>
|
||||
#include <common/components/worker/Worker.h>
|
||||
#include <common/nodes/LocalNode.h>
|
||||
#include <common/nodes/NodeStoreClients.h>
|
||||
#include <common/nodes/Node.h>
|
||||
#include <common/toolkit/MessagingTk.h>
|
||||
#include <common/toolkit/NetFilter.h>
|
||||
#include <common/toolkit/NodesTk.h>
|
||||
#include <misc/TSDatabase.h>
|
||||
#include <components/CleanUp.h>
|
||||
#include <components/StatsCollector.h>
|
||||
#include <components/NodeListRequestor.h>
|
||||
#include <net/message/NetMessageFactory.h>
|
||||
#include <nodes/NodeStoreMetaEx.h>
|
||||
#include <nodes/NodeStoreStorageEx.h>
|
||||
#include <nodes/NodeStoreMgmtEx.h>
|
||||
|
||||
class App : public AbstractApp
|
||||
{
|
||||
public:
|
||||
enum AppCode
|
||||
{
|
||||
NO_ERROR = 0,
|
||||
INVALID_CONFIG = 1,
|
||||
INITIALIZATION_ERROR = 2,
|
||||
RUNTIME_ERROR = 3
|
||||
};
|
||||
|
||||
|
||||
App(int argc, char** argv);
|
||||
|
||||
virtual void run() override;
|
||||
virtual void stopComponents() override;
|
||||
virtual void handleComponentException(std::exception& e) override;
|
||||
virtual void handleNetworkInterfaceFailure(const std::string& devname) override;
|
||||
|
||||
|
||||
private:
|
||||
int appResult;
|
||||
int argc;
|
||||
char** argv;
|
||||
LockFD pidFileLockFD;
|
||||
|
||||
std::unique_ptr<TargetMapper> targetMapper;
|
||||
|
||||
std::unique_ptr<Config> cfg;
|
||||
std::unique_ptr<NetFilter> netFilter;
|
||||
std::unique_ptr<NetFilter> tcpOnlyFilter;
|
||||
std::unique_ptr<NetMessageFactory> netMessageFactory;
|
||||
NicListCapabilities localNicCaps;
|
||||
std::shared_ptr<Node> localNode;
|
||||
std::unique_ptr<TSDatabase> tsdb;
|
||||
std::unique_ptr<MultiWorkQueue> workQueue;
|
||||
|
||||
std::unique_ptr<NodeStoreMgmtEx> mgmtNodes;
|
||||
std::unique_ptr<NodeStoreMetaEx> metaNodes;
|
||||
std::unique_ptr<NodeStoreStorageEx> storageNodes;
|
||||
std::unique_ptr<MirrorBuddyGroupMapper> metaBuddyGroupMapper;
|
||||
std::unique_ptr<MirrorBuddyGroupMapper> storageBuddyGroupMapper;
|
||||
|
||||
std::unique_ptr<NodeListRequestor> nodeListRequestor;
|
||||
std::unique_ptr<StatsCollector> statsCollector;
|
||||
std::unique_ptr<CleanUp> cleanUp;
|
||||
|
||||
std::list<std::unique_ptr<Worker>> workerList;
|
||||
|
||||
void printOrLogError(const std::string& text) const;
|
||||
|
||||
void runNormal();
|
||||
void initDataObjects();
|
||||
void initComponents();
|
||||
void startComponents();
|
||||
void joinComponents();
|
||||
void initWorkers();
|
||||
void startWorkers();
|
||||
void stopWorkers();
|
||||
void joinWorkers();
|
||||
void initLocalNodeInfo();
|
||||
void logInfos();
|
||||
void daemonize();
|
||||
|
||||
public:
|
||||
NodeStoreServers* getServerStoreFromType(NodeType nodeType)
|
||||
{
|
||||
switch (nodeType)
|
||||
{
|
||||
case NODETYPE_Meta:
|
||||
return metaNodes.get();
|
||||
|
||||
case NODETYPE_Storage:
|
||||
return storageNodes.get();
|
||||
|
||||
case NODETYPE_Mgmt:
|
||||
return mgmtNodes.get();
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
virtual ICommonConfig* getCommonConfig() const override
|
||||
{
|
||||
return cfg.get();
|
||||
}
|
||||
|
||||
virtual NetFilter* getNetFilter() const override
|
||||
{
|
||||
return netFilter.get();
|
||||
}
|
||||
|
||||
virtual NetFilter* getTcpOnlyFilter() const override
|
||||
{
|
||||
return tcpOnlyFilter.get();
|
||||
}
|
||||
|
||||
virtual AbstractNetMessageFactory* getNetMessageFactory() const override
|
||||
{
|
||||
return netMessageFactory.get();
|
||||
}
|
||||
|
||||
std::shared_ptr<Node> getLocalNode()
|
||||
{
|
||||
return localNode;
|
||||
}
|
||||
|
||||
Config* getConfig()
|
||||
{
|
||||
return cfg.get();
|
||||
}
|
||||
|
||||
MultiWorkQueue *getWorkQueue()
|
||||
{
|
||||
return workQueue.get();
|
||||
}
|
||||
|
||||
NodeStoreMetaEx *getMetaNodes()
|
||||
{
|
||||
return metaNodes.get();
|
||||
}
|
||||
|
||||
NodeStoreStorageEx *getStorageNodes()
|
||||
{
|
||||
return storageNodes.get();
|
||||
}
|
||||
|
||||
NodeStoreMgmtEx *getMgmtNodes()
|
||||
{
|
||||
return mgmtNodes.get();
|
||||
}
|
||||
|
||||
TSDatabase *getTSDB()
|
||||
{
|
||||
return tsdb.get();
|
||||
}
|
||||
|
||||
TargetMapper* getTargetMapper()
|
||||
{
|
||||
return targetMapper.get();
|
||||
}
|
||||
|
||||
MirrorBuddyGroupMapper* getMetaBuddyGroupMapper()
|
||||
{
|
||||
return metaBuddyGroupMapper.get();
|
||||
}
|
||||
|
||||
MirrorBuddyGroupMapper* getStorageBuddyGroupMapper()
|
||||
{
|
||||
return storageBuddyGroupMapper.get();
|
||||
}
|
||||
|
||||
int getAppResult()
|
||||
{
|
||||
return appResult;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif /*APP_H_*/
|
||||
210
mon/source/app/Config.cpp
Normal file
210
mon/source/app/Config.cpp
Normal file
@@ -0,0 +1,210 @@
|
||||
#include <common/toolkit/StringTk.h>
|
||||
#include "Config.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define CONFIG_DEFAULT_CFGFILENAME "/etc/beegfs/beegfs-mon.conf"
|
||||
|
||||
Config::Config(int argc, char** argv): AbstractConfig(argc, argv)
|
||||
{
|
||||
initConfig(argc, argv, true);
|
||||
|
||||
// check mandatory value
|
||||
if(getSysMgmtdHost().empty())
|
||||
throw InvalidConfigException("Management host undefined.");
|
||||
|
||||
// Load auth config file
|
||||
if (!dbAuthFile.empty())
|
||||
{
|
||||
std::ifstream authConfig(dbAuthFile);
|
||||
|
||||
if (!authConfig.good())
|
||||
throw InvalidConfigException("Could not open InfluxDB authentication file");
|
||||
|
||||
StringMap authMap;
|
||||
MapTk::loadStringMapFromFile(dbAuthFile.c_str(), &authMap);
|
||||
|
||||
for (const auto& e : authMap) {
|
||||
if (e.first == "password") {
|
||||
dbAuthPassword = e.second;
|
||||
} else if (e.first == "username") {
|
||||
dbAuthUsername = e.second;
|
||||
} else if (e.first == "organization") {
|
||||
dbAuthOrg = e.second;
|
||||
} else if (e.first == "token") {
|
||||
dbAuthToken = e.second;
|
||||
} else {
|
||||
throw InvalidConfigException("The InfluxDB authentication file may only contain "
|
||||
"the options username and password for influxdb version 1.x "
|
||||
"organization and token for influxdb version 2.x" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Config::loadDefaults(bool addDashes)
|
||||
{
|
||||
AbstractConfig::loadDefaults();
|
||||
|
||||
// re-definitions
|
||||
configMapRedefine("cfgFile", "");
|
||||
configMapRedefine("connUseRDMA", "false");
|
||||
|
||||
// own definitions
|
||||
configMapRedefine("connInterfacesFile", "");
|
||||
configMapRedefine("tuneNumWorkers", "4");
|
||||
configMapRedefine("runDaemonized", "false");
|
||||
configMapRedefine("pidFile", "");
|
||||
|
||||
configMapRedefine("dbType", "influxdb");
|
||||
configMapRedefine("dbHostName", "localhost");
|
||||
configMapRedefine("dbHostPort", "8086");
|
||||
configMapRedefine("dbDatabase", "beegfs_mon");
|
||||
configMapRedefine("dbAuthFile", "");
|
||||
|
||||
// those are used by influxdb only but are kept like this for compatibility
|
||||
configMapRedefine("dbMaxPointsPerRequest", "5000");
|
||||
configMapRedefine("dbSetRetentionPolicy", "true");
|
||||
configMapRedefine("dbRetentionDuration", "1d");
|
||||
|
||||
configMapRedefine("dbBucket", "");
|
||||
|
||||
configMapRedefine("cassandraMaxInsertsPerBatch","25");
|
||||
configMapRedefine("cassandraTTLSecs", "86400");
|
||||
|
||||
configMapRedefine("collectClientOpsByNode", "true");
|
||||
configMapRedefine("collectClientOpsByUser", "true");
|
||||
|
||||
configMapRedefine("httpTimeoutMSecs", "1000");
|
||||
configMapRedefine("statsRequestIntervalSecs", "5");
|
||||
configMapRedefine("nodelistRequestIntervalSecs","30");
|
||||
|
||||
configMapRedefine("curlCheckSSLCertificates", "true");
|
||||
|
||||
}
|
||||
|
||||
void Config::applyConfigMap(bool enableException, bool addDashes)
|
||||
{
|
||||
AbstractConfig::applyConfigMap(false);
|
||||
|
||||
for (StringMapIter iter = configMap.begin(); iter != configMap.end(); )
|
||||
{
|
||||
bool unknownElement = false;
|
||||
|
||||
if (iter->first == std::string("logType"))
|
||||
{
|
||||
if (iter->second == "syslog")
|
||||
{
|
||||
logType = LogType_SYSLOG;
|
||||
}
|
||||
else if (iter->second == "logfile")
|
||||
{
|
||||
logType = LogType_LOGFILE;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw InvalidConfigException("The value of config argument logType is invalid:"
|
||||
" Must be syslog or logfile.");
|
||||
}
|
||||
}
|
||||
else if (iter->first == std::string("connInterfacesFile"))
|
||||
connInterfacesFile = iter->second;
|
||||
else
|
||||
if (iter->first == std::string("tuneNumWorkers"))
|
||||
tuneNumWorkers = StringTk::strToUInt(iter->second);
|
||||
else
|
||||
if (iter->first == std::string("runDaemonized"))
|
||||
runDaemonized = StringTk::strToBool(iter->second);
|
||||
else
|
||||
if (iter->first == std::string("pidFile"))
|
||||
pidFile = iter->second;
|
||||
else
|
||||
if (iter->first == std::string("dbType"))
|
||||
{
|
||||
if (iter->second == "influxdb")
|
||||
dbType = DbTypes::INFLUXDB;
|
||||
else if (iter->second == "influxdb2")
|
||||
dbType = DbTypes::INFLUXDB2;
|
||||
else if (iter->second == "cassandra")
|
||||
dbType = DbTypes::CASSANDRA;
|
||||
else
|
||||
throw InvalidConfigException("The value of config argument dbType is invalid:"
|
||||
" Must be influxdb or cassandra.");
|
||||
}
|
||||
else
|
||||
if (iter->first == std::string("dbHostName"))
|
||||
dbHostName = iter->second;
|
||||
else
|
||||
if (iter->first == std::string("dbHostPort"))
|
||||
dbHostPort = StringTk::strToUInt(iter->second);
|
||||
else
|
||||
if (iter->first == std::string("dbDatabase"))
|
||||
dbDatabase = iter->second;
|
||||
else
|
||||
if (iter->first == std::string("dbAuthFile"))
|
||||
dbAuthFile = iter->second;
|
||||
else
|
||||
// those are used by influxdb only but are kept like this for compatibility
|
||||
if (iter->first == std::string("dbMaxPointsPerRequest"))
|
||||
influxdbMaxPointsPerRequest = StringTk::strToUInt(iter->second);
|
||||
else
|
||||
if (iter->first == std::string("dbSetRetentionPolicy"))
|
||||
influxdbSetRetentionPolicy = StringTk::strToBool(iter->second);
|
||||
else
|
||||
if (iter->first == std::string("dbRetentionDuration"))
|
||||
influxdbRetentionDuration = iter->second;
|
||||
else
|
||||
// those are used by influxdb2
|
||||
if (iter->first == std::string("dbBucket"))
|
||||
dbBucket = iter->second;
|
||||
else
|
||||
|
||||
if (iter->first == std::string("cassandraMaxInsertsPerBatch"))
|
||||
cassandraMaxInsertsPerBatch = StringTk::strToUInt(iter->second);
|
||||
else
|
||||
if (iter->first == std::string("cassandraTTLSecs"))
|
||||
cassandraTTLSecs = StringTk::strToUInt(iter->second);
|
||||
else
|
||||
if (iter->first == std::string("collectClientOpsByNode"))
|
||||
collectClientOpsByNode = StringTk::strToBool(iter->second);
|
||||
else
|
||||
if (iter->first == std::string("collectClientOpsByUser"))
|
||||
collectClientOpsByUser = StringTk::strToBool(iter->second);
|
||||
else
|
||||
if (iter->first == std::string("httpTimeoutMSecs"))
|
||||
httpTimeout = std::chrono::milliseconds(StringTk::strToUInt(iter->second));
|
||||
else
|
||||
if (iter->first == std::string("statsRequestIntervalSecs"))
|
||||
statsRequestInterval = std::chrono::seconds(StringTk::strToUInt(iter->second));
|
||||
else
|
||||
if (iter->first == std::string("nodelistRequestIntervalSecs"))
|
||||
nodelistRequestInterval = std::chrono::seconds(StringTk::strToUInt(iter->second));
|
||||
else
|
||||
if (iter->first == std::string("curlCheckSSLCertificates"))
|
||||
curlCheckSSLCertificates = StringTk::strToBool(iter->second);
|
||||
else
|
||||
{
|
||||
unknownElement = true;
|
||||
|
||||
if (enableException)
|
||||
{
|
||||
throw InvalidConfigException(std::string("The config argument '")
|
||||
+ iter->first + std::string("' is invalid.") );
|
||||
}
|
||||
}
|
||||
|
||||
if (unknownElement)
|
||||
{
|
||||
iter++;
|
||||
}
|
||||
else
|
||||
{
|
||||
iter = eraseFromConfigMap(iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Config::initImplicitVals()
|
||||
{
|
||||
AbstractConfig::initConnAuthHash(connAuthFile, &connAuthHash);
|
||||
}
|
||||
179
mon/source/app/Config.h
Normal file
179
mon/source/app/Config.h
Normal file
@@ -0,0 +1,179 @@
|
||||
#ifndef CONFIG_H_
|
||||
#define CONFIG_H_
|
||||
|
||||
#include <common/app/config/AbstractConfig.h>
|
||||
|
||||
|
||||
class Config : public AbstractConfig
|
||||
{
|
||||
public:
|
||||
Config(int argc, char** argv);
|
||||
|
||||
enum DbTypes
|
||||
{
|
||||
INFLUXDB,
|
||||
INFLUXDB2,
|
||||
CASSANDRA
|
||||
};
|
||||
|
||||
private:
|
||||
// configurables
|
||||
std::string connInterfacesFile;
|
||||
unsigned tuneNumWorkers;
|
||||
bool runDaemonized;
|
||||
std::string pidFile;
|
||||
|
||||
// mon-specific configurables
|
||||
DbTypes dbType;
|
||||
std::string dbHostName;
|
||||
unsigned dbHostPort;
|
||||
std::string dbDatabase;
|
||||
std::string dbBucket;
|
||||
std::string dbAuthFile;
|
||||
unsigned influxdbMaxPointsPerRequest;
|
||||
bool influxdbSetRetentionPolicy;
|
||||
std::string influxdbRetentionDuration;
|
||||
unsigned cassandraMaxInsertsPerBatch;
|
||||
unsigned cassandraTTLSecs;
|
||||
bool collectClientOpsByNode;
|
||||
bool collectClientOpsByUser;
|
||||
std::chrono::milliseconds httpTimeout;
|
||||
std::chrono::seconds statsRequestInterval;
|
||||
std::chrono::seconds nodelistRequestInterval;
|
||||
bool curlCheckSSLCertificates;
|
||||
|
||||
std::string dbAuthUsername;
|
||||
std::string dbAuthPassword;
|
||||
std::string dbAuthOrg;
|
||||
std::string dbAuthToken;
|
||||
|
||||
|
||||
virtual void loadDefaults(bool addDashes) override;
|
||||
virtual void applyConfigMap(bool enableException, bool addDashes) override;
|
||||
virtual void initImplicitVals() override;
|
||||
|
||||
public:
|
||||
// getters & setters
|
||||
|
||||
const std::string& getConnInterfacesFile() const
|
||||
{
|
||||
return connInterfacesFile;
|
||||
}
|
||||
|
||||
unsigned getTuneNumWorkers() const
|
||||
{
|
||||
return tuneNumWorkers;
|
||||
}
|
||||
|
||||
bool getRunDaemonized() const
|
||||
{
|
||||
return runDaemonized;
|
||||
}
|
||||
|
||||
const std::string& getPIDFile() const
|
||||
{
|
||||
return pidFile;
|
||||
}
|
||||
|
||||
DbTypes getDbType() const
|
||||
{
|
||||
return dbType;
|
||||
}
|
||||
|
||||
const std::string& getDbHostName() const
|
||||
{
|
||||
return dbHostName;
|
||||
}
|
||||
|
||||
unsigned getDbHostPort() const
|
||||
{
|
||||
return dbHostPort;
|
||||
}
|
||||
|
||||
const std::string& getDbDatabase() const
|
||||
{
|
||||
return dbDatabase;
|
||||
}
|
||||
|
||||
const std::string& getDbBucket() const
|
||||
{
|
||||
return dbBucket;
|
||||
}
|
||||
|
||||
unsigned getInfluxdbMaxPointsPerRequest() const
|
||||
{
|
||||
return influxdbMaxPointsPerRequest;
|
||||
}
|
||||
|
||||
bool getInfluxDbSetRetentionPolicy() const
|
||||
{
|
||||
return influxdbSetRetentionPolicy;
|
||||
}
|
||||
|
||||
const std::string& getInfluxDbRetentionDuration() const
|
||||
{
|
||||
return influxdbRetentionDuration;
|
||||
}
|
||||
|
||||
unsigned getCassandraMaxInsertsPerBatch() const
|
||||
{
|
||||
return cassandraMaxInsertsPerBatch;
|
||||
}
|
||||
|
||||
unsigned getCassandraTTLSecs() const
|
||||
{
|
||||
return cassandraTTLSecs;
|
||||
}
|
||||
|
||||
bool getCollectClientOpsByNode() const
|
||||
{
|
||||
return collectClientOpsByNode;
|
||||
}
|
||||
|
||||
bool getCollectClientOpsByUser() const
|
||||
{
|
||||
return collectClientOpsByUser;
|
||||
}
|
||||
|
||||
const std::chrono::milliseconds& getHttpTimeout() const
|
||||
{
|
||||
return httpTimeout;
|
||||
}
|
||||
|
||||
const std::chrono::seconds& getStatsRequestInterval() const
|
||||
{
|
||||
return statsRequestInterval;
|
||||
}
|
||||
|
||||
const std::chrono::seconds& getNodelistRequestInterval() const
|
||||
{
|
||||
return nodelistRequestInterval;
|
||||
}
|
||||
|
||||
const std::string& getDbAuthUsername() const
|
||||
{
|
||||
return dbAuthUsername;
|
||||
}
|
||||
|
||||
const std::string& getDbAuthPassword() const
|
||||
{
|
||||
return dbAuthPassword;
|
||||
}
|
||||
|
||||
const std::string& getDbAuthOrg() const
|
||||
{
|
||||
return dbAuthOrg;
|
||||
}
|
||||
|
||||
const std::string& getDbAuthToken() const
|
||||
{
|
||||
return dbAuthToken;
|
||||
}
|
||||
|
||||
bool getCurlCheckSSLCertificates() const
|
||||
{
|
||||
return curlCheckSSLCertificates;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*CONFIG_H_*/
|
||||
14
mon/source/app/Main.cpp
Normal file
14
mon/source/app/Main.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include <common/toolkit/BuildTypeTk.h>
|
||||
#include <app/SignalHandler.h>
|
||||
#include <app/App.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
BuildTypeTk::checkDebugBuildTypes();
|
||||
AbstractApp::runTimeInitsAndChecks();
|
||||
|
||||
App app(argc, argv);
|
||||
app.startInCurrentThread();
|
||||
|
||||
return app.getAppResult();
|
||||
}
|
||||
49
mon/source/app/SignalHandler.cpp
Normal file
49
mon/source/app/SignalHandler.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include "SignalHandler.h"
|
||||
|
||||
#include <common/app/log/Logger.h>
|
||||
#include <app/App.h>
|
||||
|
||||
#include <csignal>
|
||||
|
||||
App* SignalHandler::app = nullptr;
|
||||
|
||||
void SignalHandler::registerSignalHandler(App* app)
|
||||
{
|
||||
SignalHandler::app = app;
|
||||
signal(SIGINT, SignalHandler::handle);
|
||||
signal(SIGTERM, SignalHandler::handle);
|
||||
}
|
||||
|
||||
|
||||
void SignalHandler::handle(int sig)
|
||||
{
|
||||
// reset signal handling to default
|
||||
signal(sig, SIG_DFL);
|
||||
|
||||
if (Logger::isInitialized())
|
||||
{
|
||||
switch(sig)
|
||||
{
|
||||
case SIGINT:
|
||||
{
|
||||
LOG(GENERAL, CRITICAL, "Received a SIGINT. Shutting down...");
|
||||
} break;
|
||||
|
||||
case SIGTERM:
|
||||
{
|
||||
LOG(GENERAL, CRITICAL, "Received a SIGTERM. Shutting down...");
|
||||
} break;
|
||||
|
||||
default:
|
||||
{
|
||||
// shouldn't happen
|
||||
LOG(GENERAL, CRITICAL, "Received an unknown signal. Shutting down...");
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
if (app != nullptr)
|
||||
{
|
||||
app->stopComponents();
|
||||
}
|
||||
}
|
||||
16
mon/source/app/SignalHandler.h
Normal file
16
mon/source/app/SignalHandler.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef SIGNAL_HANDLER_H_
|
||||
#define SIGNAL_HANDLER_H_
|
||||
|
||||
class App;
|
||||
|
||||
class SignalHandler
|
||||
{
|
||||
public:
|
||||
static void registerSignalHandler(App* app);
|
||||
static void handle(int sig);
|
||||
|
||||
private:
|
||||
static App* app;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user