mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-16 01:51:45 +00:00
Single Logger implementation for FairLogger & FairMQLogger
This commit is contained in:
committed by
Mohammad Al-Turany
parent
d3e0b9fc97
commit
4e942e489b
@@ -73,11 +73,11 @@ FairMQMap XML::UserParser(stringstream& input, const string& deviceId, const str
|
||||
namespace Helper
|
||||
{
|
||||
|
||||
void PrintDeviceList(const boost::property_tree::ptree& tree, const std::string& formatFlag)
|
||||
void PrintDeviceList(const boost::property_tree::ptree& tree, const string& formatFlag)
|
||||
{
|
||||
string deviceIdKey;
|
||||
|
||||
// do a first loop just to print the device-id in json input
|
||||
// do a first loop just to print the device-id in json input
|
||||
for (const auto& p : tree)
|
||||
{
|
||||
if (p.first == "devices")
|
||||
@@ -88,23 +88,23 @@ void PrintDeviceList(const boost::property_tree::ptree& tree, const std::string&
|
||||
if (key != "")
|
||||
{
|
||||
deviceIdKey = key;
|
||||
LOG(TRACE) << "Found config for device key '" << deviceIdKey << "' in JSON input";
|
||||
LOG(DEBUG) << "Found config for device key '" << deviceIdKey << "' in JSON input";
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceIdKey = q.second.get<string>("id");
|
||||
LOG(TRACE) << "Found config for device id '" << deviceIdKey << "' in JSON input";
|
||||
LOG(DEBUG) << "Found config for device id '" << deviceIdKey << "' in JSON input";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p.first == "device")
|
||||
{
|
||||
//get id attribute to choose the device
|
||||
// get id attribute to choose the device
|
||||
if (formatFlag == "xml")
|
||||
{
|
||||
deviceIdKey = p.second.get<string>("<xmlattr>.id");
|
||||
LOG(TRACE) << "Found config for '" << deviceIdKey << "' in XML input";
|
||||
LOG(DEBUG) << "Found config for '" << deviceIdKey << "' in XML input";
|
||||
}
|
||||
|
||||
if (formatFlag == "json")
|
||||
@@ -113,12 +113,12 @@ void PrintDeviceList(const boost::property_tree::ptree& tree, const std::string&
|
||||
if (key != "")
|
||||
{
|
||||
deviceIdKey = key;
|
||||
LOG(TRACE) << "Found config for device key '" << deviceIdKey << "' in JSON input";
|
||||
LOG(DEBUG) << "Found config for device key '" << deviceIdKey << "' in JSON input";
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceIdKey = p.second.get<string>("id");
|
||||
LOG(TRACE) << "Found config for device id '" << deviceIdKey << "' in JSON input";
|
||||
LOG(DEBUG) << "Found config for device id '" << deviceIdKey << "' in JSON input";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -428,7 +428,7 @@ void SocketParser(const boost::property_tree::ptree& tree, vector<FairMQChannel>
|
||||
void PrintPropertyTree(const boost::property_tree::ptree& tree, int level)
|
||||
{
|
||||
for (const auto& p : tree) {
|
||||
std::cout << std::setw(level+1) << level << ": " << p.first << " " << p.second.get_value<string>() << std::endl;
|
||||
cout << setw(level+1) << level << ": " << p.first << " " << p.second.get_value<string>() << endl;
|
||||
PrintPropertyTree(p.second.get_child(""), level + 1);
|
||||
}
|
||||
}
|
||||
|
@@ -8,30 +8,27 @@
|
||||
/*
|
||||
* File: FairMQProgOptions.cxx
|
||||
* Author: winckler
|
||||
*
|
||||
*
|
||||
* Created on March 11, 2015, 10:20 PM
|
||||
*/
|
||||
|
||||
#include "FairMQProgOptions.h"
|
||||
#include <algorithm>
|
||||
#include "FairMQParser.h"
|
||||
#include "FairMQSuboptParser.h"
|
||||
#include "FairMQLogger.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
FairMQProgOptions::FairMQProgOptions()
|
||||
: FairProgOptions()
|
||||
, fMQParserOptions("MQ-Device parser options")
|
||||
, fMQOptionsInCfg("MQ-Device options")
|
||||
, fMQOptionsInCmd("MQ-Device options")
|
||||
, fMQParserOptions("FairMQ config parser options")
|
||||
, fMQCmdOptions("FairMQ device options")
|
||||
, fFairMQMap()
|
||||
, fHelpTitle("***** FAIRMQ Program Options ***** ")
|
||||
, fVersion("Beta version 0.1")
|
||||
, fChannelInfo()
|
||||
, fMQKeyMap()
|
||||
// , fSignalMap() //string API
|
||||
{
|
||||
}
|
||||
|
||||
@@ -39,86 +36,51 @@ FairMQProgOptions::~FairMQProgOptions()
|
||||
{
|
||||
}
|
||||
|
||||
void FairMQProgOptions::ParseAll(const std::vector<std::string>& cmdLineArgs, bool allowUnregistered)
|
||||
int FairMQProgOptions::ParseAll(const vector<string>& cmdLineArgs, bool allowUnregistered)
|
||||
{
|
||||
std::vector<const char*> argv(cmdLineArgs.size());
|
||||
vector<const char*> argv(cmdLineArgs.size());
|
||||
|
||||
std::transform(cmdLineArgs.begin(), cmdLineArgs.end(), argv.begin(), [](const std::string& str)
|
||||
transform(cmdLineArgs.begin(), cmdLineArgs.end(), argv.begin(), [](const string& str)
|
||||
{
|
||||
return str.c_str();
|
||||
});
|
||||
|
||||
ParseAll(argv.size(), const_cast<char**>(argv.data()), allowUnregistered);
|
||||
return ParseAll(argv.size(), const_cast<char**>(argv.data()), allowUnregistered);
|
||||
}
|
||||
|
||||
void FairMQProgOptions::ParseAll(const int argc, char const* const* argv, bool allowUnregistered)
|
||||
int FairMQProgOptions::ParseAll(const int argc, char const* const* argv, bool allowUnregistered)
|
||||
{
|
||||
// init description
|
||||
InitOptionDescription();
|
||||
// parse command line options
|
||||
|
||||
if (FairProgOptions::ParseCmdLine(argc, argv, fCmdLineOptions, fVarMap, allowUnregistered))
|
||||
{
|
||||
// ParseCmdLine return 0 if help or version cmd not called. return 1 if called
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
// if txt/INI configuration file enabled then parse it as well
|
||||
if (fUseConfigFile)
|
||||
{
|
||||
// check if file exist
|
||||
if (fs::exists(fConfigFile))
|
||||
{
|
||||
if (FairProgOptions::ParseCfgFile(fConfigFile.string(), fConfigFileOptions, fVarMap, allowUnregistered))
|
||||
{
|
||||
// ParseCfgFile return -1 if cannot open or read config file. It return 0 otherwise
|
||||
LOG(ERROR) << "Could not parse config";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(ERROR) << "config file '" << fConfigFile << "' not found";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (fVarMap.count("print-options"))
|
||||
{
|
||||
PrintOptionsRaw();
|
||||
exit(EXIT_SUCCESS);
|
||||
// ParseCmdLine returns 0 if no immediate switches found.
|
||||
return 1;
|
||||
}
|
||||
|
||||
// if these options are provided, do no further checks and let the device handle them
|
||||
if (fVarMap.count("print-channels") || fVarMap.count("version"))
|
||||
{
|
||||
fair::mq::logger::DefaultConsoleSetFilter(fSeverityMap.at("NOLOG"));
|
||||
return;
|
||||
fair::Logger::SetConsoleSeverity("nolog");
|
||||
return 0;
|
||||
}
|
||||
|
||||
string severity = GetValue<string>("severity");
|
||||
string logFile = GetValue<string>("log-to-file");
|
||||
bool color = GetValue<bool>("color");
|
||||
|
||||
string verbosity = GetValue<string>("verbosity");
|
||||
string logFile = GetValue<string>("log-to-file");
|
||||
bool color = GetValue<bool>("log-color");
|
||||
|
||||
// check if the provided verbosity level is valid, otherwise set to DEBUG
|
||||
if (fSeverityMap.count(verbosity) == 0)
|
||||
{
|
||||
LOG(ERROR) << " verbosity level '" << verbosity << "' unknown, it will be set to DEBUG";
|
||||
verbosity = "DEBUG";
|
||||
}
|
||||
fair::Logger::SetVerbosity(verbosity);
|
||||
|
||||
if (logFile != "")
|
||||
{
|
||||
fair::mq::logger::ReinitLogger(false, logFile, fSeverityMap.at(verbosity));
|
||||
fair::mq::logger::DefaultConsoleSetFilter(fSeverityMap.at("NOLOG"));
|
||||
fair::Logger::InitFileSink(logFile, severity);
|
||||
fair::Logger::SetConsoleSeverity("nolog");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!color)
|
||||
{
|
||||
fair::mq::logger::ReinitLogger(false);
|
||||
}
|
||||
|
||||
fair::mq::logger::DefaultConsoleSetFilter(fSeverityMap.at(verbosity));
|
||||
fair::Logger::SetConsoleColor(color);
|
||||
fair::Logger::SetConsoleSeverity(severity);
|
||||
}
|
||||
|
||||
// check if one of required MQ config option is there
|
||||
@@ -140,9 +102,9 @@ void FairMQProgOptions::ParseAll(const int argc, char const* const* argv, bool a
|
||||
LOG(WARN) << "FairMQProgOptions: no channels configuration provided via neither of:";
|
||||
for (const auto& p : MQParserKeys)
|
||||
{
|
||||
LOG(WARN) << " --" << p;
|
||||
LOG(WARNING) << " --" << p;
|
||||
}
|
||||
LOG(WARN) << "No channels will be created (You can create them manually).";
|
||||
LOG(warn) << "No channels will be created (You can create them manually).";
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -180,10 +142,8 @@ void FairMQProgOptions::ParseAll(const int argc, char const* const* argv, bool a
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(ERROR) << "mq-config command line called but file extension '"
|
||||
<< ext
|
||||
<< "' not recognized. Program will now exit";
|
||||
exit(EXIT_FAILURE);
|
||||
LOG(error) << "mq-config command line called but file extension '" << ext << "' not recognized. Program will now exit";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,6 +173,8 @@ void FairMQProgOptions::ParseAll(const int argc, char const* const* argv, bool a
|
||||
}
|
||||
|
||||
FairProgOptions::PrintOptions();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FairMQProgOptions::Store(const FairMQMap& channels)
|
||||
@@ -237,7 +199,7 @@ void FairMQProgOptions::UpdateChannelInfo()
|
||||
fChannelInfo.clear();
|
||||
for (const auto& c : fFairMQMap)
|
||||
{
|
||||
fChannelInfo.insert(std::make_pair(c.first, c.second.size()));
|
||||
fChannelInfo.insert(make_pair(c.first, c.second.size()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,104 +237,64 @@ void FairMQProgOptions::UpdateMQValues()
|
||||
UpdateVarMap<string>(methodKey, channel.GetMethod());
|
||||
UpdateVarMap<string>(addressKey, channel.GetAddress());
|
||||
UpdateVarMap<string>(transportKey, channel.GetTransport());
|
||||
|
||||
//UpdateVarMap<string>(sndBufSizeKey, to_string(channel.GetSndBufSize()));// string API
|
||||
UpdateVarMap<int>(sndBufSizeKey, channel.GetSndBufSize());
|
||||
|
||||
//UpdateVarMap<string>(rcvBufSizeKey, to_string(channel.GetRcvBufSize()));// string API
|
||||
UpdateVarMap<int>(rcvBufSizeKey, channel.GetRcvBufSize());
|
||||
|
||||
//UpdateVarMap<string>(sndKernelSizeKey, to_string(channel.GetSndKernelSize()));// string API
|
||||
UpdateVarMap<int>(sndKernelSizeKey, channel.GetSndKernelSize());
|
||||
|
||||
//UpdateVarMap<string>(rcvKernelSizeKey, to_string(channel.GetRcvKernelSize()));// string API
|
||||
UpdateVarMap<int>(rcvKernelSizeKey, channel.GetRcvKernelSize());
|
||||
|
||||
//UpdateVarMap<string>(rateLoggingKey,to_string(channel.GetRateLogging()));// string API
|
||||
UpdateVarMap<int>(rateLoggingKey, channel.GetRateLogging());
|
||||
|
||||
/*
|
||||
LOG(DEBUG) << "Update MQ parameters of variable map";
|
||||
LOG(DEBUG) << "key = " << typeKey <<"\t value = " << GetValue<string>(typeKey);
|
||||
LOG(DEBUG) << "key = " << methodKey <<"\t value = " << GetValue<string>(methodKey);
|
||||
LOG(DEBUG) << "key = " << addressKey <<"\t value = " << GetValue<string>(addressKey);
|
||||
LOG(DEBUG) << "key = " << sndBufSizeKey << "\t value = " << GetValue<int>(sndBufSizeKey);
|
||||
LOG(DEBUG) << "key = " << rcvBufSizeKey <<"\t value = " << GetValue<int>(rcvBufSizeKey);
|
||||
LOG(DEBUG) << "key = " << sndKernelSizeKey << "\t value = " << GetValue<int>(sndKernelSizeKey);
|
||||
LOG(DEBUG) << "key = " << rcvKernelSizeKey <<"\t value = " << GetValue<int>(rcvKernelSizeKey);
|
||||
LOG(DEBUG) << "key = " << rateLoggingKey <<"\t value = " << GetValue<int>(rateLoggingKey);
|
||||
*/
|
||||
index++;
|
||||
}
|
||||
UpdateVarMap<int>(p.first + ".numSockets", index);
|
||||
UpdateVarMap<int>("chans." + p.first + ".numSockets", index);
|
||||
}
|
||||
}
|
||||
|
||||
int FairMQProgOptions::NotifySwitchOption()
|
||||
int FairMQProgOptions::ImmediateOptions()
|
||||
{
|
||||
if (fVarMap.count("help"))
|
||||
{
|
||||
std::cout << fHelpTitle << std::endl << fVisibleOptions;
|
||||
cout << "===== FairMQ Program Options =====" << endl << fVisibleOptions;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fVarMap.count("print-options"))
|
||||
{
|
||||
PrintOptionsRaw();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FairMQProgOptions::FillOptionDescription(boost::program_options::options_description& options)
|
||||
{
|
||||
options.add_options()
|
||||
("id", po::value<string>(), "Device ID (required argument).")
|
||||
("io-threads", po::value<int >()->default_value(1), "Number of I/O threads.")
|
||||
("transport", po::value<string>()->default_value("zeromq"), "Transport ('zeromq'/'nanomsg').")
|
||||
("config", po::value<string>()->default_value("static"), "Config source ('static'/<config library filename>).")
|
||||
("network-interface", po::value<string>()->default_value("default"), "Network interface to bind on (e.g. eth0, ib0..., default will try to detect the interface of the default route).")
|
||||
("config-key", po::value<string>(), "Use provided value instead of device id for fetching the configuration from the config file.")
|
||||
("catch-signals", po::value<int >()->default_value(1), "Enable signal handling (1/0).")
|
||||
("initialization-timeout", po::value<int >()->default_value(120), "Timeout for the initialization in seconds (when expecting dynamic initialization).")
|
||||
("port-range-min", po::value<int >()->default_value(22000), "Start of the port range for dynamic initialization.")
|
||||
("port-range-max", po::value<int >()->default_value(32000), "End of the port range for dynamic initialization.")
|
||||
("log-to-file", po::value<string>()->default_value(""), "Log output to a file.")
|
||||
("print-channels", po::value<bool >()->implicit_value(true), "Print registered channel endpoints in a machine-readable format (<channel name>:<min num subchannels>:<max num subchannels>)")
|
||||
("shm-segment-size", po::value<size_t>()->default_value(2000000000), "Shared memory: size of the shared memory segment (in bytes).")
|
||||
("rate", po::value<float >()->default_value(0.), "Rate for conditional run loop (Hz).")
|
||||
("session", po::value<string>()->default_value("default"), "Session name.")
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
void FairMQProgOptions::InitOptionDescription()
|
||||
{
|
||||
// Id required in command line if config txt file not enabled
|
||||
if (fUseConfigFile)
|
||||
{
|
||||
FillOptionDescription(fMQOptionsInCmd);
|
||||
|
||||
FillOptionDescription(fMQOptionsInCfg);
|
||||
}
|
||||
else
|
||||
{
|
||||
FillOptionDescription(fMQOptionsInCmd);
|
||||
}
|
||||
fMQCmdOptions.add_options()
|
||||
("id", po::value<string>(), "Device ID (required argument).")
|
||||
("io-threads", po::value<int >()->default_value(1), "Number of I/O threads.")
|
||||
("transport", po::value<string>()->default_value("zeromq"), "Transport ('zeromq'/'nanomsg').")
|
||||
("config", po::value<string>()->default_value("static"), "Config source ('static'/<config library filename>).")
|
||||
("network-interface", po::value<string>()->default_value("default"), "Network interface to bind on (e.g. eth0, ib0..., default will try to detect the interface of the default route).")
|
||||
("config-key", po::value<string>(), "Use provided value instead of device id for fetching the configuration from the config file.")
|
||||
("initialization-timeout", po::value<int >()->default_value(120), "Timeout for the initialization in seconds (when expecting dynamic initialization).")
|
||||
("port-range-min", po::value<int >()->default_value(22000), "Start of the port range for dynamic initialization.")
|
||||
("port-range-max", po::value<int >()->default_value(32000), "End of the port range for dynamic initialization.")
|
||||
("log-to-file", po::value<string>()->default_value(""), "Log output to a file.")
|
||||
("print-channels", po::value<bool >()->implicit_value(true), "Print registered channel endpoints in a machine-readable format (<channel name>:<min num subchannels>:<max num subchannels>)")
|
||||
("shm-segment-size", po::value<size_t>()->default_value(2000000000), "Shared memory: size of the shared memory segment (in bytes).")
|
||||
("rate", po::value<float >()->default_value(0.), "Rate for conditional run loop (Hz).")
|
||||
("session", po::value<string>()->default_value("default"), "Session name.")
|
||||
;
|
||||
|
||||
fMQParserOptions.add_options()
|
||||
("config-xml-string", po::value<vector<string>>()->multitoken(), "XML input as command line string.")
|
||||
// ("config-xml-file", po::value<string>(), "XML input as file.")
|
||||
("config-json-string", po::value<vector<string>>()->multitoken(), "JSON input as command line string.")
|
||||
// ("config-json-file", po::value<string>(), "JSON input as file.")
|
||||
("mq-config", po::value<string>(), "JSON/XML input as file. The configuration object will check xml or json file extention and will call the json or xml parser accordingly")
|
||||
(FairMQParser::SUBOPT::OptionKeyChannelConfig, po::value<std::vector<std::string>>()->multitoken()->composing(), "Configuration of single or multiple channel(s) by comma separated key=value list")
|
||||
(FairMQParser::SUBOPT::OptionKeyChannelConfig, po::value<vector<string>>()->multitoken()->composing(), "Configuration of single or multiple channel(s) by comma separated key=value list")
|
||||
;
|
||||
|
||||
AddToCmdLineOptions(fGenericDesc);
|
||||
AddToCmdLineOptions(fMQOptionsInCmd);
|
||||
AddToCmdLineOptions(fGeneralDesc);
|
||||
AddToCmdLineOptions(fMQCmdOptions);
|
||||
AddToCmdLineOptions(fMQParserOptions);
|
||||
|
||||
if (fUseConfigFile)
|
||||
{
|
||||
AddToCfgFileOptions(fMQOptionsInCfg, false);
|
||||
AddToCfgFileOptions(fMQParserOptions, false);
|
||||
}
|
||||
}
|
||||
|
||||
int FairMQProgOptions::UpdateChannelMap(const string& channelName, int index, const string& member, const string& val)
|
||||
@@ -409,45 +331,6 @@ int FairMQProgOptions::UpdateChannelMap(const string& channelName, int index, co
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// string API
|
||||
int FairMQProgOptions::UpdateChannelMap(const string& channelName, int index, const string& member, const string& val)
|
||||
{
|
||||
if (member == "type")
|
||||
{
|
||||
fFairMQMap.at(channelName).at(index).UpdateType(val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (member == "method")
|
||||
{
|
||||
fFairMQMap.at(channelName).at(index).UpdateMethod(val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (member == "address")
|
||||
{
|
||||
fFairMQMap.at(channelName).at(index).UpdateAddress(val);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (member == "sndBufSize" || member == "rcvBufSize" || member == "rateLogging")
|
||||
{
|
||||
UpdateChannelMap(channelName,index,member,ConvertTo<int>(val));
|
||||
}
|
||||
|
||||
//if we get there it means something is wrong
|
||||
LOG(ERROR) << "update of FairMQChannel map failed for the following key: "
|
||||
<< channelName<<"."<<index<<"."<<member;
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
int FairMQProgOptions::UpdateChannelMap(const string& channelName, int index, const string& member, int val)
|
||||
{
|
||||
if (member == "sndBufSize")
|
||||
@@ -469,9 +352,8 @@ int FairMQProgOptions::UpdateChannelMap(const string& channelName, int index, co
|
||||
}
|
||||
else
|
||||
{
|
||||
//if we get there it means something is wrong
|
||||
LOG(ERROR) << "update of FairMQChannel map failed for the following key: "
|
||||
<< channelName << "." << index << "." << member;
|
||||
// if we get there it means something is wrong
|
||||
LOG(ERROR) << "update of FairMQChannel map failed for the following key: " << channelName << "." << index << "." << member;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@@ -18,16 +18,15 @@
|
||||
|
||||
#include <fairmq/EventManager.h>
|
||||
|
||||
#include "FairProgOptions.h"
|
||||
#include "FairMQChannel.h"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
#include "FairProgOptions.h"
|
||||
#include "FairMQChannel.h"
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
@@ -43,17 +42,15 @@ class FairMQProgOptions : public FairProgOptions
|
||||
{
|
||||
protected:
|
||||
using FairMQMap = std::unordered_map<std::string, std::vector<FairMQChannel>>;
|
||||
//using signal_type = boost::signals2::signal<void(const std::string&, const std::string&)>;// string API
|
||||
//using signal_type_ptr = boost::shared_ptr<signal_type>;// string API
|
||||
|
||||
public:
|
||||
FairMQProgOptions();
|
||||
virtual ~FairMQProgOptions();
|
||||
|
||||
void ParseAll(const std::vector<std::string>& cmdLineArgs, bool allowUnregistered);
|
||||
// parse command line and txt/INI configuration file.
|
||||
int ParseAll(const std::vector<std::string>& cmdLineArgs, bool allowUnregistered);
|
||||
// parse command line.
|
||||
// default parser for the mq-configuration file (JSON/XML) is called if command line key mq-config is called
|
||||
virtual void ParseAll(const int argc, char const* const* argv, bool allowUnregistered = false);
|
||||
int ParseAll(const int argc, char const* const* argv, bool allowUnregistered = false) override;
|
||||
|
||||
// external parser, store function
|
||||
template <typename T, typename ...Args>
|
||||
@@ -81,93 +78,11 @@ class FairMQProgOptions : public FairProgOptions
|
||||
return fChannelInfo;
|
||||
}
|
||||
|
||||
// to customize title of the executable help command line
|
||||
void SetHelpTitle(const std::string& title)
|
||||
{
|
||||
fHelpTitle = title;
|
||||
}
|
||||
// to customize the executable version command line
|
||||
void SetVersion(const std::string& version)
|
||||
{
|
||||
fVersion = version;
|
||||
}
|
||||
|
||||
// store key-value of type T into variable_map.
|
||||
// store key-value of type T into variable_map.
|
||||
// If key is found in fMQKeyMap, update the FairMQChannelMap accordingly
|
||||
// Note that the fMQKeyMap is filled:
|
||||
// - if UpdateChannelMap(const FairMQMap& map) method is called
|
||||
// - if UpdateChannelMap(const FairMQMap& map) method is called
|
||||
// - if UserParser template method is called (it is called in the ParseAll method if json or xml MQ-config files is provided)
|
||||
|
||||
|
||||
/* // string API
|
||||
|
||||
//overload for string literal
|
||||
int UpdateValue(const std::string& key, const char* val) // string API
|
||||
{
|
||||
UpdateValue(key,std::string(val));
|
||||
return 0;
|
||||
}
|
||||
// overload for string values
|
||||
int UpdateValue(const std::string& key, const std::string& val) // string API
|
||||
{
|
||||
try
|
||||
{
|
||||
if (fVarMap.count(key))
|
||||
{
|
||||
|
||||
|
||||
if (!FairMQ::is_this_type<std::string>(fVarMap.at(key)))
|
||||
{
|
||||
LOG(ERROR) << "You try to update a value as string (for key="<< key <<") while it has been defined with a different type in the option description.";
|
||||
abort();
|
||||
}
|
||||
|
||||
// update variable map
|
||||
UpdateVarMap(key,val);
|
||||
|
||||
if (fMQKeyMap.count(key))
|
||||
{
|
||||
std::string channelName;
|
||||
int index = 0;
|
||||
std::string member;
|
||||
std::tie(channelName, index, member) = fMQKeyMap.at(key);
|
||||
UpdateChannelMap(channelName, index, member, val);
|
||||
}
|
||||
|
||||
// execute stored function of a given key if exist
|
||||
//if (std::is_same<T, int>::value || std::is_same<T, std::string>::value)//if one wants to restrict type
|
||||
if (fSignalMap.count(key))
|
||||
EmitUpdate(key,val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
LOG(ERROR) <<"UpdatedValue failed because the provided key '"
|
||||
<<key
|
||||
<<"' is not found in the variable map";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
LOG(ERROR) << "Caught exception on key "<<key;
|
||||
abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//overload for string literal
|
||||
/*int UpdateValue(const std::string& key, const char* val) // string API
|
||||
{
|
||||
UpdateValue<std::string>(key,val);
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
|
||||
// specialization/overloading for string, pass by const ref
|
||||
int UpdateValue(const std::string& key, const std::string& val) // string API
|
||||
@@ -214,9 +129,7 @@ class FairMQProgOptions : public FairProgOptions
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(ERROR) << "UpdatedValue failed because the provided key '"
|
||||
<< key
|
||||
<< "' is not found in the variable map";
|
||||
LOG(error) << "UpdateValue failed: key '" << key << "' not found in the variable map";
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -284,30 +197,14 @@ class FairMQProgOptions : public FairProgOptions
|
||||
|
||||
fEvents.Unsubscribe<fair::mq::PropertyChangeAsString, std::string>(subscriber);
|
||||
}
|
||||
/*
|
||||
template <typename F>
|
||||
void Subscribe(const std::string& key, F&& func)
|
||||
{
|
||||
if (fVarMap.count(key))
|
||||
{
|
||||
//if key-value not yet found, then add it
|
||||
if (fSignalMap.find(key) == fSignalMap.end())
|
||||
fSignalMap.emplace(key, boost::make_shared<signal_type>());
|
||||
(*fSignalMap.at(key)).connect(std::forward<F>(func));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// replace FairMQChannelMap, and update variable map accordingly
|
||||
int UpdateChannelMap(const FairMQMap& map);
|
||||
|
||||
protected:
|
||||
po::options_description fMQCmdOptions;
|
||||
po::options_description fMQParserOptions;
|
||||
po::options_description fMQOptionsInCfg;
|
||||
po::options_description fMQOptionsInCmd;
|
||||
FairMQMap fFairMQMap;
|
||||
std::string fHelpTitle;
|
||||
std::string fVersion;
|
||||
|
||||
// map of read channel info - channel name - number of subchannels
|
||||
std::unordered_map<std::string, int> fChannelInfo;
|
||||
@@ -315,36 +212,20 @@ class FairMQProgOptions : public FairProgOptions
|
||||
using MQKey = std::tuple<std::string, int, std::string>;//store key info
|
||||
std::map<std::string, MQKey> fMQKeyMap;// key=full path - val=key info
|
||||
|
||||
virtual int NotifySwitchOption(); // for custom help & version printing
|
||||
int ImmediateOptions() override; // for custom help & version printing
|
||||
void InitOptionDescription();
|
||||
|
||||
// fill boost option description with the standard options
|
||||
static void FillOptionDescription(po::options_description& options);
|
||||
|
||||
// read FairMQChannelMap and insert/update corresponding values in variable map
|
||||
// create key for variable map as follow : channelName.index.memberName
|
||||
void UpdateMQValues();
|
||||
int Store(const FairMQMap& channels);
|
||||
|
||||
private:
|
||||
/*
|
||||
// string API
|
||||
std::map<std::string, signal_type_ptr > fSignalMap;
|
||||
void EmitUpdate(const std::string& key, const char* val)
|
||||
{
|
||||
EmitUpdate(key,std::string(val));
|
||||
}
|
||||
void EmitUpdate(const std::string& key, const std::string& val)
|
||||
{
|
||||
(*fSignalMap.at(key))(key,val);
|
||||
}
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
void EmitUpdate(const std::string& key, T val)
|
||||
{
|
||||
//compile time check whether T is const char* or char*, and in that case a compile time error is thrown.
|
||||
static_assert(!std::is_same<T,const char*>::value || !std::is_same<T, char*>::value,
|
||||
static_assert(!std::is_same<T,const char*>::value || !std::is_same<T, char*>::value,
|
||||
"In template member FairMQProgOptions::EmitUpdate<T>(key,val) the types const char* or char* for the calback signatures are not supported.");
|
||||
fEvents.Emit<fair::mq::PropertyChange, T>(key, val);
|
||||
fEvents.Emit<fair::mq::PropertyChangeAsString, std::string>(key, GetStringValue(key));
|
||||
|
@@ -15,49 +15,30 @@
|
||||
#include "FairProgOptions.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
FairProgOptions::FairProgOptions() :
|
||||
fVarMap(),
|
||||
fGenericDesc("Generic options description"),
|
||||
fConfigDesc("Configuration options description"),
|
||||
fEnvironmentDesc("Environment variables"),
|
||||
fHiddenDesc("Hidden options description"),
|
||||
fCmdLineOptions("Command line options"),
|
||||
fConfigFileOptions("Configuration file options"),
|
||||
fSeverityMap(),
|
||||
fVisibleOptions("Visible options"),
|
||||
fConfigMutex(),
|
||||
fVerbosityLevel("INFO"),
|
||||
fUseConfigFile(false),
|
||||
fConfigFile()
|
||||
FairProgOptions::FairProgOptions()
|
||||
: fVarMap()
|
||||
, fGeneralDesc("General options")
|
||||
, fCmdLineOptions("Command line options")
|
||||
, fVisibleOptions("Visible options")
|
||||
, fConfigMutex()
|
||||
{
|
||||
|
||||
LOG(NOLOG) << "";// temporary hack to prevent throwing exception when accessing empty sinklist --> fixed me
|
||||
fGenericDesc.add_options()
|
||||
fGeneralDesc.add_options()
|
||||
("help,h", "produce help")
|
||||
("version,v", "print version")
|
||||
("verbosity", po::value<std::string>(&fVerbosityLevel)->default_value("DEBUG"), "Verbosity level : TRACE, DEBUG, RESULTS, INFO, WARN, ERROR, STATE, NOLOG")
|
||||
("log-color", po::value<bool>()->default_value(true), "logger color: true or false")
|
||||
("severity", po::value<string>()->default_value("debug"), "Log severity level : trace, debug, info, state, warn, error, fatal, nolog")
|
||||
("verbosity", po::value<string>()->default_value("medium"), "Log verbosity level : veryhigh, high, medium, low")
|
||||
("color", po::value<bool>()->default_value(true), "Log color (true/false)")
|
||||
("print-options", po::value<bool>()->implicit_value(true), "print options in machine-readable format (<option>:<computed-value>:<type>:<description>)");
|
||||
|
||||
fSeverityMap["TRACE"] = fair::mq::logger::SeverityLevel::TRACE;
|
||||
fSeverityMap["DEBUG"] = fair::mq::logger::SeverityLevel::DEBUG;
|
||||
fSeverityMap["RESULTS"] = fair::mq::logger::SeverityLevel::RESULTS;
|
||||
fSeverityMap["INFO"] = fair::mq::logger::SeverityLevel::INFO;
|
||||
fSeverityMap["WARN"] = fair::mq::logger::SeverityLevel::WARN;
|
||||
fSeverityMap["ERROR"] = fair::mq::logger::SeverityLevel::ERROR;
|
||||
fSeverityMap["STATE"] = fair::mq::logger::SeverityLevel::STATE;
|
||||
fSeverityMap["NOLOG"] = fair::mq::logger::SeverityLevel::NOLOG;
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
FairProgOptions::~FairProgOptions()
|
||||
{
|
||||
}
|
||||
|
||||
/// //////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Add option descriptions
|
||||
int FairProgOptions::AddToCmdLineOptions(const po::options_description optDesc, bool visible)
|
||||
{
|
||||
@@ -69,61 +50,11 @@ int FairProgOptions::AddToCmdLineOptions(const po::options_description optDesc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FairProgOptions::AddToCfgFileOptions(const po::options_description optDesc, bool visible)
|
||||
{
|
||||
//if UseConfigFile() not yet called, then enable it with required file name to be provided by command line
|
||||
if (!fUseConfigFile)
|
||||
{
|
||||
UseConfigFile();
|
||||
}
|
||||
|
||||
fConfigFileOptions.add(optDesc);
|
||||
if (visible)
|
||||
{
|
||||
fVisibleOptions.add(optDesc);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//*
|
||||
po::options_description& FairProgOptions::GetCmdLineOptions()
|
||||
{
|
||||
return fCmdLineOptions;
|
||||
}
|
||||
|
||||
po::options_description& FairProgOptions::GetCfgFileOptions()
|
||||
{
|
||||
return fConfigFileOptions;
|
||||
}
|
||||
|
||||
po::options_description& FairProgOptions::GetEnvironmentOptions()
|
||||
{
|
||||
return fEnvironmentDesc;
|
||||
}
|
||||
|
||||
int FairProgOptions::AddToEnvironmentOptions(const po::options_description optDesc)
|
||||
{
|
||||
fEnvironmentDesc.add(optDesc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FairProgOptions::UseConfigFile(const string& filename)
|
||||
{
|
||||
fUseConfigFile = true;
|
||||
if (filename.empty())
|
||||
{
|
||||
fConfigDesc.add_options()
|
||||
("config-file", po::value<boost::filesystem::path>(&fConfigFile)->required(), "Path to configuration file (required argument)");
|
||||
AddToCmdLineOptions(fConfigDesc);
|
||||
}
|
||||
else
|
||||
{
|
||||
fConfigFile = filename;
|
||||
}
|
||||
}
|
||||
|
||||
/// //////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Parser
|
||||
|
||||
int FairProgOptions::ParseCmdLine(const int argc, char const* const* argv, const po::options_description& desc, po::variables_map& varmap, bool allowUnregistered)
|
||||
{
|
||||
// get options from cmd line and store in variable map
|
||||
@@ -140,9 +71,9 @@ int FairProgOptions::ParseCmdLine(const int argc, char const* const* argv, const
|
||||
po::store(po::parse_command_line(argc, argv, desc), varmap);
|
||||
}
|
||||
|
||||
// call the virtual NotifySwitchOption method to handle switch options like e.g. "--help" or "--version"
|
||||
// Handles options like "--help" or "--version"
|
||||
// return 1 if switch options found in varmap
|
||||
if (NotifySwitchOption())
|
||||
if (ImmediateOptions())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@@ -156,89 +87,8 @@ int FairProgOptions::ParseCmdLine(const int argc, char const* const* argv, const
|
||||
return ParseCmdLine(argc, argv, desc, fVarMap, allowUnregistered);
|
||||
}
|
||||
|
||||
int FairProgOptions::ParseCfgFile(ifstream& ifs, const po::options_description& desc, po::variables_map& varmap, bool allowUnregistered)
|
||||
{
|
||||
if (!ifs)
|
||||
{
|
||||
LOG(ERROR) << "can not open configuration file";
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
po::store(parse_config_file(ifs, desc, allowUnregistered), varmap);
|
||||
po::notify(varmap);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FairProgOptions::ParseCfgFile(const string& filename, const po::options_description& desc, po::variables_map& varmap, bool allowUnregistered)
|
||||
{
|
||||
ifstream ifs(filename.c_str());
|
||||
if (!ifs)
|
||||
{
|
||||
LOG(ERROR) << "can not open configuration file: " << filename;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
po::store(parse_config_file(ifs, desc, allowUnregistered), varmap);
|
||||
po::notify(varmap);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FairProgOptions::ParseCfgFile(const string& filename, const po::options_description& desc, bool allowUnregistered)
|
||||
{
|
||||
return ParseCfgFile(filename,desc,fVarMap,allowUnregistered);
|
||||
}
|
||||
|
||||
int FairProgOptions::ParseCfgFile(ifstream& ifs, const po::options_description& desc, bool allowUnregistered)
|
||||
{
|
||||
return ParseCfgFile(ifs,desc,fVarMap,allowUnregistered);
|
||||
}
|
||||
|
||||
int FairProgOptions::ParseEnvironment(const function<string(string)>& environmentMapper)
|
||||
{
|
||||
po::store(po::parse_environment(fEnvironmentDesc, environmentMapper), fVarMap);
|
||||
po::notify(fVarMap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FairProgOptions::PrintHelp() const
|
||||
{
|
||||
cout << fVisibleOptions << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FairProgOptions::PrintOptionsRaw()
|
||||
{
|
||||
MapVarValInfo_t mapInfo;
|
||||
|
||||
for (const auto& m : fVarMap)
|
||||
{
|
||||
mapInfo[m.first] = GetVariableValueInfo(m.second);
|
||||
}
|
||||
|
||||
for (const auto& p : mapInfo)
|
||||
{
|
||||
string keyStr;
|
||||
string valueStr;
|
||||
string typeInfoStr;
|
||||
string defaultStr;
|
||||
string emptyStr;
|
||||
keyStr = p.first;
|
||||
tie(valueStr, typeInfoStr, defaultStr, emptyStr) = p.second;
|
||||
auto option = fCmdLineOptions.find_nothrow(keyStr, false);
|
||||
cout << keyStr << ":" << valueStr << ":" << typeInfoStr << ":" << (option ? option->description() : "<not found>") << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FairProgOptions::PrintOptions()
|
||||
{
|
||||
// //////////////////////////////////
|
||||
// Method to overload.
|
||||
// -> loop over variable map and print its content
|
||||
// -> In this example the following types are supported:
|
||||
@@ -283,20 +133,27 @@ int FairProgOptions::PrintOptions()
|
||||
|
||||
// formatting and printing
|
||||
|
||||
LOG(DEBUG) << setfill ('*') << setw (totalLength + 3) << "*";// +3 because of string " = "
|
||||
string PrintOptionsTitle = " Configuration ";
|
||||
stringstream ss;
|
||||
ss << "\n";
|
||||
|
||||
ss << setfill('*') << setw(totalLength + 3) << "*" << "\n"; // +3 because of string " = "
|
||||
string title = " Configuration ";
|
||||
|
||||
int leftSpaceLength = 0;
|
||||
int rightSpaceLength = 0;
|
||||
int leftTitleShiftLength = 0;
|
||||
int rightTitleShiftLength = 0;
|
||||
|
||||
leftTitleShiftLength = PrintOptionsTitle.length() / 2;
|
||||
leftTitleShiftLength = title.length() / 2;
|
||||
|
||||
if ((PrintOptionsTitle.length()) % 2)
|
||||
if ((title.length()) % 2)
|
||||
{
|
||||
rightTitleShiftLength = leftTitleShiftLength + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
rightTitleShiftLength = leftTitleShiftLength;
|
||||
}
|
||||
|
||||
leftSpaceLength = (totalLength + 3) / 2 - leftTitleShiftLength;
|
||||
if ((totalLength + 3) % 2)
|
||||
@@ -308,11 +165,11 @@ int FairProgOptions::PrintOptions()
|
||||
rightSpaceLength = (totalLength + 3) / 2 - rightTitleShiftLength;
|
||||
}
|
||||
|
||||
LOG(DEBUG) << setfill ('*') << setw(leftSpaceLength) << "*"
|
||||
<< setw(PrintOptionsTitle.length()) << PrintOptionsTitle
|
||||
<< setfill ('*') << setw(rightSpaceLength) << "*";
|
||||
ss << setfill ('*') << setw(leftSpaceLength) << "*"
|
||||
<< setw(title.length()) << title
|
||||
<< setfill ('*') << setw(rightSpaceLength) << "*" << "\n";
|
||||
|
||||
LOG(DEBUG) << setfill ('*') << setw (totalLength+3) << "*";
|
||||
ss << setfill ('*') << setw (totalLength+3) << "*" << "\n";
|
||||
|
||||
for (const auto& p : mapinfo)
|
||||
{
|
||||
@@ -323,36 +180,46 @@ int FairProgOptions::PrintOptions()
|
||||
string emptyStr;
|
||||
keyStr = p.first;
|
||||
tie(valueStr, typeInfoStr, defaultStr, emptyStr) = p.second;
|
||||
LOG(DEBUG) << std::setfill(' ')
|
||||
<< setw(maxLength1st) << left
|
||||
<< p.first << " = "
|
||||
<< setw(maxLength2nd)
|
||||
<< valueStr
|
||||
<< setw(maxLengthTypeInfo)
|
||||
<< typeInfoStr
|
||||
<< setw(maxLengthDefault)
|
||||
<< defaultStr
|
||||
<< setw(maxLengthEmpty)
|
||||
<< emptyStr;
|
||||
ss << setfill(' ')
|
||||
<< setw(maxLength1st) << left
|
||||
<< p.first << " = "
|
||||
<< setw(maxLength2nd)
|
||||
<< valueStr
|
||||
<< setw(maxLengthTypeInfo)
|
||||
<< typeInfoStr
|
||||
<< setw(maxLengthDefault)
|
||||
<< defaultStr
|
||||
<< setw(maxLengthEmpty)
|
||||
<< emptyStr
|
||||
<< "\n";
|
||||
}
|
||||
LOG(DEBUG) << setfill ('*') << setw (totalLength + 3) << "*";// +3 for " = "
|
||||
ss << setfill ('*') << setw(totalLength + 3) << "*";// +3 for " = "
|
||||
|
||||
LOG(DEBUG) << ss.str();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FairProgOptions::NotifySwitchOption()
|
||||
int FairProgOptions::PrintOptionsRaw()
|
||||
{
|
||||
// Method to overload.
|
||||
if (fVarMap.count("help"))
|
||||
MapVarValInfo_t mapInfo;
|
||||
|
||||
for (const auto& m : fVarMap)
|
||||
{
|
||||
cout << "***** FAIR Program Options ***** \n" << fVisibleOptions;
|
||||
return 1;
|
||||
mapInfo[m.first] = GetVariableValueInfo(m.second);
|
||||
}
|
||||
|
||||
if (fVarMap.count("version"))
|
||||
for (const auto& p : mapInfo)
|
||||
{
|
||||
cout << "alpha version 0.0\n";
|
||||
return 1;
|
||||
string keyStr;
|
||||
string valueStr;
|
||||
string typeInfoStr;
|
||||
string defaultStr;
|
||||
string emptyStr;
|
||||
keyStr = p.first;
|
||||
tie(valueStr, typeInfoStr, defaultStr, emptyStr) = p.second;
|
||||
auto option = fCmdLineOptions.find_nothrow(keyStr, false);
|
||||
cout << keyStr << ":" << valueStr << ":" << typeInfoStr << ":" << (option ? option->description() : "<not found>") << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@@ -16,27 +16,28 @@
|
||||
#define FAIRPROGOPTIONS_H
|
||||
|
||||
#include "FairMQLogger.h"
|
||||
#include "FairProgOptionsHelper.h"
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include "FairProgOptionsHelper.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
#include <mutex>
|
||||
#include <tuple>
|
||||
|
||||
/*
|
||||
* FairProgOptions abstract base class
|
||||
* parse command line, configuration file options as well as environment variables.
|
||||
*
|
||||
* parse command line, configuration file options.
|
||||
*
|
||||
* The user defines in the derived class the option descriptions and
|
||||
* the pure virtual ParseAll() method
|
||||
*
|
||||
*
|
||||
* class MyOptions : public FairProgOptions
|
||||
* {
|
||||
* public :
|
||||
* public :
|
||||
* MyOptions() : FairProgOptions()
|
||||
* {
|
||||
* fCmdlineOptions.add(fGenericDesc);
|
||||
@@ -80,13 +81,7 @@ class FairProgOptions
|
||||
|
||||
// add options_description
|
||||
int AddToCmdLineOptions(const po::options_description optDesc, bool visible = true);
|
||||
int AddToCfgFileOptions(const po::options_description optDesc, bool visible = true);
|
||||
int AddToEnvironmentOptions(const po::options_description optDesc);
|
||||
po::options_description& GetCmdLineOptions();
|
||||
po::options_description& GetCfgFileOptions();
|
||||
po::options_description& GetEnvironmentOptions();
|
||||
|
||||
void UseConfigFile(const std::string& filename = "");
|
||||
|
||||
// get value corresponding to the key
|
||||
template<typename T>
|
||||
@@ -108,9 +103,8 @@ class FairProgOptions
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
LOG(ERROR) << "Exception thrown for the key '" << key << "'";
|
||||
LOG(ERROR) << e.what();
|
||||
this->PrintHelp();
|
||||
LOG(error) << "Exception thrown for the key '" << key << "'";
|
||||
LOG(error) << e.what();
|
||||
}
|
||||
|
||||
return val;
|
||||
@@ -168,44 +162,26 @@ class FairProgOptions
|
||||
int ParseCmdLine(const int argc, char const* const* argv, const po::options_description& desc, po::variables_map& varmap, bool allowUnregistered = false);
|
||||
int ParseCmdLine(const int argc, char const* const* argv, const po::options_description& desc, bool allowUnregistered = false);
|
||||
|
||||
int ParseCfgFile(const std::string& filename, const po::options_description& desc, po::variables_map& varmap, bool allowUnregistered = false);
|
||||
int ParseCfgFile(const std::string& filename, const po::options_description& desc, bool allowUnregistered = false);
|
||||
int ParseCfgFile(std::ifstream& ifs, const po::options_description& desc, po::variables_map& varmap, bool allowUnregistered = false);
|
||||
int ParseCfgFile(std::ifstream& ifs, const po::options_description& desc, bool allowUnregistered = false);
|
||||
|
||||
int ParseEnvironment(const std::function<std::string(std::string)>&);
|
||||
|
||||
virtual void ParseAll(const int argc, char const* const* argv, bool allowUnregistered = false) = 0;// TODO change return type to bool and propagate to executable
|
||||
virtual int ParseAll(const int argc, char const* const* argv, bool allowUnregistered = false) = 0;// TODO change return type to bool and propagate to executable
|
||||
|
||||
virtual int PrintOptions();
|
||||
virtual int PrintOptionsRaw();
|
||||
int PrintHelp() const;
|
||||
|
||||
protected:
|
||||
// options container
|
||||
po::variables_map fVarMap;
|
||||
|
||||
// basic description categories
|
||||
po::options_description fGenericDesc;
|
||||
po::options_description fConfigDesc;
|
||||
po::options_description fEnvironmentDesc;
|
||||
po::options_description fHiddenDesc;
|
||||
po::options_description fGeneralDesc;
|
||||
|
||||
// Description of cmd line and simple configuration file (configuration file like txt, but not like xml json ini)
|
||||
po::options_description fCmdLineOptions;
|
||||
po::options_description fConfigFileOptions;
|
||||
|
||||
// Description which is printed in help command line
|
||||
// to handle logger severity
|
||||
std::map<std::string, fair::mq::logger::SeverityLevel> fSeverityMap;
|
||||
po::options_description fVisibleOptions;
|
||||
|
||||
mutable std::mutex fConfigMutex;
|
||||
|
||||
std::string fVerbosityLevel;
|
||||
bool fUseConfigFile;
|
||||
boost::filesystem::path fConfigFile;
|
||||
virtual int NotifySwitchOption();
|
||||
virtual int ImmediateOptions() = 0;
|
||||
|
||||
// UpdateVarMap() and replace() --> helper functions to modify the value of variable map after calling po::store
|
||||
template<typename T>
|
||||
@@ -227,7 +203,7 @@ class FairProgOptions
|
||||
|
||||
VarValInfo_t GetVariableValueInfo(const po::variable_value& varValue);
|
||||
|
||||
static void Max(int &val, const int &comp)
|
||||
static void Max(int& val, const int& comp)
|
||||
{
|
||||
if (comp > val)
|
||||
{
|
||||
|
@@ -1,48 +1,44 @@
|
||||
|
||||
<fairMQOptions>
|
||||
<device name="merger" id="merger" >
|
||||
<channel name="two_inputs_channel" >
|
||||
<socket name="input1" >
|
||||
<type>pull</type>
|
||||
<method>bind</method>
|
||||
<address>tcp://*:5569</address>
|
||||
<sndBufSize>1000</sndBufSize>
|
||||
<rcvBufSize>1000</rcvBufSize>
|
||||
<rateLogging>1</rateLogging>
|
||||
|
||||
</socket>
|
||||
<socket name="input2" >
|
||||
<type>pull</type>
|
||||
<method>bind</method>
|
||||
<address>tcp://*:5570</address>
|
||||
<sndBufSize>1000</sndBufSize>
|
||||
<rcvBufSize>1000</rcvBufSize>
|
||||
<rateLogging>1</rateLogging>
|
||||
|
||||
</socket>
|
||||
</channel>
|
||||
<channel name="one_output_channel" >
|
||||
<socket name="output1" >
|
||||
<type>push</type>
|
||||
<method>connect</method>
|
||||
<address>tcp://*:5571</address>
|
||||
<sndBufSize>1000</sndBufSize>
|
||||
<rcvBufSize>1000</rcvBufSize>
|
||||
<rateLogging>1</rateLogging>
|
||||
</socket>
|
||||
</channel>
|
||||
<device name="merger" id="merger">
|
||||
<channel name="two_inputs_channel">
|
||||
<socket name="input1">
|
||||
<type>pull</type>
|
||||
<method>bind</method>
|
||||
<address>tcp://*:5569</address>
|
||||
<sndBufSize>1000</sndBufSize>
|
||||
<rcvBufSize>1000</rcvBufSize>
|
||||
<rateLogging>1</rateLogging>
|
||||
</socket>
|
||||
<socket name="input2">
|
||||
<type>pull</type>
|
||||
<method>bind</method>
|
||||
<address>tcp://*:5570</address>
|
||||
<sndBufSize>1000</sndBufSize>
|
||||
<rcvBufSize>1000</rcvBufSize>
|
||||
<rateLogging>1</rateLogging>
|
||||
</socket>
|
||||
</channel>
|
||||
<channel name="one_output_channel">
|
||||
<socket name="output1">
|
||||
<type>push</type>
|
||||
<method>connect</method>
|
||||
<address>tcp://*:5571</address>
|
||||
<sndBufSize>1000</sndBufSize>
|
||||
<rcvBufSize>1000</rcvBufSize>
|
||||
<rateLogging>1</rateLogging>
|
||||
</socket>
|
||||
</channel>
|
||||
</device>
|
||||
<device name="sink" id="sink" >
|
||||
<channel name="one_input" >
|
||||
<socket name="input1" >
|
||||
<type>pull</type>
|
||||
<method>bind</method>
|
||||
<address>tcp://localhost:5571</address>
|
||||
<sndBufSize>1000</sndBufSize>
|
||||
<rcvBufSize>1000</rcvBufSize>
|
||||
<rateLogging>1</rateLogging>
|
||||
</socket>
|
||||
<device name="sink" id="sink">
|
||||
<channel name="one_input">
|
||||
<socket name="input1">
|
||||
<type>pull</type>
|
||||
<method>bind</method>
|
||||
<address>tcp://localhost:5571</address>
|
||||
<sndBufSize>1000</sndBufSize>
|
||||
<rcvBufSize>1000</rcvBufSize>
|
||||
<rateLogging>1</rateLogging>
|
||||
</socket>
|
||||
</channel>
|
||||
</device>
|
||||
</fairMQOptions>
|
||||
|
||||
|
@@ -10,19 +10,13 @@
|
||||
#include "FairMQParser.h"
|
||||
#include "FairMQProgOptions.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// tests
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// Parse xml from file
|
||||
int testXML1(FairMQProgOptions* config)
|
||||
{
|
||||
LOG(INFO)<<"--------- test XML1 ---------\n";
|
||||
std::string filename;
|
||||
std::string XMLrootNode;
|
||||
|
||||
|
||||
filename=config->GetValue<std::string>("config-xml-file");
|
||||
XMLrootNode=config->GetValue<std::string>("xml.config.node.root");
|
||||
std::string id=config->GetValue<std::string>("id");
|
||||
@@ -30,12 +24,11 @@ int testXML1(FairMQProgOptions* config)
|
||||
// other xml parser test
|
||||
config->UserParser<FairMQParser::MQXML2>(filename);
|
||||
config->UserParser<FairMQParser::MQXML3>(filename,"merger");
|
||||
|
||||
|
||||
LOG(INFO)<<"--------- test XML1 end ---------\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Parse xml from command line
|
||||
int testXML2(FairMQProgOptions* config)
|
||||
{
|
||||
@@ -44,14 +37,14 @@ int testXML2(FairMQProgOptions* config)
|
||||
std::string XMLrootNode;
|
||||
std::string id=config->GetValue<std::string>("id");
|
||||
XMLrootNode=config->GetValue<std::string>("xml.config.node.root");
|
||||
|
||||
|
||||
// Note: convert the vector<string> into one string with GetStringValue(key)
|
||||
XML=config->GetStringValue("config-xml-string");
|
||||
|
||||
|
||||
std::stringstream iss;
|
||||
iss << XML;
|
||||
config->UserParser<FairMQParser::XML>(iss,id,XMLrootNode);
|
||||
|
||||
|
||||
LOG(INFO)<<"--------- test XML2 end ---------\n";
|
||||
return 0;
|
||||
}
|
||||
@@ -63,12 +56,12 @@ int testJSON1(FairMQProgOptions* config)
|
||||
std::string filename;
|
||||
std::string JSONrootNode;
|
||||
std::string id=config->GetValue<std::string>("id");
|
||||
|
||||
|
||||
filename=config->GetValue<std::string>("config-json-file");
|
||||
JSONrootNode=config->GetValue<std::string>("json.config.node.root");
|
||||
|
||||
|
||||
config->UserParser<FairMQParser::JSON>(filename,id,JSONrootNode);
|
||||
|
||||
|
||||
LOG(INFO)<<"--------- test JSON1 end ---------\n";
|
||||
return 0;
|
||||
}
|
||||
@@ -81,59 +74,63 @@ int testJSON2(FairMQProgOptions* config)
|
||||
std::string JSONrootNode;
|
||||
std::string id=config->GetValue<std::string>("id");
|
||||
JSONrootNode=config->GetValue<std::string>("json.config.node.root");
|
||||
|
||||
|
||||
// Note: convert the vector<string> into one string with GetStringValue(key)
|
||||
JSON=config->GetStringValue("config-json-string");
|
||||
|
||||
|
||||
std::stringstream iss;
|
||||
iss << JSON;
|
||||
config->UserParser<FairMQParser::JSON>(iss,id,JSONrootNode);
|
||||
|
||||
|
||||
LOG(INFO)<<"--------- test JSON2 end ---------\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
/// main
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
FairMQProgOptions* config= new FairMQProgOptions();
|
||||
try
|
||||
{
|
||||
po::options_description format_desc("XML or JSON input");
|
||||
format_desc.add_options()
|
||||
format_desc.add_options()
|
||||
("xml.config.node.root", po::value<std::string>()->default_value("fairMQOptions"), "xml root node ")
|
||||
("json.config.node.root", po::value<std::string>()->default_value("fairMQOptions"), "json root node ")
|
||||
;
|
||||
|
||||
|
||||
config->AddToCmdLineOptions(format_desc);
|
||||
|
||||
// Parse command line
|
||||
if(config->ParseAll(argc,argv))
|
||||
if (config->ParseAll(argc,argv))
|
||||
{
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
// Set severity level (Default is 0=DEBUG)
|
||||
int verbosity = config->GetValue<int>("verbosity");
|
||||
FairMQLogger::Level lvl=static_cast<FairMQLogger::Level>(verbosity);
|
||||
int severity = config->GetValue<int>("severity");
|
||||
FairMQLogger::Level lvl=static_cast<FairMQLogger::Level>(severity);
|
||||
SET_LOGGER_LEVEL(lvl);
|
||||
|
||||
|
||||
|
||||
// Parse xml or json from cmd line or file
|
||||
|
||||
if(config->GetVarMap().count("config-xml-file"))
|
||||
if (config->GetVarMap().count("config-xml-file"))
|
||||
{
|
||||
testXML1(config);
|
||||
|
||||
if(config->GetVarMap().count("config-xml-string"))
|
||||
}
|
||||
|
||||
if (config->GetVarMap().count("config-xml-string"))
|
||||
{
|
||||
testXML2(config);
|
||||
|
||||
if(config->GetVarMap().count("config-json-file"))
|
||||
}
|
||||
|
||||
if (config->GetVarMap().count("config-json-file"))
|
||||
{
|
||||
testJSON1(config);
|
||||
|
||||
if(config->GetVarMap().count("config-json-string"))
|
||||
}
|
||||
|
||||
if (config->GetVarMap().count("config-json-string"))
|
||||
{
|
||||
testJSON2(config);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
@@ -142,9 +139,3 @@ int main(int argc, char** argv)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -15,17 +15,16 @@
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
||||
{
|
||||
try
|
||||
{
|
||||
FairMQProgOptions config;
|
||||
|
||||
|
||||
po::options_description format_desc("XML input");
|
||||
format_desc.add_options()
|
||||
("xml.config.node.root", po::value<std::string>()->default_value("fairMQOptions"), "xml root node ")
|
||||
;
|
||||
|
||||
|
||||
po::options_description io_file_opt_desc("I/O file Options");
|
||||
io_file_opt_desc.add_options()
|
||||
("input.file.name", po::value<std::string>(), "input file name")
|
||||
@@ -38,21 +37,20 @@ int main(int argc, char** argv)
|
||||
|
||||
config.AddToCmdLineOptions(format_desc,true);
|
||||
config.AddToCmdLineOptions(io_file_opt_desc,true);
|
||||
|
||||
|
||||
|
||||
config.EnableCfgFile();// UseConfigFile (by default config file is not defined)
|
||||
config.AddToCfgFileOptions(format_desc,false);//false because already added to visible
|
||||
config.AddToCfgFileOptions(io_file_opt_desc,false);
|
||||
|
||||
|
||||
// Parse command line and config file
|
||||
if(config.ParseAll(argc,argv))
|
||||
return 0;
|
||||
|
||||
|
||||
// Set severity level (Default is 0=DEBUG)
|
||||
int verbosity=config.GetValue<int>("verbosity");
|
||||
FairMQLogger::Level lvl=static_cast<FairMQLogger::Level>(verbosity);
|
||||
int severity = config.GetValue<int>("severity");
|
||||
FairMQLogger::Level lvl = static_cast<FairMQLogger::Level>(severity);
|
||||
SET_LOGGER_LEVEL(lvl);
|
||||
|
||||
|
||||
// parse XML file
|
||||
std::string filename;
|
||||
std::string XMLrootNode;
|
||||
@@ -61,8 +59,6 @@ int main(int argc, char** argv)
|
||||
XMLrootNode=config.GetValue<std::string>("xml.config.node.root");
|
||||
std::string id=config.GetValue<std::string>("id");
|
||||
config.UserParser<FairMQParser::XML>(filename,id,XMLrootNode);
|
||||
|
||||
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
@@ -71,9 +67,3 @@ int main(int argc, char** argv)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -6,6 +6,6 @@ VERBOSE="DEBUG"
|
||||
JSONCONFIGFILE="@CMAKE_BINARY_DIR@/bin/config/ex1-sampler-sink.json"
|
||||
|
||||
########################## start DEVICE
|
||||
DEVICE="runConfigExample --transport $TRANSPORT --verbosity $VERBOSE"
|
||||
DEVICE="runConfigExample --transport $TRANSPORT --severity $VERBOSE"
|
||||
DEVICE+=" --id sampler1 --mq-config $JSONCONFIGFILE"
|
||||
@CMAKE_BINARY_DIR@/bin/$DEVICE
|
||||
|
Reference in New Issue
Block a user