mirror of
https://github.com/FairRootGroup/FairMQ.git
synced 2025-10-13 08:41:16 +00:00
Single Logger implementation for FairLogger & FairMQLogger
This commit is contained in:
parent
d3e0b9fc97
commit
4e942e489b
|
@ -83,7 +83,6 @@ set(FAIRMQ_HEADER_FILES
|
||||||
devices/FairMQProxy.h
|
devices/FairMQProxy.h
|
||||||
devices/FairMQSink.h
|
devices/FairMQSink.h
|
||||||
devices/FairMQSplitter.h
|
devices/FairMQSplitter.h
|
||||||
logger/logger.h
|
|
||||||
options/FairMQParser.h
|
options/FairMQParser.h
|
||||||
options/FairMQProgOptions.h
|
options/FairMQProgOptions.h
|
||||||
options/FairMQSuboptParser.h
|
options/FairMQSuboptParser.h
|
||||||
|
@ -127,13 +126,9 @@ if(NANOMSG_FOUND)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if("${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}" VERSION_LESS "1.56")
|
##########################
|
||||||
set(FAIRMQ_HEADER_FILES_NAMESPACED ${FAIRMQ_HEADER_FILES_NAMESPACED}
|
# libFairMQ source files #
|
||||||
logger/fairroot_null_deleter.h
|
##########################
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
set(FAIRMQ_SOURCE_FILES
|
set(FAIRMQ_SOURCE_FILES
|
||||||
DeviceRunner.cxx
|
DeviceRunner.cxx
|
||||||
FairMQChannel.cxx
|
FairMQChannel.cxx
|
||||||
|
@ -150,7 +145,6 @@ set(FAIRMQ_SOURCE_FILES
|
||||||
devices/FairMQProxy.cxx
|
devices/FairMQProxy.cxx
|
||||||
# devices/FairMQSink.cxx
|
# devices/FairMQSink.cxx
|
||||||
devices/FairMQSplitter.cxx
|
devices/FairMQSplitter.cxx
|
||||||
logger/logger.cxx
|
|
||||||
options/FairMQParser.cxx
|
options/FairMQParser.cxx
|
||||||
options/FairMQProgOptions.cxx
|
options/FairMQProgOptions.cxx
|
||||||
options/FairMQSuboptParser.cxx
|
options/FairMQSuboptParser.cxx
|
||||||
|
@ -208,6 +202,7 @@ add_library(FairMQ SHARED
|
||||||
#######################
|
#######################
|
||||||
target_include_directories(FairMQ
|
target_include_directories(FairMQ
|
||||||
PUBLIC # consumers inherit public include directories
|
PUBLIC # consumers inherit public include directories
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/logger>
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||||
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
|
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
|
||||||
$<INSTALL_INTERFACE:include/fairmq>
|
$<INSTALL_INTERFACE:include/fairmq>
|
||||||
|
@ -224,8 +219,6 @@ target_link_libraries(FairMQ
|
||||||
dl
|
dl
|
||||||
pthread
|
pthread
|
||||||
Boost::boost
|
Boost::boost
|
||||||
Boost::log
|
|
||||||
Boost::log_setup
|
|
||||||
Boost::program_options
|
Boost::program_options
|
||||||
Boost::thread
|
Boost::thread
|
||||||
Boost::system
|
Boost::system
|
||||||
|
@ -233,6 +226,7 @@ target_link_libraries(FairMQ
|
||||||
Boost::regex
|
Boost::regex
|
||||||
Boost::date_time
|
Boost::date_time
|
||||||
Boost::signals
|
Boost::signals
|
||||||
|
Logger
|
||||||
$<$<PLATFORM_ID:Linux>:rt>
|
$<$<PLATFORM_ID:Linux>:rt>
|
||||||
|
|
||||||
PRIVATE # only libFairMQ links against private dependencies
|
PRIVATE # only libFairMQ links against private dependencies
|
||||||
|
|
|
@ -41,7 +41,10 @@ auto DeviceRunner::Run() -> int
|
||||||
fEvents.Emit<hooks::ModifyRawCmdLineArgs>(*this);
|
fEvents.Emit<hooks::ModifyRawCmdLineArgs>(*this);
|
||||||
////////////////////////
|
////////////////////////
|
||||||
|
|
||||||
fConfig.ParseAll(fRawCmdLineArgs, true);
|
if (fConfig.ParseAll(fRawCmdLineArgs, true))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
////// CALL HOOK ///////
|
////// CALL HOOK ///////
|
||||||
fEvents.Emit<hooks::InstantiateDevice>(*this);
|
fEvents.Emit<hooks::InstantiateDevice>(*this);
|
||||||
|
|
|
@ -20,6 +20,6 @@
|
||||||
timestamp_t get_timestamp()
|
timestamp_t get_timestamp()
|
||||||
{
|
{
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
gettimeofday(&now, NULL);
|
gettimeofday(&now, nullptr);
|
||||||
return now.tv_usec + static_cast<timestamp_t>(now.tv_sec) * 1000000;
|
return now.tv_usec + static_cast<timestamp_t>(now.tv_sec) * 1000000;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
* Copyright (C) 2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||||
* *
|
* *
|
||||||
* This software is distributed under the terms of the *
|
* This software is distributed under the terms of the *
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
#ifndef FAIRMQLOGGER_H_
|
#ifndef FAIRMQLOGGER_H_
|
||||||
#define FAIRMQLOGGER_H_
|
#define FAIRMQLOGGER_H_
|
||||||
|
|
||||||
#include "logger/logger.h"
|
#include <Logger.h>
|
||||||
|
|
||||||
using timestamp_t = unsigned long long;
|
using timestamp_t = unsigned long long;
|
||||||
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
* File: fairroot_null_deleter.h
|
|
||||||
* Author: winckler
|
|
||||||
*
|
|
||||||
* Created on September 21, 2015, 11:50 AM
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FAIRROOT_NULL_DELETER_H
|
|
||||||
#define FAIRROOT_NULL_DELETER_H
|
|
||||||
// boost like null_deleter introduced for backward compability if boost version < 1.56
|
|
||||||
|
|
||||||
namespace fairroot
|
|
||||||
{
|
|
||||||
struct null_deleter
|
|
||||||
{
|
|
||||||
//! Function object result type
|
|
||||||
using result_type = void;
|
|
||||||
/*!
|
|
||||||
* Does nothing
|
|
||||||
*/
|
|
||||||
template< typename T >
|
|
||||||
void operator() (T*) const noexcept {}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif /* FAIRROOT_NULL_DELETER_H */
|
|
||||||
|
|
|
@ -1,314 +0,0 @@
|
||||||
/********************************************************************************
|
|
||||||
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
|
||||||
* *
|
|
||||||
* This software is distributed under the terms of the *
|
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
|
||||||
* copied verbatim in the file "LICENSE" *
|
|
||||||
********************************************************************************/
|
|
||||||
#include "logger.h"
|
|
||||||
|
|
||||||
#include <boost/version.hpp>
|
|
||||||
|
|
||||||
#include <boost/log/core/core.hpp>
|
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
|
||||||
|
|
||||||
#include <boost/log/support/date_time.hpp>
|
|
||||||
|
|
||||||
#include <boost/log/utility/setup/common_attributes.hpp>
|
|
||||||
#include <boost/log/utility/manipulators/to_log.hpp>
|
|
||||||
#include <boost/log/utility/formatting_ostream.hpp>
|
|
||||||
|
|
||||||
#include <boost/log/sinks/text_ostream_backend.hpp>
|
|
||||||
#include <boost/log/sinks/text_file_backend.hpp>
|
|
||||||
#include <boost/log/sinks/sync_frontend.hpp>
|
|
||||||
#include <boost/log/sinks/basic_sink_frontend.hpp>
|
|
||||||
|
|
||||||
#include <boost/log/expressions.hpp>
|
|
||||||
#include <boost/log/expressions/attr.hpp>
|
|
||||||
#include <boost/log/expressions/attr_fwd.hpp>
|
|
||||||
#include <boost/log/expressions/keyword.hpp>
|
|
||||||
|
|
||||||
#if BOOST_VERSION < 105600
|
|
||||||
#include "fairroot_null_deleter.h"
|
|
||||||
using empty_deleter_t = fairroot::null_deleter;
|
|
||||||
#else
|
|
||||||
#include <boost/core/null_deleter.hpp>
|
|
||||||
using empty_deleter_t = boost::null_deleter;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/make_shared.hpp>
|
|
||||||
#include <boost/shared_ptr.hpp>
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <ostream>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
namespace blog = boost::log;
|
|
||||||
namespace bptime = boost::posix_time;
|
|
||||||
|
|
||||||
struct TagConsole;
|
|
||||||
struct TagFile;
|
|
||||||
|
|
||||||
BOOST_LOG_ATTRIBUTE_KEYWORD(fairmq_logger_timestamp, "TimeStamp", bptime::ptime)
|
|
||||||
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", fair::mq::logger::SeverityLevel)
|
|
||||||
|
|
||||||
BOOST_LOG_GLOBAL_LOGGER_INIT(global_logger, blog::sources::severity_logger_mt)
|
|
||||||
{
|
|
||||||
blog::sources::severity_logger_mt<fair::mq::logger::SeverityLevel> globalLogger;
|
|
||||||
globalLogger.add_attribute("TimeStamp", blog::attributes::local_clock());
|
|
||||||
fair::mq::logger::DefaultConsoleInit();
|
|
||||||
return globalLogger;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace fair
|
|
||||||
{
|
|
||||||
namespace mq
|
|
||||||
{
|
|
||||||
namespace logger
|
|
||||||
{
|
|
||||||
|
|
||||||
vector<boost::shared_ptr<blog::sinks::basic_sink_frontend>> sinkList;// global var
|
|
||||||
|
|
||||||
void InitConsoleLogFormatter(const blog::record_view& view, blog::formatting_ostream& os)
|
|
||||||
{
|
|
||||||
os << "[\033[01;36m";
|
|
||||||
|
|
||||||
auto dateTimeFormatter = blog::expressions::stream << blog::expressions::format_date_time<bptime::ptime>("TimeStamp", "%H:%M:%S");
|
|
||||||
dateTimeFormatter(view, os);
|
|
||||||
|
|
||||||
os << "\033[0m][" << view.attribute_values()["Severity"].extract<SeverityLevel, TagConsole>() << "] " << view.attribute_values()["Message"].extract<string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitFileLogFormatter(const blog::record_view& view, blog::formatting_ostream& os)
|
|
||||||
{
|
|
||||||
os << "[";
|
|
||||||
|
|
||||||
auto dateTimeFormatter = blog::expressions::stream << blog::expressions::format_date_time<bptime::ptime>("TimeStamp", "%H:%M:%S");
|
|
||||||
dateTimeFormatter(view, os);
|
|
||||||
|
|
||||||
os << "][" << view.attribute_values()["Severity"].extract<SeverityLevel, TagFile>() << "] " << view.attribute_values()["Message"].extract<string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// helper function to format in color console output
|
|
||||||
string writeIn(const string& textInBold, color::Code color)
|
|
||||||
{
|
|
||||||
ostringstream os;
|
|
||||||
os << "\033[01;" << color << "m" << textInBold << "\033[0m";
|
|
||||||
return os.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// overload operator for console output
|
|
||||||
blog::formatting_ostream& operator<<(blog::formatting_ostream& stream, blog::to_log_manip<SeverityLevel, TagConsole> const& manip)
|
|
||||||
{
|
|
||||||
SeverityLevel level = manip.get();
|
|
||||||
size_t idx = static_cast<size_t>(level);
|
|
||||||
if (idx < gLogSeverityLevelString.size())
|
|
||||||
{
|
|
||||||
switch (level)
|
|
||||||
{
|
|
||||||
case SeverityLevel::TRACE:
|
|
||||||
stream << writeIn(gLogSeverityLevelString.at(idx), color::FG_BLUE);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SeverityLevel::DEBUG:
|
|
||||||
stream << writeIn(gLogSeverityLevelString.at(idx), color::FG_BLUE);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SeverityLevel::RESULTS:
|
|
||||||
stream << writeIn(gLogSeverityLevelString.at(idx), color::FG_MAGENTA);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SeverityLevel::INFO:
|
|
||||||
stream << writeIn(gLogSeverityLevelString.at(idx), color::FG_GREEN);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SeverityLevel::WARN:
|
|
||||||
stream << writeIn(gLogSeverityLevelString.at(idx), color::FG_YELLOW);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SeverityLevel::STATE:
|
|
||||||
stream << writeIn(gLogSeverityLevelString.at(idx), color::FG_MAGENTA);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SeverityLevel::ERROR:
|
|
||||||
stream << writeIn(gLogSeverityLevelString.at(idx), color::FG_RED);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SeverityLevel::NOLOG:
|
|
||||||
stream << writeIn(gLogSeverityLevelString.at(idx), color::FG_DEFAULT);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stream << writeIn("Unknown log level ", color::FG_RED) << "(int level = " << static_cast<int>(level) << ")";
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
// overload operator for file output
|
|
||||||
blog::formatting_ostream& operator<<(blog::formatting_ostream& stream, blog::to_log_manip<SeverityLevel, TagFile> const& manip)
|
|
||||||
{
|
|
||||||
SeverityLevel level = manip.get();
|
|
||||||
size_t idx = static_cast<size_t>(level);
|
|
||||||
if (idx < gLogSeverityLevelString.size())
|
|
||||||
{
|
|
||||||
stream << gLogSeverityLevelString.at(idx);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stream << writeIn("Unknown log level ", color::FG_RED) << "(int level = " << static_cast<int>(level) << ")";
|
|
||||||
}
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemoveRegisteredSinks()
|
|
||||||
{
|
|
||||||
if (sinkList.size() > 0)
|
|
||||||
{
|
|
||||||
for (const auto& sink : sinkList)
|
|
||||||
{
|
|
||||||
blog::core::get()->remove_sink(sink);
|
|
||||||
}
|
|
||||||
sinkList.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReinitLogger(bool color, const string& filename, SeverityLevel level)
|
|
||||||
{
|
|
||||||
BOOST_LOG_SEV(global_logger::get(), SeverityLevel::NOLOG) << "";
|
|
||||||
RemoveRegisteredSinks();
|
|
||||||
DefaultConsoleInit(color);
|
|
||||||
if (level != SeverityLevel::NOLOG)
|
|
||||||
{
|
|
||||||
if (!filename.empty())
|
|
||||||
{
|
|
||||||
DefaultAddFileSink(filename, level);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// console sink related functions
|
|
||||||
void DefaultConsoleInit(bool color/* = true*/)
|
|
||||||
{
|
|
||||||
// add a text sink
|
|
||||||
using TextSink = blog::sinks::synchronous_sink<blog::sinks::text_ostream_backend>;
|
|
||||||
|
|
||||||
RemoveRegisteredSinks();
|
|
||||||
|
|
||||||
// CONSOLE - all severity except error
|
|
||||||
boost::shared_ptr<TextSink> sink = boost::make_shared<TextSink>();
|
|
||||||
// add "console" output stream to our sink
|
|
||||||
sink->locked_backend()->add_stream(boost::shared_ptr<ostream>(&clog, empty_deleter_t()));
|
|
||||||
|
|
||||||
// specify the format of the log message
|
|
||||||
if (color)
|
|
||||||
{
|
|
||||||
sink->set_formatter(&InitConsoleLogFormatter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sink->set_formatter(&InitFileLogFormatter);
|
|
||||||
}
|
|
||||||
|
|
||||||
sink->set_filter(severity != SeverityLevel::ERROR && severity < SeverityLevel::NOLOG);
|
|
||||||
// add sink to the core
|
|
||||||
sinkList.push_back(sink);
|
|
||||||
blog::core::get()->add_sink(sink);
|
|
||||||
|
|
||||||
// CONSOLE - only severity error
|
|
||||||
boost::shared_ptr<TextSink> sinkError = boost::make_shared<TextSink>();
|
|
||||||
sinkError->locked_backend()->add_stream(boost::shared_ptr<ostream>(&cerr, empty_deleter_t()));
|
|
||||||
|
|
||||||
if (color)
|
|
||||||
{
|
|
||||||
sinkError->set_formatter(&InitConsoleLogFormatter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sinkError->set_formatter(&InitFileLogFormatter);
|
|
||||||
}
|
|
||||||
|
|
||||||
sinkError->set_filter(severity == SeverityLevel::ERROR);
|
|
||||||
sinkList.push_back(sinkError);
|
|
||||||
blog::core::get()->add_sink(sinkError);
|
|
||||||
}
|
|
||||||
|
|
||||||
int DefaultConsoleSetFilter(SeverityLevel level)
|
|
||||||
{
|
|
||||||
if (sinkList.size() >= 2)
|
|
||||||
{
|
|
||||||
sinkList.at(0)->set_filter([level](const blog::attribute_value_set& attrSet)
|
|
||||||
{
|
|
||||||
auto sev = attrSet["Severity"].extract<SeverityLevel>();
|
|
||||||
auto mainConsoleSinkCondition = (sev != SeverityLevel::ERROR) && (sev < SeverityLevel::NOLOG);
|
|
||||||
return mainConsoleSinkCondition && (sev >= level);
|
|
||||||
});
|
|
||||||
|
|
||||||
sinkList.at(1)->set_filter([level](const blog::attribute_value_set& attrSet)
|
|
||||||
{
|
|
||||||
auto sev = attrSet["Severity"].extract<SeverityLevel>();
|
|
||||||
auto errorConsoleSinkCondition = sev == SeverityLevel::ERROR;
|
|
||||||
return errorConsoleSinkCondition && (sev >= level);
|
|
||||||
});
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// file sink related functions
|
|
||||||
void DefaultAddFileSink(const string& filename, SeverityLevel level)
|
|
||||||
{
|
|
||||||
// add a text sink
|
|
||||||
string formattedFilename(filename);
|
|
||||||
formattedFilename += "_%Y-%m-%d_%H-%M-%S.%N.log";
|
|
||||||
|
|
||||||
// add a text sink
|
|
||||||
using SinkBackend = blog::sinks::text_file_backend;
|
|
||||||
using Sink = blog::sinks::synchronous_sink<SinkBackend>;
|
|
||||||
|
|
||||||
boost::shared_ptr<SinkBackend> backend = boost::make_shared<SinkBackend>(
|
|
||||||
blog::keywords::file_name = formattedFilename,
|
|
||||||
blog::keywords::rotation_size = 10 * 1024 * 1024,
|
|
||||||
// rotate at midnight every day
|
|
||||||
blog::keywords::time_based_rotation = blog::sinks::file::rotation_at_time_point(0, 0, 0),
|
|
||||||
// log collector,
|
|
||||||
// -- maximum total size of the stored log files is 1GB.
|
|
||||||
// -- minimum free space on the drive is 2GB
|
|
||||||
blog::keywords::max_size = 1000 * 1024 * 1024,
|
|
||||||
blog::keywords::min_free_space = 2000 * 1024 * 1024,
|
|
||||||
blog::keywords::auto_flush = true
|
|
||||||
//keywords::time_based_rotation = &is_it_time_to_rotate
|
|
||||||
);
|
|
||||||
boost::shared_ptr<Sink> sink = boost::make_shared<Sink>(backend);
|
|
||||||
|
|
||||||
// specify the format of the log message
|
|
||||||
sink->set_formatter(&InitFileLogFormatter);
|
|
||||||
|
|
||||||
// forward lambda for setting the filter
|
|
||||||
sink->set_filter([level](const blog::attribute_value_set& attrSet)
|
|
||||||
{
|
|
||||||
auto sev = attrSet["Severity"].extract<SeverityLevel>();
|
|
||||||
return (sev >= level) && (sev < SeverityLevel::NOLOG);
|
|
||||||
});
|
|
||||||
|
|
||||||
// add file sinks to core and list
|
|
||||||
blog::core::get()->add_sink(sink);
|
|
||||||
sinkList.push_back(sink);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace logger
|
|
||||||
} // namespace mq
|
|
||||||
} // namespace fair
|
|
|
@ -1,120 +0,0 @@
|
||||||
/********************************************************************************
|
|
||||||
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
|
||||||
* *
|
|
||||||
* This software is distributed under the terms of the *
|
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
|
||||||
* copied verbatim in the file "LICENSE" *
|
|
||||||
********************************************************************************/
|
|
||||||
/*
|
|
||||||
* File: logger.h
|
|
||||||
* Author: winckler
|
|
||||||
*
|
|
||||||
* Created on August 21, 2015, 6:12 PM
|
|
||||||
*/
|
|
||||||
#ifndef FAIR_MQ_LOGGER_H
|
|
||||||
#define FAIR_MQ_LOGGER_H
|
|
||||||
|
|
||||||
#define BOOST_LOG_DYN_LINK 1 // necessary when linking the boost_log library dynamically
|
|
||||||
#define FUSION_MAX_VECTOR_SIZE 20
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
#undef DEBUG
|
|
||||||
#warning "The symbol 'DEBUG' is used in FairMQLogger. undefining..."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/version.hpp>
|
|
||||||
|
|
||||||
#include <boost/log/sources/global_logger_storage.hpp>
|
|
||||||
#include <boost/log/sources/severity_logger.hpp>
|
|
||||||
#include <boost/log/sources/record_ostream.hpp>
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
|
|
||||||
namespace fair
|
|
||||||
{
|
|
||||||
namespace mq
|
|
||||||
{
|
|
||||||
namespace logger
|
|
||||||
{
|
|
||||||
|
|
||||||
enum SeverityLevel
|
|
||||||
{
|
|
||||||
TRACE,
|
|
||||||
DEBUG,
|
|
||||||
RESULTS,
|
|
||||||
INFO,
|
|
||||||
STATE,
|
|
||||||
WARN,
|
|
||||||
ERROR,
|
|
||||||
NOLOG
|
|
||||||
};
|
|
||||||
|
|
||||||
static const std::array<std::string, 8> gLogSeverityLevelString
|
|
||||||
{
|
|
||||||
{
|
|
||||||
"TRACE",
|
|
||||||
"DEBUG",
|
|
||||||
"RESULTS",
|
|
||||||
"INFO",
|
|
||||||
"STATE",
|
|
||||||
"WARN",
|
|
||||||
"ERROR",
|
|
||||||
"NOLOG"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace color
|
|
||||||
{
|
|
||||||
|
|
||||||
enum Code
|
|
||||||
{
|
|
||||||
FG_BLACK = 30,
|
|
||||||
FG_RED = 31,
|
|
||||||
FG_GREEN = 32,
|
|
||||||
FG_YELLOW = 33,
|
|
||||||
FG_BLUE = 34,
|
|
||||||
FG_MAGENTA = 35,
|
|
||||||
FG_CYAN = 36,
|
|
||||||
FG_WHITE = 37,
|
|
||||||
FG_DEFAULT = 39,
|
|
||||||
BG_RED = 41,
|
|
||||||
BG_GREEN = 42,
|
|
||||||
BG_BLUE = 44,
|
|
||||||
BG_DEFAULT = 49
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace color
|
|
||||||
|
|
||||||
void ReinitLogger(bool color, const std::string& filename = "", SeverityLevel level = SeverityLevel::NOLOG);
|
|
||||||
void RemoveRegisteredSinks();
|
|
||||||
|
|
||||||
// console sink related functions
|
|
||||||
void DefaultConsoleInit(bool color = true);
|
|
||||||
int DefaultConsoleSetFilter(SeverityLevel level);
|
|
||||||
|
|
||||||
// file sink related functions
|
|
||||||
void DefaultAddFileSink(const std::string& filename, SeverityLevel level);
|
|
||||||
|
|
||||||
} // namespace logger
|
|
||||||
} // namespace mq
|
|
||||||
} // namespace fair
|
|
||||||
|
|
||||||
// register a global logger (declaration)
|
|
||||||
BOOST_LOG_GLOBAL_LOGGER(global_logger, boost::log::sources::severity_logger_mt<fair::mq::logger::SeverityLevel>)
|
|
||||||
|
|
||||||
// helper macros
|
|
||||||
|
|
||||||
// global macros (core). Level filters are set globally here, that is to all register sinks
|
|
||||||
// add empty string if boost 1.59.0 (see : https://svn.boost.org/trac/boost/ticket/11549 )
|
|
||||||
#if BOOST_VERSION == 105900
|
|
||||||
#define LOG(severity) BOOST_LOG_SEV(global_logger::get(), fair::mq::logger::SeverityLevel::severity) << ""
|
|
||||||
#define MQLOG(severity) BOOST_LOG_SEV(global_logger::get(), fair::mq::logger::SeverityLevel::severity) << ""
|
|
||||||
#else
|
|
||||||
#define LOG(severity) BOOST_LOG_SEV(global_logger::get(), fair::mq::logger::SeverityLevel::severity)
|
|
||||||
#define MQLOG(severity) BOOST_LOG_SEV(global_logger::get(), fair::mq::logger::SeverityLevel::severity)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SET_LOG_CONSOLE_LEVEL(loglevel) DefaultConsoleSetFilter(fair::mq::logger::SeverityLevel::loglevel)
|
|
||||||
#define ADD_LOG_FILESINK(filename, loglevel) DefaultAddFileSink(filename, fair::mq::logger::SeverityLevel::loglevel)
|
|
||||||
|
|
||||||
#endif // FAIR_MQ_LOGGER_H
|
|
|
@ -1,113 +0,0 @@
|
||||||
/********************************************************************************
|
|
||||||
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
|
||||||
* *
|
|
||||||
* This software is distributed under the terms of the *
|
|
||||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
|
||||||
* copied verbatim in the file "LICENSE" *
|
|
||||||
********************************************************************************/
|
|
||||||
|
|
||||||
// WARNING : pragma commands to hide boost warning
|
|
||||||
// TODO : remove these pragma commands when boost will fix this issue in future release
|
|
||||||
|
|
||||||
#if defined(__clang__)
|
|
||||||
_Pragma("clang diagnostic push")
|
|
||||||
_Pragma("clang diagnostic ignored \"-Wshadow\"")
|
|
||||||
#include "logger.h"
|
|
||||||
_Pragma("clang diagnostic pop")
|
|
||||||
#elif defined(__GNUC__) || defined(__GNUG__)
|
|
||||||
_Pragma("GCC diagnostic push")
|
|
||||||
_Pragma("GCC diagnostic ignored \"-Wshadow\"")
|
|
||||||
#include "logger.h"
|
|
||||||
_Pragma("GCC diagnostic pop")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/log/support/date_time.hpp>
|
|
||||||
|
|
||||||
void test_logger()
|
|
||||||
{
|
|
||||||
LOG(TRACE) << "this is a trace message";
|
|
||||||
LOG(DEBUG) << "this is a debug message";
|
|
||||||
LOG(RESULTS) << "this is a results message";
|
|
||||||
LOG(INFO) << "this is a info message";
|
|
||||||
LOG(WARN) << "this is a warning message";
|
|
||||||
LOG(ERROR) << "this is an error message";
|
|
||||||
LOG(STATE) << "this is a state message";
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_console_level()
|
|
||||||
{
|
|
||||||
std::cout<<"********* test logger : SET_LOG_CONSOLE_LEVEL(lvl) *********"<<std::endl;
|
|
||||||
SET_LOG_CONSOLE_LEVEL(TRACE);
|
|
||||||
test_logger();
|
|
||||||
std::cout << "----------------------------"<<std::endl;
|
|
||||||
|
|
||||||
SET_LOG_CONSOLE_LEVEL(DEBUG);
|
|
||||||
test_logger();
|
|
||||||
std::cout << "----------------------------"<<std::endl;
|
|
||||||
|
|
||||||
SET_LOG_CONSOLE_LEVEL(RESULTS);
|
|
||||||
test_logger();
|
|
||||||
std::cout << "----------------------------"<<std::endl;
|
|
||||||
|
|
||||||
SET_LOG_CONSOLE_LEVEL(INFO);
|
|
||||||
test_logger();
|
|
||||||
std::cout << "----------------------------"<<std::endl;
|
|
||||||
|
|
||||||
SET_LOG_CONSOLE_LEVEL(WARN);
|
|
||||||
test_logger();
|
|
||||||
std::cout << "----------------------------"<<std::endl;
|
|
||||||
|
|
||||||
SET_LOG_CONSOLE_LEVEL(ERROR);
|
|
||||||
test_logger();
|
|
||||||
std::cout << "----------------------------"<<std::endl;
|
|
||||||
|
|
||||||
SET_LOG_CONSOLE_LEVEL(STATE);
|
|
||||||
test_logger();
|
|
||||||
std::cout << "----------------------------"<<std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
test_console_level();
|
|
||||||
SET_LOG_CONSOLE_LEVEL(INFO);
|
|
||||||
|
|
||||||
std::cout << "----------------------------"<<std::endl;
|
|
||||||
LOG(INFO)<<"open log file 1";
|
|
||||||
ADD_LOG_FILESINK("test_log1",ERROR);
|
|
||||||
test_logger();
|
|
||||||
|
|
||||||
std::cout << "----------------------------"<<std::endl;
|
|
||||||
LOG(INFO)<<"open log file 2";
|
|
||||||
ADD_LOG_FILESINK("test_log2",STATE);
|
|
||||||
test_logger();
|
|
||||||
|
|
||||||
// advanced commands
|
|
||||||
std::cout << "----------------------------"<<std::endl;
|
|
||||||
LOG(INFO)<<"open log file 3";// custom file sink setting
|
|
||||||
// AddFileSink([](const boost::log::attribute_value_set& attr_set)
|
|
||||||
// {
|
|
||||||
// auto sev = attr_set["Severity"].extract<custom_severity_level>();
|
|
||||||
// return (sev == FairMQ::ERROR);
|
|
||||||
// },
|
|
||||||
// boost::log::keywords::file_name = "test_log3_%5N.log",
|
|
||||||
// boost::log::keywords::rotation_size = 5 * 1024 * 1024,
|
|
||||||
// boost::log::keywords::time_based_rotation = boost::log::sinks::file::rotation_at_time_point(12, 0, 0)
|
|
||||||
// );
|
|
||||||
|
|
||||||
test_logger();
|
|
||||||
|
|
||||||
std::cout << "----------------------------"<<std::endl;
|
|
||||||
LOG(INFO)<<"set filter of last sink";// custom file sink setting
|
|
||||||
// get last added sink and reset filter to WARN and ERROR
|
|
||||||
FairMQ::Logger::sinkList.back()->set_filter([](const boost::log::attribute_value_set& attr_set)
|
|
||||||
{
|
|
||||||
auto sev = attr_set["Severity"].extract<custom_severity_level>();
|
|
||||||
return (sev == FairMQ::WARN) || (sev == FairMQ::ERROR);
|
|
||||||
});
|
|
||||||
test_logger();
|
|
||||||
|
|
||||||
// remove all sinks, and restart console sinks
|
|
||||||
ReinitLogger(false);
|
|
||||||
test_logger();
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -73,7 +73,7 @@ FairMQMap XML::UserParser(stringstream& input, const string& deviceId, const str
|
||||||
namespace Helper
|
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;
|
string deviceIdKey;
|
||||||
|
|
||||||
|
@ -88,23 +88,23 @@ void PrintDeviceList(const boost::property_tree::ptree& tree, const std::string&
|
||||||
if (key != "")
|
if (key != "")
|
||||||
{
|
{
|
||||||
deviceIdKey = 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
|
else
|
||||||
{
|
{
|
||||||
deviceIdKey = q.second.get<string>("id");
|
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")
|
if (p.first == "device")
|
||||||
{
|
{
|
||||||
//get id attribute to choose the device
|
// get id attribute to choose the device
|
||||||
if (formatFlag == "xml")
|
if (formatFlag == "xml")
|
||||||
{
|
{
|
||||||
deviceIdKey = p.second.get<string>("<xmlattr>.id");
|
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")
|
if (formatFlag == "json")
|
||||||
|
@ -113,12 +113,12 @@ void PrintDeviceList(const boost::property_tree::ptree& tree, const std::string&
|
||||||
if (key != "")
|
if (key != "")
|
||||||
{
|
{
|
||||||
deviceIdKey = 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
|
else
|
||||||
{
|
{
|
||||||
deviceIdKey = p.second.get<string>("id");
|
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)
|
void PrintPropertyTree(const boost::property_tree::ptree& tree, int level)
|
||||||
{
|
{
|
||||||
for (const auto& p : tree) {
|
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);
|
PrintPropertyTree(p.second.get_child(""), level + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,25 +13,22 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "FairMQProgOptions.h"
|
#include "FairMQProgOptions.h"
|
||||||
#include <algorithm>
|
|
||||||
#include "FairMQParser.h"
|
#include "FairMQParser.h"
|
||||||
#include "FairMQSuboptParser.h"
|
#include "FairMQSuboptParser.h"
|
||||||
#include "FairMQLogger.h"
|
#include "FairMQLogger.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
FairMQProgOptions::FairMQProgOptions()
|
FairMQProgOptions::FairMQProgOptions()
|
||||||
: FairProgOptions()
|
: FairProgOptions()
|
||||||
, fMQParserOptions("MQ-Device parser options")
|
, fMQParserOptions("FairMQ config parser options")
|
||||||
, fMQOptionsInCfg("MQ-Device options")
|
, fMQCmdOptions("FairMQ device options")
|
||||||
, fMQOptionsInCmd("MQ-Device options")
|
|
||||||
, fFairMQMap()
|
, fFairMQMap()
|
||||||
, fHelpTitle("***** FAIRMQ Program Options ***** ")
|
|
||||||
, fVersion("Beta version 0.1")
|
|
||||||
, fChannelInfo()
|
, fChannelInfo()
|
||||||
, fMQKeyMap()
|
, 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();
|
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();
|
InitOptionDescription();
|
||||||
// parse command line options
|
|
||||||
if (FairProgOptions::ParseCmdLine(argc, argv, fCmdLineOptions, fVarMap, allowUnregistered))
|
if (FairProgOptions::ParseCmdLine(argc, argv, fCmdLineOptions, fVarMap, allowUnregistered))
|
||||||
{
|
{
|
||||||
// ParseCmdLine return 0 if help or version cmd not called. return 1 if called
|
// ParseCmdLine returns 0 if no immediate switches found.
|
||||||
exit(EXIT_SUCCESS);
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if these options are provided, do no further checks and let the device handle them
|
// if these options are provided, do no further checks and let the device handle them
|
||||||
if (fVarMap.count("print-channels") || fVarMap.count("version"))
|
if (fVarMap.count("print-channels") || fVarMap.count("version"))
|
||||||
{
|
{
|
||||||
fair::mq::logger::DefaultConsoleSetFilter(fSeverityMap.at("NOLOG"));
|
fair::Logger::SetConsoleSeverity("nolog");
|
||||||
return;
|
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 verbosity = GetValue<string>("verbosity");
|
||||||
string logFile = GetValue<string>("log-to-file");
|
fair::Logger::SetVerbosity(verbosity);
|
||||||
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";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (logFile != "")
|
if (logFile != "")
|
||||||
{
|
{
|
||||||
fair::mq::logger::ReinitLogger(false, logFile, fSeverityMap.at(verbosity));
|
fair::Logger::InitFileSink(logFile, severity);
|
||||||
fair::mq::logger::DefaultConsoleSetFilter(fSeverityMap.at("NOLOG"));
|
fair::Logger::SetConsoleSeverity("nolog");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!color)
|
fair::Logger::SetConsoleColor(color);
|
||||||
{
|
fair::Logger::SetConsoleSeverity(severity);
|
||||||
fair::mq::logger::ReinitLogger(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
fair::mq::logger::DefaultConsoleSetFilter(fSeverityMap.at(verbosity));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if one of required MQ config option is there
|
// 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:";
|
LOG(WARN) << "FairMQProgOptions: no channels configuration provided via neither of:";
|
||||||
for (const auto& p : MQParserKeys)
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -180,10 +142,8 @@ void FairMQProgOptions::ParseAll(const int argc, char const* const* argv, bool a
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG(ERROR) << "mq-config command line called but file extension '"
|
LOG(error) << "mq-config command line called but file extension '" << ext << "' not recognized. Program will now exit";
|
||||||
<< ext
|
return 1;
|
||||||
<< "' not recognized. Program will now exit";
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,6 +173,8 @@ void FairMQProgOptions::ParseAll(const int argc, char const* const* argv, bool a
|
||||||
}
|
}
|
||||||
|
|
||||||
FairProgOptions::PrintOptions();
|
FairProgOptions::PrintOptions();
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FairMQProgOptions::Store(const FairMQMap& channels)
|
int FairMQProgOptions::Store(const FairMQMap& channels)
|
||||||
|
@ -237,7 +199,7 @@ void FairMQProgOptions::UpdateChannelInfo()
|
||||||
fChannelInfo.clear();
|
fChannelInfo.clear();
|
||||||
for (const auto& c : fFairMQMap)
|
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>(methodKey, channel.GetMethod());
|
||||||
UpdateVarMap<string>(addressKey, channel.GetAddress());
|
UpdateVarMap<string>(addressKey, channel.GetAddress());
|
||||||
UpdateVarMap<string>(transportKey, channel.GetTransport());
|
UpdateVarMap<string>(transportKey, channel.GetTransport());
|
||||||
|
|
||||||
//UpdateVarMap<string>(sndBufSizeKey, to_string(channel.GetSndBufSize()));// string API
|
|
||||||
UpdateVarMap<int>(sndBufSizeKey, channel.GetSndBufSize());
|
UpdateVarMap<int>(sndBufSizeKey, channel.GetSndBufSize());
|
||||||
|
|
||||||
//UpdateVarMap<string>(rcvBufSizeKey, to_string(channel.GetRcvBufSize()));// string API
|
|
||||||
UpdateVarMap<int>(rcvBufSizeKey, channel.GetRcvBufSize());
|
UpdateVarMap<int>(rcvBufSizeKey, channel.GetRcvBufSize());
|
||||||
|
|
||||||
//UpdateVarMap<string>(sndKernelSizeKey, to_string(channel.GetSndKernelSize()));// string API
|
|
||||||
UpdateVarMap<int>(sndKernelSizeKey, channel.GetSndKernelSize());
|
UpdateVarMap<int>(sndKernelSizeKey, channel.GetSndKernelSize());
|
||||||
|
|
||||||
//UpdateVarMap<string>(rcvKernelSizeKey, to_string(channel.GetRcvKernelSize()));// string API
|
|
||||||
UpdateVarMap<int>(rcvKernelSizeKey, channel.GetRcvKernelSize());
|
UpdateVarMap<int>(rcvKernelSizeKey, channel.GetRcvKernelSize());
|
||||||
|
|
||||||
//UpdateVarMap<string>(rateLoggingKey,to_string(channel.GetRateLogging()));// string API
|
|
||||||
UpdateVarMap<int>(rateLoggingKey, channel.GetRateLogging());
|
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++;
|
index++;
|
||||||
}
|
}
|
||||||
UpdateVarMap<int>(p.first + ".numSockets", index);
|
UpdateVarMap<int>("chans." + p.first + ".numSockets", index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int FairMQProgOptions::NotifySwitchOption()
|
int FairMQProgOptions::ImmediateOptions()
|
||||||
{
|
{
|
||||||
if (fVarMap.count("help"))
|
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 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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()
|
void FairMQProgOptions::InitOptionDescription()
|
||||||
{
|
{
|
||||||
// Id required in command line if config txt file not enabled
|
fMQCmdOptions.add_options()
|
||||||
if (fUseConfigFile)
|
("id", po::value<string>(), "Device ID (required argument).")
|
||||||
{
|
("io-threads", po::value<int >()->default_value(1), "Number of I/O threads.")
|
||||||
FillOptionDescription(fMQOptionsInCmd);
|
("transport", po::value<string>()->default_value("zeromq"), "Transport ('zeromq'/'nanomsg').")
|
||||||
|
("config", po::value<string>()->default_value("static"), "Config source ('static'/<config library filename>).")
|
||||||
FillOptionDescription(fMQOptionsInCfg);
|
("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.")
|
||||||
else
|
("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.")
|
||||||
FillOptionDescription(fMQOptionsInCmd);
|
("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()
|
fMQParserOptions.add_options()
|
||||||
("config-xml-string", po::value<vector<string>>()->multitoken(), "XML input as command line string.")
|
("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-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")
|
("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(fGeneralDesc);
|
||||||
AddToCmdLineOptions(fMQOptionsInCmd);
|
AddToCmdLineOptions(fMQCmdOptions);
|
||||||
AddToCmdLineOptions(fMQParserOptions);
|
AddToCmdLineOptions(fMQParserOptions);
|
||||||
|
|
||||||
if (fUseConfigFile)
|
|
||||||
{
|
|
||||||
AddToCfgFileOptions(fMQOptionsInCfg, false);
|
|
||||||
AddToCfgFileOptions(fMQParserOptions, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int FairMQProgOptions::UpdateChannelMap(const string& channelName, int index, const string& member, const string& val)
|
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)
|
int FairMQProgOptions::UpdateChannelMap(const string& channelName, int index, const string& member, int val)
|
||||||
{
|
{
|
||||||
if (member == "sndBufSize")
|
if (member == "sndBufSize")
|
||||||
|
@ -469,9 +352,8 @@ int FairMQProgOptions::UpdateChannelMap(const string& channelName, int index, co
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//if we get there it means something is wrong
|
// if we get there it means something is wrong
|
||||||
LOG(ERROR) << "update of FairMQChannel map failed for the following key: "
|
LOG(ERROR) << "update of FairMQChannel map failed for the following key: " << channelName << "." << index << "." << member;
|
||||||
<< channelName << "." << index << "." << member;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,16 +18,15 @@
|
||||||
|
|
||||||
#include <fairmq/EventManager.h>
|
#include <fairmq/EventManager.h>
|
||||||
|
|
||||||
|
#include "FairProgOptions.h"
|
||||||
|
#include "FairMQChannel.h"
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "FairProgOptions.h"
|
|
||||||
#include "FairMQChannel.h"
|
|
||||||
|
|
||||||
namespace fair
|
namespace fair
|
||||||
{
|
{
|
||||||
namespace mq
|
namespace mq
|
||||||
|
@ -43,17 +42,15 @@ class FairMQProgOptions : public FairProgOptions
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
using FairMQMap = std::unordered_map<std::string, std::vector<FairMQChannel>>;
|
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:
|
public:
|
||||||
FairMQProgOptions();
|
FairMQProgOptions();
|
||||||
virtual ~FairMQProgOptions();
|
virtual ~FairMQProgOptions();
|
||||||
|
|
||||||
void ParseAll(const std::vector<std::string>& cmdLineArgs, bool allowUnregistered);
|
int ParseAll(const std::vector<std::string>& cmdLineArgs, bool allowUnregistered);
|
||||||
// parse command line and txt/INI configuration file.
|
// parse command line.
|
||||||
// default parser for the mq-configuration file (JSON/XML) is called if command line key mq-config is called
|
// 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
|
// external parser, store function
|
||||||
template <typename T, typename ...Args>
|
template <typename T, typename ...Args>
|
||||||
|
@ -81,94 +78,12 @@ class FairMQProgOptions : public FairProgOptions
|
||||||
return fChannelInfo;
|
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
|
// If key is found in fMQKeyMap, update the FairMQChannelMap accordingly
|
||||||
// Note that the fMQKeyMap is filled:
|
// 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)
|
// - 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
|
// specialization/overloading for string, pass by const ref
|
||||||
int UpdateValue(const std::string& key, const std::string& val) // string API
|
int UpdateValue(const std::string& key, const std::string& val) // string API
|
||||||
{
|
{
|
||||||
|
@ -214,9 +129,7 @@ class FairMQProgOptions : public FairProgOptions
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG(ERROR) << "UpdatedValue failed because the provided key '"
|
LOG(error) << "UpdateValue failed: key '" << key << "' not found in the variable map";
|
||||||
<< key
|
|
||||||
<< "' is not found in the variable map";
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -284,30 +197,14 @@ class FairMQProgOptions : public FairProgOptions
|
||||||
|
|
||||||
fEvents.Unsubscribe<fair::mq::PropertyChangeAsString, std::string>(subscriber);
|
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
|
// replace FairMQChannelMap, and update variable map accordingly
|
||||||
int UpdateChannelMap(const FairMQMap& map);
|
int UpdateChannelMap(const FairMQMap& map);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
po::options_description fMQCmdOptions;
|
||||||
po::options_description fMQParserOptions;
|
po::options_description fMQParserOptions;
|
||||||
po::options_description fMQOptionsInCfg;
|
|
||||||
po::options_description fMQOptionsInCmd;
|
|
||||||
FairMQMap fFairMQMap;
|
FairMQMap fFairMQMap;
|
||||||
std::string fHelpTitle;
|
|
||||||
std::string fVersion;
|
|
||||||
|
|
||||||
// map of read channel info - channel name - number of subchannels
|
// map of read channel info - channel name - number of subchannels
|
||||||
std::unordered_map<std::string, int> fChannelInfo;
|
std::unordered_map<std::string, int> fChannelInfo;
|
||||||
|
@ -315,31 +212,15 @@ class FairMQProgOptions : public FairProgOptions
|
||||||
using MQKey = std::tuple<std::string, int, std::string>;//store key info
|
using MQKey = std::tuple<std::string, int, std::string>;//store key info
|
||||||
std::map<std::string, MQKey> fMQKeyMap;// key=full path - val=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();
|
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
|
// read FairMQChannelMap and insert/update corresponding values in variable map
|
||||||
// create key for variable map as follow : channelName.index.memberName
|
// create key for variable map as follow : channelName.index.memberName
|
||||||
void UpdateMQValues();
|
void UpdateMQValues();
|
||||||
int Store(const FairMQMap& channels);
|
int Store(const FairMQMap& channels);
|
||||||
|
|
||||||
private:
|
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>
|
template<typename T>
|
||||||
void EmitUpdate(const std::string& key, T val)
|
void EmitUpdate(const std::string& key, T val)
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,49 +15,30 @@
|
||||||
#include "FairProgOptions.h"
|
#include "FairProgOptions.h"
|
||||||
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
FairProgOptions::FairProgOptions() :
|
FairProgOptions::FairProgOptions()
|
||||||
fVarMap(),
|
: fVarMap()
|
||||||
fGenericDesc("Generic options description"),
|
, fGeneralDesc("General options")
|
||||||
fConfigDesc("Configuration options description"),
|
, fCmdLineOptions("Command line options")
|
||||||
fEnvironmentDesc("Environment variables"),
|
, fVisibleOptions("Visible options")
|
||||||
fHiddenDesc("Hidden options description"),
|
, fConfigMutex()
|
||||||
fCmdLineOptions("Command line options"),
|
|
||||||
fConfigFileOptions("Configuration file options"),
|
|
||||||
fSeverityMap(),
|
|
||||||
fVisibleOptions("Visible options"),
|
|
||||||
fConfigMutex(),
|
|
||||||
fVerbosityLevel("INFO"),
|
|
||||||
fUseConfigFile(false),
|
|
||||||
fConfigFile()
|
|
||||||
{
|
{
|
||||||
|
fGeneralDesc.add_options()
|
||||||
LOG(NOLOG) << "";// temporary hack to prevent throwing exception when accessing empty sinklist --> fixed me
|
|
||||||
fGenericDesc.add_options()
|
|
||||||
("help,h", "produce help")
|
("help,h", "produce help")
|
||||||
("version,v", "print version")
|
("version,v", "print version")
|
||||||
("verbosity", po::value<std::string>(&fVerbosityLevel)->default_value("DEBUG"), "Verbosity level : TRACE, DEBUG, RESULTS, INFO, WARN, ERROR, STATE, NOLOG")
|
("severity", po::value<string>()->default_value("debug"), "Log severity level : trace, debug, info, state, warn, error, fatal, nolog")
|
||||||
("log-color", po::value<bool>()->default_value(true), "logger color: true or false")
|
("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>)");
|
("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()
|
FairProgOptions::~FairProgOptions()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// //////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// Add option descriptions
|
/// Add option descriptions
|
||||||
int FairProgOptions::AddToCmdLineOptions(const po::options_description optDesc, bool visible)
|
int FairProgOptions::AddToCmdLineOptions(const po::options_description optDesc, bool visible)
|
||||||
{
|
{
|
||||||
|
@ -69,61 +50,11 @@ int FairProgOptions::AddToCmdLineOptions(const po::options_description optDesc,
|
||||||
return 0;
|
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()
|
po::options_description& FairProgOptions::GetCmdLineOptions()
|
||||||
{
|
{
|
||||||
return fCmdLineOptions;
|
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)
|
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
|
// 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);
|
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
|
// return 1 if switch options found in varmap
|
||||||
if (NotifySwitchOption())
|
if (ImmediateOptions())
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -156,89 +87,8 @@ int FairProgOptions::ParseCmdLine(const int argc, char const* const* argv, const
|
||||||
return ParseCmdLine(argc, argv, desc, fVarMap, allowUnregistered);
|
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()
|
int FairProgOptions::PrintOptions()
|
||||||
{
|
{
|
||||||
// //////////////////////////////////
|
|
||||||
// Method to overload.
|
// Method to overload.
|
||||||
// -> loop over variable map and print its content
|
// -> loop over variable map and print its content
|
||||||
// -> In this example the following types are supported:
|
// -> In this example the following types are supported:
|
||||||
|
@ -283,20 +133,27 @@ int FairProgOptions::PrintOptions()
|
||||||
|
|
||||||
// formatting and printing
|
// formatting and printing
|
||||||
|
|
||||||
LOG(DEBUG) << setfill ('*') << setw (totalLength + 3) << "*";// +3 because of string " = "
|
stringstream ss;
|
||||||
string PrintOptionsTitle = " Configuration ";
|
ss << "\n";
|
||||||
|
|
||||||
|
ss << setfill('*') << setw(totalLength + 3) << "*" << "\n"; // +3 because of string " = "
|
||||||
|
string title = " Configuration ";
|
||||||
|
|
||||||
int leftSpaceLength = 0;
|
int leftSpaceLength = 0;
|
||||||
int rightSpaceLength = 0;
|
int rightSpaceLength = 0;
|
||||||
int leftTitleShiftLength = 0;
|
int leftTitleShiftLength = 0;
|
||||||
int rightTitleShiftLength = 0;
|
int rightTitleShiftLength = 0;
|
||||||
|
|
||||||
leftTitleShiftLength = PrintOptionsTitle.length() / 2;
|
leftTitleShiftLength = title.length() / 2;
|
||||||
|
|
||||||
if ((PrintOptionsTitle.length()) % 2)
|
if ((title.length()) % 2)
|
||||||
|
{
|
||||||
rightTitleShiftLength = leftTitleShiftLength + 1;
|
rightTitleShiftLength = leftTitleShiftLength + 1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
rightTitleShiftLength = leftTitleShiftLength;
|
rightTitleShiftLength = leftTitleShiftLength;
|
||||||
|
}
|
||||||
|
|
||||||
leftSpaceLength = (totalLength + 3) / 2 - leftTitleShiftLength;
|
leftSpaceLength = (totalLength + 3) / 2 - leftTitleShiftLength;
|
||||||
if ((totalLength + 3) % 2)
|
if ((totalLength + 3) % 2)
|
||||||
|
@ -308,11 +165,11 @@ int FairProgOptions::PrintOptions()
|
||||||
rightSpaceLength = (totalLength + 3) / 2 - rightTitleShiftLength;
|
rightSpaceLength = (totalLength + 3) / 2 - rightTitleShiftLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(DEBUG) << setfill ('*') << setw(leftSpaceLength) << "*"
|
ss << setfill ('*') << setw(leftSpaceLength) << "*"
|
||||||
<< setw(PrintOptionsTitle.length()) << PrintOptionsTitle
|
<< setw(title.length()) << title
|
||||||
<< setfill ('*') << setw(rightSpaceLength) << "*";
|
<< setfill ('*') << setw(rightSpaceLength) << "*" << "\n";
|
||||||
|
|
||||||
LOG(DEBUG) << setfill ('*') << setw (totalLength+3) << "*";
|
ss << setfill ('*') << setw (totalLength+3) << "*" << "\n";
|
||||||
|
|
||||||
for (const auto& p : mapinfo)
|
for (const auto& p : mapinfo)
|
||||||
{
|
{
|
||||||
|
@ -323,36 +180,46 @@ int FairProgOptions::PrintOptions()
|
||||||
string emptyStr;
|
string emptyStr;
|
||||||
keyStr = p.first;
|
keyStr = p.first;
|
||||||
tie(valueStr, typeInfoStr, defaultStr, emptyStr) = p.second;
|
tie(valueStr, typeInfoStr, defaultStr, emptyStr) = p.second;
|
||||||
LOG(DEBUG) << std::setfill(' ')
|
ss << setfill(' ')
|
||||||
<< setw(maxLength1st) << left
|
<< setw(maxLength1st) << left
|
||||||
<< p.first << " = "
|
<< p.first << " = "
|
||||||
<< setw(maxLength2nd)
|
<< setw(maxLength2nd)
|
||||||
<< valueStr
|
<< valueStr
|
||||||
<< setw(maxLengthTypeInfo)
|
<< setw(maxLengthTypeInfo)
|
||||||
<< typeInfoStr
|
<< typeInfoStr
|
||||||
<< setw(maxLengthDefault)
|
<< setw(maxLengthDefault)
|
||||||
<< defaultStr
|
<< defaultStr
|
||||||
<< setw(maxLengthEmpty)
|
<< setw(maxLengthEmpty)
|
||||||
<< emptyStr;
|
<< emptyStr
|
||||||
|
<< "\n";
|
||||||
}
|
}
|
||||||
LOG(DEBUG) << setfill ('*') << setw (totalLength + 3) << "*";// +3 for " = "
|
ss << setfill ('*') << setw(totalLength + 3) << "*";// +3 for " = "
|
||||||
|
|
||||||
|
LOG(DEBUG) << ss.str();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FairProgOptions::NotifySwitchOption()
|
int FairProgOptions::PrintOptionsRaw()
|
||||||
{
|
{
|
||||||
// Method to overload.
|
MapVarValInfo_t mapInfo;
|
||||||
if (fVarMap.count("help"))
|
|
||||||
|
for (const auto& m : fVarMap)
|
||||||
{
|
{
|
||||||
cout << "***** FAIR Program Options ***** \n" << fVisibleOptions;
|
mapInfo[m.first] = GetVariableValueInfo(m.second);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fVarMap.count("version"))
|
for (const auto& p : mapInfo)
|
||||||
{
|
{
|
||||||
cout << "alpha version 0.0\n";
|
string keyStr;
|
||||||
return 1;
|
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;
|
return 0;
|
||||||
|
|
|
@ -16,20 +16,21 @@
|
||||||
#define FAIRPROGOPTIONS_H
|
#define FAIRPROGOPTIONS_H
|
||||||
|
|
||||||
#include "FairMQLogger.h"
|
#include "FairMQLogger.h"
|
||||||
|
#include "FairProgOptionsHelper.h"
|
||||||
|
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include "FairProgOptionsHelper.h"
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iterator>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FairProgOptions abstract base class
|
* 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 user defines in the derived class the option descriptions and
|
||||||
* the pure virtual ParseAll() method
|
* the pure virtual ParseAll() method
|
||||||
|
@ -80,13 +81,7 @@ class FairProgOptions
|
||||||
|
|
||||||
// add options_description
|
// add options_description
|
||||||
int AddToCmdLineOptions(const po::options_description optDesc, bool visible = true);
|
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& GetCmdLineOptions();
|
||||||
po::options_description& GetCfgFileOptions();
|
|
||||||
po::options_description& GetEnvironmentOptions();
|
|
||||||
|
|
||||||
void UseConfigFile(const std::string& filename = "");
|
|
||||||
|
|
||||||
// get value corresponding to the key
|
// get value corresponding to the key
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -108,9 +103,8 @@ class FairProgOptions
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
LOG(ERROR) << "Exception thrown for the key '" << key << "'";
|
LOG(error) << "Exception thrown for the key '" << key << "'";
|
||||||
LOG(ERROR) << e.what();
|
LOG(error) << e.what();
|
||||||
this->PrintHelp();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
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, 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 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);
|
virtual int ParseAll(const int argc, char const* const* argv, bool allowUnregistered = false) = 0;// TODO change return type to bool and propagate to executable
|
||||||
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 PrintOptions();
|
virtual int PrintOptions();
|
||||||
virtual int PrintOptionsRaw();
|
virtual int PrintOptionsRaw();
|
||||||
int PrintHelp() const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// options container
|
// options container
|
||||||
po::variables_map fVarMap;
|
po::variables_map fVarMap;
|
||||||
|
|
||||||
// basic description categories
|
// basic description categories
|
||||||
po::options_description fGenericDesc;
|
po::options_description fGeneralDesc;
|
||||||
po::options_description fConfigDesc;
|
|
||||||
po::options_description fEnvironmentDesc;
|
|
||||||
po::options_description fHiddenDesc;
|
|
||||||
|
|
||||||
// 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 fCmdLineOptions;
|
||||||
po::options_description fConfigFileOptions;
|
|
||||||
|
|
||||||
// Description which is printed in help command line
|
// 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;
|
po::options_description fVisibleOptions;
|
||||||
|
|
||||||
mutable std::mutex fConfigMutex;
|
mutable std::mutex fConfigMutex;
|
||||||
|
|
||||||
std::string fVerbosityLevel;
|
virtual int ImmediateOptions() = 0;
|
||||||
bool fUseConfigFile;
|
|
||||||
boost::filesystem::path fConfigFile;
|
|
||||||
virtual int NotifySwitchOption();
|
|
||||||
|
|
||||||
// UpdateVarMap() and replace() --> helper functions to modify the value of variable map after calling po::store
|
// UpdateVarMap() and replace() --> helper functions to modify the value of variable map after calling po::store
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -227,7 +203,7 @@ class FairProgOptions
|
||||||
|
|
||||||
VarValInfo_t GetVariableValueInfo(const po::variable_value& varValue);
|
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)
|
if (comp > val)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,48 +1,44 @@
|
||||||
|
|
||||||
<fairMQOptions>
|
<fairMQOptions>
|
||||||
<device name="merger" id="merger" >
|
<device name="merger" id="merger">
|
||||||
<channel name="two_inputs_channel" >
|
<channel name="two_inputs_channel">
|
||||||
<socket name="input1" >
|
<socket name="input1">
|
||||||
<type>pull</type>
|
<type>pull</type>
|
||||||
<method>bind</method>
|
<method>bind</method>
|
||||||
<address>tcp://*:5569</address>
|
<address>tcp://*:5569</address>
|
||||||
<sndBufSize>1000</sndBufSize>
|
<sndBufSize>1000</sndBufSize>
|
||||||
<rcvBufSize>1000</rcvBufSize>
|
<rcvBufSize>1000</rcvBufSize>
|
||||||
<rateLogging>1</rateLogging>
|
<rateLogging>1</rateLogging>
|
||||||
|
</socket>
|
||||||
</socket>
|
<socket name="input2">
|
||||||
<socket name="input2" >
|
<type>pull</type>
|
||||||
<type>pull</type>
|
<method>bind</method>
|
||||||
<method>bind</method>
|
<address>tcp://*:5570</address>
|
||||||
<address>tcp://*:5570</address>
|
<sndBufSize>1000</sndBufSize>
|
||||||
<sndBufSize>1000</sndBufSize>
|
<rcvBufSize>1000</rcvBufSize>
|
||||||
<rcvBufSize>1000</rcvBufSize>
|
<rateLogging>1</rateLogging>
|
||||||
<rateLogging>1</rateLogging>
|
</socket>
|
||||||
|
</channel>
|
||||||
</socket>
|
<channel name="one_output_channel">
|
||||||
</channel>
|
<socket name="output1">
|
||||||
<channel name="one_output_channel" >
|
<type>push</type>
|
||||||
<socket name="output1" >
|
<method>connect</method>
|
||||||
<type>push</type>
|
<address>tcp://*:5571</address>
|
||||||
<method>connect</method>
|
<sndBufSize>1000</sndBufSize>
|
||||||
<address>tcp://*:5571</address>
|
<rcvBufSize>1000</rcvBufSize>
|
||||||
<sndBufSize>1000</sndBufSize>
|
<rateLogging>1</rateLogging>
|
||||||
<rcvBufSize>1000</rcvBufSize>
|
</socket>
|
||||||
<rateLogging>1</rateLogging>
|
</channel>
|
||||||
</socket>
|
|
||||||
</channel>
|
|
||||||
</device>
|
</device>
|
||||||
<device name="sink" id="sink" >
|
<device name="sink" id="sink">
|
||||||
<channel name="one_input" >
|
<channel name="one_input">
|
||||||
<socket name="input1" >
|
<socket name="input1">
|
||||||
<type>pull</type>
|
<type>pull</type>
|
||||||
<method>bind</method>
|
<method>bind</method>
|
||||||
<address>tcp://localhost:5571</address>
|
<address>tcp://localhost:5571</address>
|
||||||
<sndBufSize>1000</sndBufSize>
|
<sndBufSize>1000</sndBufSize>
|
||||||
<rcvBufSize>1000</rcvBufSize>
|
<rcvBufSize>1000</rcvBufSize>
|
||||||
<rateLogging>1</rateLogging>
|
<rateLogging>1</rateLogging>
|
||||||
</socket>
|
</socket>
|
||||||
</channel>
|
</channel>
|
||||||
</device>
|
</device>
|
||||||
</fairMQOptions>
|
</fairMQOptions>
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,6 @@
|
||||||
#include "FairMQParser.h"
|
#include "FairMQParser.h"
|
||||||
#include "FairMQProgOptions.h"
|
#include "FairMQProgOptions.h"
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
// tests
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// Parse xml from file
|
// Parse xml from file
|
||||||
int testXML1(FairMQProgOptions* config)
|
int testXML1(FairMQProgOptions* config)
|
||||||
{
|
{
|
||||||
|
@ -35,7 +29,6 @@ int testXML1(FairMQProgOptions* config)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Parse xml from command line
|
// Parse xml from command line
|
||||||
int testXML2(FairMQProgOptions* config)
|
int testXML2(FairMQProgOptions* config)
|
||||||
{
|
{
|
||||||
|
@ -93,10 +86,6 @@ int testJSON2(FairMQProgOptions* config)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
/// main
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
FairMQProgOptions* config= new FairMQProgOptions();
|
FairMQProgOptions* config= new FairMQProgOptions();
|
||||||
|
@ -111,28 +100,36 @@ int main(int argc, char** argv)
|
||||||
config->AddToCmdLineOptions(format_desc);
|
config->AddToCmdLineOptions(format_desc);
|
||||||
|
|
||||||
// Parse command line
|
// Parse command line
|
||||||
if(config->ParseAll(argc,argv))
|
if (config->ParseAll(argc,argv))
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Set severity level (Default is 0=DEBUG)
|
// Set severity level (Default is 0=DEBUG)
|
||||||
int verbosity = config->GetValue<int>("verbosity");
|
int severity = config->GetValue<int>("severity");
|
||||||
FairMQLogger::Level lvl=static_cast<FairMQLogger::Level>(verbosity);
|
FairMQLogger::Level lvl=static_cast<FairMQLogger::Level>(severity);
|
||||||
SET_LOGGER_LEVEL(lvl);
|
SET_LOGGER_LEVEL(lvl);
|
||||||
|
|
||||||
|
|
||||||
// Parse xml or json from cmd line or file
|
// 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);
|
testXML1(config);
|
||||||
|
}
|
||||||
|
|
||||||
if(config->GetVarMap().count("config-xml-string"))
|
if (config->GetVarMap().count("config-xml-string"))
|
||||||
|
{
|
||||||
testXML2(config);
|
testXML2(config);
|
||||||
|
}
|
||||||
|
|
||||||
if(config->GetVarMap().count("config-json-file"))
|
if (config->GetVarMap().count("config-json-file"))
|
||||||
|
{
|
||||||
testJSON1(config);
|
testJSON1(config);
|
||||||
|
}
|
||||||
|
|
||||||
if(config->GetVarMap().count("config-json-string"))
|
if (config->GetVarMap().count("config-json-string"))
|
||||||
|
{
|
||||||
testJSON2(config);
|
testJSON2(config);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
|
@ -142,9 +139,3 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
FairMQProgOptions config;
|
FairMQProgOptions config;
|
||||||
|
@ -39,7 +38,6 @@ int main(int argc, char** argv)
|
||||||
config.AddToCmdLineOptions(format_desc,true);
|
config.AddToCmdLineOptions(format_desc,true);
|
||||||
config.AddToCmdLineOptions(io_file_opt_desc,true);
|
config.AddToCmdLineOptions(io_file_opt_desc,true);
|
||||||
|
|
||||||
|
|
||||||
config.EnableCfgFile();// UseConfigFile (by default config file is not defined)
|
config.EnableCfgFile();// UseConfigFile (by default config file is not defined)
|
||||||
config.AddToCfgFileOptions(format_desc,false);//false because already added to visible
|
config.AddToCfgFileOptions(format_desc,false);//false because already added to visible
|
||||||
config.AddToCfgFileOptions(io_file_opt_desc,false);
|
config.AddToCfgFileOptions(io_file_opt_desc,false);
|
||||||
|
@ -49,8 +47,8 @@ int main(int argc, char** argv)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Set severity level (Default is 0=DEBUG)
|
// Set severity level (Default is 0=DEBUG)
|
||||||
int verbosity=config.GetValue<int>("verbosity");
|
int severity = config.GetValue<int>("severity");
|
||||||
FairMQLogger::Level lvl=static_cast<FairMQLogger::Level>(verbosity);
|
FairMQLogger::Level lvl = static_cast<FairMQLogger::Level>(severity);
|
||||||
SET_LOGGER_LEVEL(lvl);
|
SET_LOGGER_LEVEL(lvl);
|
||||||
|
|
||||||
// parse XML file
|
// parse XML file
|
||||||
|
@ -61,8 +59,6 @@ int main(int argc, char** argv)
|
||||||
XMLrootNode=config.GetValue<std::string>("xml.config.node.root");
|
XMLrootNode=config.GetValue<std::string>("xml.config.node.root");
|
||||||
std::string id=config.GetValue<std::string>("id");
|
std::string id=config.GetValue<std::string>("id");
|
||||||
config.UserParser<FairMQParser::XML>(filename,id,XMLrootNode);
|
config.UserParser<FairMQParser::XML>(filename,id,XMLrootNode);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
|
@ -71,9 +67,3 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,6 @@ VERBOSE="DEBUG"
|
||||||
JSONCONFIGFILE="@CMAKE_BINARY_DIR@/bin/config/ex1-sampler-sink.json"
|
JSONCONFIGFILE="@CMAKE_BINARY_DIR@/bin/config/ex1-sampler-sink.json"
|
||||||
|
|
||||||
########################## start DEVICE
|
########################## start DEVICE
|
||||||
DEVICE="runConfigExample --transport $TRANSPORT --verbosity $VERBOSE"
|
DEVICE="runConfigExample --transport $TRANSPORT --severity $VERBOSE"
|
||||||
DEVICE+=" --id sampler1 --mq-config $JSONCONFIGFILE"
|
DEVICE+=" --id sampler1 --mq-config $JSONCONFIGFILE"
|
||||||
@CMAKE_BINARY_DIR@/bin/$DEVICE
|
@CMAKE_BINARY_DIR@/bin/$DEVICE
|
||||||
|
|
|
@ -127,43 +127,43 @@ auto Control::InteractiveMode() -> void
|
||||||
switch (input)
|
switch (input)
|
||||||
{
|
{
|
||||||
case 'i':
|
case 'i':
|
||||||
LOG(INFO) << "[i] init device";
|
LOG(INFO) << "\n\n --> [i] init device\n";
|
||||||
ChangeDeviceState(DeviceStateTransition::InitDevice);
|
ChangeDeviceState(DeviceStateTransition::InitDevice);
|
||||||
break;
|
break;
|
||||||
case 'j':
|
case 'j':
|
||||||
LOG(INFO) << "[j] init task";
|
LOG(INFO) << "\n\n --> [j] init task\n";
|
||||||
ChangeDeviceState(DeviceStateTransition::InitTask);
|
ChangeDeviceState(DeviceStateTransition::InitTask);
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
LOG(INFO) << "[p] pause";
|
LOG(INFO) << "\n\n --> [p] pause\n";
|
||||||
ChangeDeviceState(DeviceStateTransition::Pause);
|
ChangeDeviceState(DeviceStateTransition::Pause);
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
LOG(INFO) << "[r] run";
|
LOG(INFO) << "\n\n --> [r] run\n";
|
||||||
ChangeDeviceState(DeviceStateTransition::Run);
|
ChangeDeviceState(DeviceStateTransition::Run);
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
LOG(INFO) << "[s] stop";
|
LOG(INFO) << "\n\n --> [s] stop\n";
|
||||||
ChangeDeviceState(DeviceStateTransition::Stop);
|
ChangeDeviceState(DeviceStateTransition::Stop);
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
LOG(INFO) << "[t] reset task";
|
LOG(INFO) << "\n\n --> [t] reset task\n";
|
||||||
ChangeDeviceState(DeviceStateTransition::ResetTask);
|
ChangeDeviceState(DeviceStateTransition::ResetTask);
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
LOG(INFO) << "[d] reset device";
|
LOG(INFO) << "\n\n --> [d] reset device\n";
|
||||||
ChangeDeviceState(DeviceStateTransition::ResetDevice);
|
ChangeDeviceState(DeviceStateTransition::ResetDevice);
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
LOG(INFO) << "[h] help";
|
LOG(INFO) << "\n\n --> [h] help\n";
|
||||||
PrintInteractiveHelp();
|
PrintInteractiveHelp();
|
||||||
break;
|
break;
|
||||||
// case 'x':
|
// case 'x':
|
||||||
// LOG(INFO) << "[x] ERROR";
|
// LOG(INFO) << "\n\n --> [x] ERROR\n";
|
||||||
// ChangeDeviceState(DeviceStateTransition::ERROR_FOUND);
|
// ChangeDeviceState(DeviceStateTransition::ERROR_FOUND);
|
||||||
// break;
|
// break;
|
||||||
case 'q':
|
case 'q':
|
||||||
LOG(INFO) << "[q] end";
|
LOG(INFO) << "\n\n --> [q] end\n";
|
||||||
keepRunning = false;
|
keepRunning = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -197,8 +197,8 @@ auto Control::InteractiveMode() -> void
|
||||||
|
|
||||||
auto Control::PrintInteractiveHelp() -> void
|
auto Control::PrintInteractiveHelp() -> void
|
||||||
{
|
{
|
||||||
LOG(INFO) << "Use keys to control the state machine:";
|
LOG(INFO) << "Use keys to control the state machine:\n\n"
|
||||||
LOG(INFO) << "[h] help, [p] pause, [r] run, [s] stop, [t] reset task, [d] reset device, [q] end, [j] init task, [i] init device";
|
<< "[h] help, [p] pause, [r] run, [s] stop, [t] reset task, [d] reset device, [q] end, [j] init task, [i] init device\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Control::WaitForNextState() -> DeviceState
|
auto Control::WaitForNextState() -> DeviceState
|
||||||
|
|
|
@ -65,6 +65,7 @@ SAMPLER+=" --id bsampler1"
|
||||||
#SAMPLER+=" --io-threads 2"
|
#SAMPLER+=" --io-threads 2"
|
||||||
#SAMPLER+=" --control static"
|
#SAMPLER+=" --control static"
|
||||||
SAMPLER+=" --transport $transport"
|
SAMPLER+=" --transport $transport"
|
||||||
|
SAMPLER+=" --severity debug"
|
||||||
SAMPLER+=" --msg-size $msgSize"
|
SAMPLER+=" --msg-size $msgSize"
|
||||||
SAMPLER+=" --same-msg $sameMsg"
|
SAMPLER+=" --same-msg $sameMsg"
|
||||||
# SAMPLER+=" --msg-rate 1000"
|
# SAMPLER+=" --msg-rate 1000"
|
||||||
|
@ -80,6 +81,7 @@ SINK+=" --id sink1"
|
||||||
#SINK+=" --io-threads 2"
|
#SINK+=" --io-threads 2"
|
||||||
#SINK+=" --control static"
|
#SINK+=" --control static"
|
||||||
SINK+=" --transport $transport"
|
SINK+=" --transport $transport"
|
||||||
|
SINK+=" --severity debug"
|
||||||
SINK+=" --max-iterations $maxIterations"
|
SINK+=" --max-iterations $maxIterations"
|
||||||
SINK+=" --mq-config @CMAKE_BINARY_DIR@/bin/config/benchmark.json"
|
SINK+=" --mq-config @CMAKE_BINARY_DIR@/bin/config/benchmark.json"
|
||||||
xterm -geometry 90x23+550+0 -hold -e $affinitySink @CMAKE_BINARY_DIR@/bin/$SINK &
|
xterm -geometry 90x23+550+0 -hold -e $affinitySink @CMAKE_BINARY_DIR@/bin/$SINK &
|
||||||
|
|
|
@ -14,7 +14,7 @@ echo "Usage: startShmPrototype [message size=1000000]"
|
||||||
SAMPLER="shm-prototype-sampler"
|
SAMPLER="shm-prototype-sampler"
|
||||||
SAMPLER+=" --id sampler1"
|
SAMPLER+=" --id sampler1"
|
||||||
SAMPLER+=" --transport $transport"
|
SAMPLER+=" --transport $transport"
|
||||||
# SAMPLER+=" --verbosity TRACE"
|
# SAMPLER+=" --severity TRACE"
|
||||||
SAMPLER+=" --msg-size $msgSize"
|
SAMPLER+=" --msg-size $msgSize"
|
||||||
# SAMPLER+=" --msg-rate 1000"
|
# SAMPLER+=" --msg-rate 1000"
|
||||||
SAMPLER+=" --mq-config @CMAKE_BINARY_DIR@/bin/config/shm-prototype.json"
|
SAMPLER+=" --mq-config @CMAKE_BINARY_DIR@/bin/config/shm-prototype.json"
|
||||||
|
@ -23,27 +23,27 @@ xterm -geometry 80x32+0+0 -hold -e @CMAKE_BINARY_DIR@/bin/prototype/shmem/$SAMPL
|
||||||
SINK1="shm-prototype-sink"
|
SINK1="shm-prototype-sink"
|
||||||
SINK1+=" --id sink1"
|
SINK1+=" --id sink1"
|
||||||
SINK1+=" --transport $transport"
|
SINK1+=" --transport $transport"
|
||||||
# SINK1+=" --verbose TRACE"
|
# SINK1+=" --severity TRACE"
|
||||||
SINK1+=" --mq-config @CMAKE_BINARY_DIR@/bin/config/shm-prototype.json"
|
SINK1+=" --mq-config @CMAKE_BINARY_DIR@/bin/config/shm-prototype.json"
|
||||||
xterm -geometry 80x32+500+0 -hold -e @CMAKE_BINARY_DIR@/bin/prototype/shmem/$SINK1 &
|
xterm -geometry 80x32+500+0 -hold -e @CMAKE_BINARY_DIR@/bin/prototype/shmem/$SINK1 &
|
||||||
|
|
||||||
# SINK2="shm-prototype-sink"
|
# SINK2="shm-prototype-sink"
|
||||||
# SINK2+=" --id sink2"
|
# SINK2+=" --id sink2"
|
||||||
# SINK2+=" --transport $transport"
|
# SINK2+=" --transport $transport"
|
||||||
# # SINK2+=" --verbose TRACE"
|
# # SINK2+=" --severity TRACE"
|
||||||
# SINK2+=" --mq-config @CMAKE_BINARY_DIR@/bin/config/shm-prototype.json"
|
# SINK2+=" --mq-config @CMAKE_BINARY_DIR@/bin/config/shm-prototype.json"
|
||||||
# xterm -geometry 80x32+500+500 -hold -e @CMAKE_BINARY_DIR@/bin/prototype/shmem/$SINK2 &
|
# xterm -geometry 80x32+500+500 -hold -e @CMAKE_BINARY_DIR@/bin/prototype/shmem/$SINK2 &
|
||||||
|
|
||||||
# SINK3="shm-prototype-sink"
|
# SINK3="shm-prototype-sink"
|
||||||
# SINK3+=" --id sink3"
|
# SINK3+=" --id sink3"
|
||||||
# SINK3+=" --transport $transport"
|
# SINK3+=" --transport $transport"
|
||||||
# # SINK3+=" --verbose TRACE"
|
# # SINK3+=" --severity TRACE"
|
||||||
# SINK3+=" --mq-config @CMAKE_BINARY_DIR@/bin/config/shm-prototype.json"
|
# SINK3+=" --mq-config @CMAKE_BINARY_DIR@/bin/config/shm-prototype.json"
|
||||||
# xterm -geometry 80x32+1000+0 -hold -e @CMAKE_BINARY_DIR@/bin/prototype/shmem/$SINK3 &
|
# xterm -geometry 80x32+1000+0 -hold -e @CMAKE_BINARY_DIR@/bin/prototype/shmem/$SINK3 &
|
||||||
|
|
||||||
# SINK4="shm-prototype-sink"
|
# SINK4="shm-prototype-sink"
|
||||||
# SINK4+=" --id sink4"
|
# SINK4+=" --id sink4"
|
||||||
# SINK4+=" --transport $transport"
|
# SINK4+=" --transport $transport"
|
||||||
# # SINK4+=" --verbose TRACE"
|
# # SINK4+=" --severity TRACE"
|
||||||
# SINK4+=" --mq-config @CMAKE_BINARY_DIR@/bin/config/shm-prototype.json"
|
# SINK4+=" --mq-config @CMAKE_BINARY_DIR@/bin/config/shm-prototype.json"
|
||||||
# xterm -geometry 80x32+1000+500 -hold -e @CMAKE_BINARY_DIR@/bin/prototype/shmem/$SINK4 &
|
# xterm -geometry 80x32+1000+500 -hold -e @CMAKE_BINARY_DIR@/bin/prototype/shmem/$SINK4 &
|
||||||
|
|
|
@ -27,7 +27,7 @@ auto RunPoller(string transport, int pollType) -> void
|
||||||
stringstream cmd;
|
stringstream cmd;
|
||||||
cmd << runTestDevice
|
cmd << runTestDevice
|
||||||
<< " --id pollout_"<< transport
|
<< " --id pollout_"<< transport
|
||||||
<< " --control static --verbosity DEBUG --log-color false"
|
<< " --control static --severity DEBUG --color false"
|
||||||
<< " --session " << session << " --mq-config \"" << mqConfig << "\"";
|
<< " --session " << session << " --mq-config \"" << mqConfig << "\"";
|
||||||
pollout = execute(cmd.str(), "[POLLOUT]");
|
pollout = execute(cmd.str(), "[POLLOUT]");
|
||||||
});
|
});
|
||||||
|
@ -37,7 +37,7 @@ auto RunPoller(string transport, int pollType) -> void
|
||||||
stringstream cmd;
|
stringstream cmd;
|
||||||
cmd << runTestDevice
|
cmd << runTestDevice
|
||||||
<< " --id pollin_" << transport
|
<< " --id pollin_" << transport
|
||||||
<< " --control static --verbosity DEBUG --log-color false"
|
<< " --control static --severity DEBUG --color false"
|
||||||
<< " --session " << session << " --mq-config \"" << mqConfig << "\" --poll-type " << pollType;
|
<< " --session " << session << " --mq-config \"" << mqConfig << "\" --poll-type " << pollType;
|
||||||
pollin = execute(cmd.str(), "[POLLIN]");
|
pollin = execute(cmd.str(), "[POLLIN]");
|
||||||
});
|
});
|
||||||
|
|
|
@ -25,24 +25,24 @@ auto RunPubSub(string transport) -> void
|
||||||
auto pub = execute_result{"", 0};
|
auto pub = execute_result{"", 0};
|
||||||
thread pub_thread([&]() {
|
thread pub_thread([&]() {
|
||||||
stringstream cmd;
|
stringstream cmd;
|
||||||
cmd << runTestDevice << " --id pub_" << transport << " --control static --verbosity DEBUG "
|
cmd << runTestDevice << " --id pub_" << transport << " --control static --severity DEBUG "
|
||||||
<< "--session " << session << " --log-color false --mq-config \"" << mqConfig << "\"";
|
<< "--session " << session << " --color false --mq-config \"" << mqConfig << "\"";
|
||||||
pub = execute(cmd.str(), "[PUB]");
|
pub = execute(cmd.str(), "[PUB]");
|
||||||
});
|
});
|
||||||
|
|
||||||
auto sub1 = execute_result{"", 0};
|
auto sub1 = execute_result{"", 0};
|
||||||
thread sub1_thread([&]() {
|
thread sub1_thread([&]() {
|
||||||
stringstream cmd;
|
stringstream cmd;
|
||||||
cmd << runTestDevice << " --id sub_1" << transport << " --control static --verbosity DEBUG "
|
cmd << runTestDevice << " --id sub_1" << transport << " --control static --severity DEBUG "
|
||||||
<< "--session " << session << " --log-color false --mq-config \"" << mqConfig << "\"";
|
<< "--session " << session << " --color false --mq-config \"" << mqConfig << "\"";
|
||||||
sub1 = execute(cmd.str(), "[SUB1]");
|
sub1 = execute(cmd.str(), "[SUB1]");
|
||||||
});
|
});
|
||||||
|
|
||||||
auto sub2 = execute_result{"", 0};
|
auto sub2 = execute_result{"", 0};
|
||||||
thread sub2_thread([&]() {
|
thread sub2_thread([&]() {
|
||||||
stringstream cmd;
|
stringstream cmd;
|
||||||
cmd << runTestDevice << " --id sub_2" << transport << " --control static --verbosity DEBUG "
|
cmd << runTestDevice << " --id sub_2" << transport << " --control static --severity DEBUG "
|
||||||
<< "--session " << session << " --log-color false --mq-config \"" << mqConfig << "\"";
|
<< "--session " << session << " --color false --mq-config \"" << mqConfig << "\"";
|
||||||
sub2 = execute(cmd.str(), "[SUB2]");
|
sub2 = execute(cmd.str(), "[SUB2]");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -25,16 +25,16 @@ auto RunPushPull(string transport) -> void
|
||||||
auto push = execute_result{"", 100};
|
auto push = execute_result{"", 100};
|
||||||
thread push_thread([&]() {
|
thread push_thread([&]() {
|
||||||
stringstream cmd;
|
stringstream cmd;
|
||||||
cmd << runTestDevice << " --id push_" << transport << " --control static --verbosity DEBUG "
|
cmd << runTestDevice << " --id push_" << transport << " --control static --severity DEBUG "
|
||||||
<< "--session " << session << " --log-color false --mq-config \"" << mqConfig << "\"";
|
<< "--session " << session << " --color false --mq-config \"" << mqConfig << "\"";
|
||||||
push = execute(cmd.str(), "[PUSH]");
|
push = execute(cmd.str(), "[PUSH]");
|
||||||
});
|
});
|
||||||
|
|
||||||
auto pull = execute_result{"", 100};
|
auto pull = execute_result{"", 100};
|
||||||
thread pull_thread([&]() {
|
thread pull_thread([&]() {
|
||||||
stringstream cmd;
|
stringstream cmd;
|
||||||
cmd << runTestDevice << " --id pull_" << transport << " --control static --verbosity DEBUG "
|
cmd << runTestDevice << " --id pull_" << transport << " --control static --severity DEBUG "
|
||||||
<< "--session " << session << " --log-color false --mq-config \"" << mqConfig << "\"";
|
<< "--session " << session << " --color false --mq-config \"" << mqConfig << "\"";
|
||||||
pull = execute(cmd.str(), "[PULL]");
|
pull = execute(cmd.str(), "[PULL]");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -25,24 +25,24 @@ auto RunReqRep(string transport) -> void
|
||||||
auto rep = execute_result{ "", 0 };
|
auto rep = execute_result{ "", 0 };
|
||||||
thread rep_thread([&]() {
|
thread rep_thread([&]() {
|
||||||
stringstream cmd;
|
stringstream cmd;
|
||||||
cmd << runTestDevice << " --id rep_" << transport << " --control static --verbosity DEBUG "
|
cmd << runTestDevice << " --id rep_" << transport << " --control static --severity DEBUG "
|
||||||
<< "--session " << session << " --log-color false --mq-config \"" << mqConfig << "\"";
|
<< "--session " << session << " --color false --mq-config \"" << mqConfig << "\"";
|
||||||
rep = execute(cmd.str(), "[REP]");
|
rep = execute(cmd.str(), "[REP]");
|
||||||
});
|
});
|
||||||
|
|
||||||
auto req1 = execute_result{ "", 0 };
|
auto req1 = execute_result{ "", 0 };
|
||||||
thread req1_thread([&]() {
|
thread req1_thread([&]() {
|
||||||
stringstream cmd;
|
stringstream cmd;
|
||||||
cmd << runTestDevice << " --id req_1" << transport << " --control static --verbosity DEBUG "
|
cmd << runTestDevice << " --id req_1" << transport << " --control static --severity DEBUG "
|
||||||
<< "--session " << session << " --log-color false --mq-config \"" << mqConfig << "\"";
|
<< "--session " << session << " --color false --mq-config \"" << mqConfig << "\"";
|
||||||
req1 = execute(cmd.str(), "[REQ1]");
|
req1 = execute(cmd.str(), "[REQ1]");
|
||||||
});
|
});
|
||||||
|
|
||||||
auto req2 = execute_result{ "", 0 };
|
auto req2 = execute_result{ "", 0 };
|
||||||
thread req2_thread([&]() {
|
thread req2_thread([&]() {
|
||||||
stringstream cmd;
|
stringstream cmd;
|
||||||
cmd << runTestDevice << " --id req_2" << transport << " --control static --verbosity DEBUG "
|
cmd << runTestDevice << " --id req_2" << transport << " --control static --severity DEBUG "
|
||||||
<< "--session " << session << " --log-color false --mq-config \"" << mqConfig << "\"";
|
<< "--session " << session << " --color false --mq-config \"" << mqConfig << "\"";
|
||||||
req2 = execute(cmd.str(), "[REQ2]");
|
req2 = execute(cmd.str(), "[REQ2]");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,8 @@ auto RunTransferTimeout(string transport) -> void
|
||||||
{
|
{
|
||||||
size_t session{fair::mq::tools::UuidHash()};
|
size_t session{fair::mq::tools::UuidHash()};
|
||||||
stringstream cmd;
|
stringstream cmd;
|
||||||
cmd << runTestDevice << " --id transfer_timeout_" << transport << " --control static --verbosity DEBUG "
|
cmd << runTestDevice << " --id transfer_timeout_" << transport << " --control static --severity DEBUG "
|
||||||
<< "--session " << session << " --log-color false --mq-config \"" << mqConfig << "\"";
|
<< "--session " << session << " --color false --mq-config \"" << mqConfig << "\"";
|
||||||
auto res = execute(cmd.str());
|
auto res = execute(cmd.str());
|
||||||
|
|
||||||
cerr << res.error_out;
|
cerr << res.error_out;
|
||||||
|
|
|
@ -40,7 +40,7 @@ auto execute(string cmd, string log_prefix) -> execute_result
|
||||||
out << log_prefix << cmd << endl;
|
out << log_prefix << cmd << endl;
|
||||||
|
|
||||||
// Execute command and capture stderr, add log_prefix line by line
|
// Execute command and capture stderr, add log_prefix line by line
|
||||||
redi::ipstream in(cmd, redi::pstreams::pstderr);
|
redi::ipstream in(cmd, redi::pstreams::pstdout);
|
||||||
auto line = string{};
|
auto line = string{};
|
||||||
while (getline(in, line))
|
while (getline(in, line))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user