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/FairMQSink.h
|
||||
devices/FairMQSplitter.h
|
||||
logger/logger.h
|
||||
options/FairMQParser.h
|
||||
options/FairMQProgOptions.h
|
||||
options/FairMQSuboptParser.h
|
||||
|
@ -127,13 +126,9 @@ if(NANOMSG_FOUND)
|
|||
)
|
||||
endif()
|
||||
|
||||
if("${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}" VERSION_LESS "1.56")
|
||||
set(FAIRMQ_HEADER_FILES_NAMESPACED ${FAIRMQ_HEADER_FILES_NAMESPACED}
|
||||
logger/fairroot_null_deleter.h
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
##########################
|
||||
# libFairMQ source files #
|
||||
##########################
|
||||
set(FAIRMQ_SOURCE_FILES
|
||||
DeviceRunner.cxx
|
||||
FairMQChannel.cxx
|
||||
|
@ -150,7 +145,6 @@ set(FAIRMQ_SOURCE_FILES
|
|||
devices/FairMQProxy.cxx
|
||||
# devices/FairMQSink.cxx
|
||||
devices/FairMQSplitter.cxx
|
||||
logger/logger.cxx
|
||||
options/FairMQParser.cxx
|
||||
options/FairMQProgOptions.cxx
|
||||
options/FairMQSuboptParser.cxx
|
||||
|
@ -208,6 +202,7 @@ add_library(FairMQ SHARED
|
|||
#######################
|
||||
target_include_directories(FairMQ
|
||||
PUBLIC # consumers inherit public include directories
|
||||
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/logger>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>
|
||||
$<INSTALL_INTERFACE:include/fairmq>
|
||||
|
@ -224,8 +219,6 @@ target_link_libraries(FairMQ
|
|||
dl
|
||||
pthread
|
||||
Boost::boost
|
||||
Boost::log
|
||||
Boost::log_setup
|
||||
Boost::program_options
|
||||
Boost::thread
|
||||
Boost::system
|
||||
|
@ -233,6 +226,7 @@ target_link_libraries(FairMQ
|
|||
Boost::regex
|
||||
Boost::date_time
|
||||
Boost::signals
|
||||
Logger
|
||||
$<$<PLATFORM_ID:Linux>:rt>
|
||||
|
||||
PRIVATE # only libFairMQ links against private dependencies
|
||||
|
|
|
@ -41,7 +41,10 @@ auto DeviceRunner::Run() -> int
|
|||
fEvents.Emit<hooks::ModifyRawCmdLineArgs>(*this);
|
||||
////////////////////////
|
||||
|
||||
fConfig.ParseAll(fRawCmdLineArgs, true);
|
||||
if (fConfig.ParseAll(fRawCmdLineArgs, true))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
////// CALL HOOK ///////
|
||||
fEvents.Emit<hooks::InstantiateDevice>(*this);
|
||||
|
|
|
@ -20,6 +20,6 @@
|
|||
timestamp_t get_timestamp()
|
||||
{
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
gettimeofday(&now, nullptr);
|
||||
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 *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
|
@ -15,7 +15,7 @@
|
|||
#ifndef FAIRMQLOGGER_H_
|
||||
#define FAIRMQLOGGER_H_
|
||||
|
||||
#include "logger/logger.h"
|
||||
#include <Logger.h>
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
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;
|
||||
|
||||
|
@ -88,12 +88,12 @@ void PrintDeviceList(const boost::property_tree::ptree& tree, const std::string&
|
|||
if (key != "")
|
||||
{
|
||||
deviceIdKey = key;
|
||||
LOG(TRACE) << "Found config for device key '" << deviceIdKey << "' in JSON input";
|
||||
LOG(DEBUG) << "Found config for device key '" << deviceIdKey << "' in JSON input";
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceIdKey = 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";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ void PrintDeviceList(const boost::property_tree::ptree& tree, const std::string&
|
|||
if (formatFlag == "xml")
|
||||
{
|
||||
deviceIdKey = p.second.get<string>("<xmlattr>.id");
|
||||
LOG(TRACE) << "Found config for '" << deviceIdKey << "' in XML input";
|
||||
LOG(DEBUG) << "Found config for '" << deviceIdKey << "' in XML input";
|
||||
}
|
||||
|
||||
if (formatFlag == "json")
|
||||
|
@ -113,12 +113,12 @@ void PrintDeviceList(const boost::property_tree::ptree& tree, const std::string&
|
|||
if (key != "")
|
||||
{
|
||||
deviceIdKey = key;
|
||||
LOG(TRACE) << "Found config for device key '" << deviceIdKey << "' in JSON input";
|
||||
LOG(DEBUG) << "Found config for device key '" << deviceIdKey << "' in JSON input";
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceIdKey = p.second.get<string>("id");
|
||||
LOG(TRACE) << "Found config for device id '" << deviceIdKey << "' in JSON input";
|
||||
LOG(DEBUG) << "Found config for device id '" << deviceIdKey << "' in JSON input";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -428,7 +428,7 @@ void SocketParser(const boost::property_tree::ptree& tree, vector<FairMQChannel>
|
|||
void PrintPropertyTree(const boost::property_tree::ptree& tree, int level)
|
||||
{
|
||||
for (const auto& p : tree) {
|
||||
std::cout << std::setw(level+1) << level << ": " << p.first << " " << p.second.get_value<string>() << std::endl;
|
||||
cout << setw(level+1) << level << ": " << p.first << " " << p.second.get_value<string>() << endl;
|
||||
PrintPropertyTree(p.second.get_child(""), level + 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,25 +13,22 @@
|
|||
*/
|
||||
|
||||
#include "FairMQProgOptions.h"
|
||||
#include <algorithm>
|
||||
#include "FairMQParser.h"
|
||||
#include "FairMQSuboptParser.h"
|
||||
#include "FairMQLogger.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
FairMQProgOptions::FairMQProgOptions()
|
||||
: FairProgOptions()
|
||||
, fMQParserOptions("MQ-Device parser options")
|
||||
, fMQOptionsInCfg("MQ-Device options")
|
||||
, fMQOptionsInCmd("MQ-Device options")
|
||||
, fMQParserOptions("FairMQ config parser options")
|
||||
, fMQCmdOptions("FairMQ device options")
|
||||
, fFairMQMap()
|
||||
, fHelpTitle("***** FAIRMQ Program Options ***** ")
|
||||
, fVersion("Beta version 0.1")
|
||||
, fChannelInfo()
|
||||
, fMQKeyMap()
|
||||
// , fSignalMap() //string API
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -39,86 +36,51 @@ FairMQProgOptions::~FairMQProgOptions()
|
|||
{
|
||||
}
|
||||
|
||||
void FairMQProgOptions::ParseAll(const std::vector<std::string>& cmdLineArgs, bool allowUnregistered)
|
||||
int FairMQProgOptions::ParseAll(const vector<string>& cmdLineArgs, bool allowUnregistered)
|
||||
{
|
||||
std::vector<const char*> argv(cmdLineArgs.size());
|
||||
vector<const char*> argv(cmdLineArgs.size());
|
||||
|
||||
std::transform(cmdLineArgs.begin(), cmdLineArgs.end(), argv.begin(), [](const std::string& str)
|
||||
transform(cmdLineArgs.begin(), cmdLineArgs.end(), argv.begin(), [](const string& str)
|
||||
{
|
||||
return str.c_str();
|
||||
});
|
||||
|
||||
ParseAll(argv.size(), const_cast<char**>(argv.data()), allowUnregistered);
|
||||
return ParseAll(argv.size(), const_cast<char**>(argv.data()), allowUnregistered);
|
||||
}
|
||||
|
||||
void FairMQProgOptions::ParseAll(const int argc, char const* const* argv, bool allowUnregistered)
|
||||
int FairMQProgOptions::ParseAll(const int argc, char const* const* argv, bool allowUnregistered)
|
||||
{
|
||||
// init description
|
||||
InitOptionDescription();
|
||||
// parse command line options
|
||||
|
||||
if (FairProgOptions::ParseCmdLine(argc, argv, fCmdLineOptions, fVarMap, allowUnregistered))
|
||||
{
|
||||
// ParseCmdLine return 0 if help or version cmd not called. return 1 if called
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
// if txt/INI configuration file enabled then parse it as well
|
||||
if (fUseConfigFile)
|
||||
{
|
||||
// check if file exist
|
||||
if (fs::exists(fConfigFile))
|
||||
{
|
||||
if (FairProgOptions::ParseCfgFile(fConfigFile.string(), fConfigFileOptions, fVarMap, allowUnregistered))
|
||||
{
|
||||
// ParseCfgFile return -1 if cannot open or read config file. It return 0 otherwise
|
||||
LOG(ERROR) << "Could not parse config";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(ERROR) << "config file '" << fConfigFile << "' not found";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (fVarMap.count("print-options"))
|
||||
{
|
||||
PrintOptionsRaw();
|
||||
exit(EXIT_SUCCESS);
|
||||
// ParseCmdLine returns 0 if no immediate switches found.
|
||||
return 1;
|
||||
}
|
||||
|
||||
// if these options are provided, do no further checks and let the device handle them
|
||||
if (fVarMap.count("print-channels") || fVarMap.count("version"))
|
||||
{
|
||||
fair::mq::logger::DefaultConsoleSetFilter(fSeverityMap.at("NOLOG"));
|
||||
return;
|
||||
fair::Logger::SetConsoleSeverity("nolog");
|
||||
return 0;
|
||||
}
|
||||
|
||||
string severity = GetValue<string>("severity");
|
||||
string logFile = GetValue<string>("log-to-file");
|
||||
bool color = GetValue<bool>("color");
|
||||
|
||||
string verbosity = GetValue<string>("verbosity");
|
||||
string logFile = GetValue<string>("log-to-file");
|
||||
bool color = GetValue<bool>("log-color");
|
||||
|
||||
// check if the provided verbosity level is valid, otherwise set to DEBUG
|
||||
if (fSeverityMap.count(verbosity) == 0)
|
||||
{
|
||||
LOG(ERROR) << " verbosity level '" << verbosity << "' unknown, it will be set to DEBUG";
|
||||
verbosity = "DEBUG";
|
||||
}
|
||||
fair::Logger::SetVerbosity(verbosity);
|
||||
|
||||
if (logFile != "")
|
||||
{
|
||||
fair::mq::logger::ReinitLogger(false, logFile, fSeverityMap.at(verbosity));
|
||||
fair::mq::logger::DefaultConsoleSetFilter(fSeverityMap.at("NOLOG"));
|
||||
fair::Logger::InitFileSink(logFile, severity);
|
||||
fair::Logger::SetConsoleSeverity("nolog");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!color)
|
||||
{
|
||||
fair::mq::logger::ReinitLogger(false);
|
||||
}
|
||||
|
||||
fair::mq::logger::DefaultConsoleSetFilter(fSeverityMap.at(verbosity));
|
||||
fair::Logger::SetConsoleColor(color);
|
||||
fair::Logger::SetConsoleSeverity(severity);
|
||||
}
|
||||
|
||||
// check if one of required MQ config option is there
|
||||
|
@ -140,9 +102,9 @@ void FairMQProgOptions::ParseAll(const int argc, char const* const* argv, bool a
|
|||
LOG(WARN) << "FairMQProgOptions: no channels configuration provided via neither of:";
|
||||
for (const auto& p : MQParserKeys)
|
||||
{
|
||||
LOG(WARN) << " --" << p;
|
||||
LOG(WARNING) << " --" << p;
|
||||
}
|
||||
LOG(WARN) << "No channels will be created (You can create them manually).";
|
||||
LOG(warn) << "No channels will be created (You can create them manually).";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -180,10 +142,8 @@ void FairMQProgOptions::ParseAll(const int argc, char const* const* argv, bool a
|
|||
}
|
||||
else
|
||||
{
|
||||
LOG(ERROR) << "mq-config command line called but file extension '"
|
||||
<< ext
|
||||
<< "' not recognized. Program will now exit";
|
||||
exit(EXIT_FAILURE);
|
||||
LOG(error) << "mq-config command line called but file extension '" << ext << "' not recognized. Program will now exit";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -213,6 +173,8 @@ void FairMQProgOptions::ParseAll(const int argc, char const* const* argv, bool a
|
|||
}
|
||||
|
||||
FairProgOptions::PrintOptions();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FairMQProgOptions::Store(const FairMQMap& channels)
|
||||
|
@ -237,7 +199,7 @@ void FairMQProgOptions::UpdateChannelInfo()
|
|||
fChannelInfo.clear();
|
||||
for (const auto& c : fFairMQMap)
|
||||
{
|
||||
fChannelInfo.insert(std::make_pair(c.first, c.second.size()));
|
||||
fChannelInfo.insert(make_pair(c.first, c.second.size()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,60 +237,44 @@ void FairMQProgOptions::UpdateMQValues()
|
|||
UpdateVarMap<string>(methodKey, channel.GetMethod());
|
||||
UpdateVarMap<string>(addressKey, channel.GetAddress());
|
||||
UpdateVarMap<string>(transportKey, channel.GetTransport());
|
||||
|
||||
//UpdateVarMap<string>(sndBufSizeKey, to_string(channel.GetSndBufSize()));// string API
|
||||
UpdateVarMap<int>(sndBufSizeKey, channel.GetSndBufSize());
|
||||
|
||||
//UpdateVarMap<string>(rcvBufSizeKey, to_string(channel.GetRcvBufSize()));// string API
|
||||
UpdateVarMap<int>(rcvBufSizeKey, channel.GetRcvBufSize());
|
||||
|
||||
//UpdateVarMap<string>(sndKernelSizeKey, to_string(channel.GetSndKernelSize()));// string API
|
||||
UpdateVarMap<int>(sndKernelSizeKey, channel.GetSndKernelSize());
|
||||
|
||||
//UpdateVarMap<string>(rcvKernelSizeKey, to_string(channel.GetRcvKernelSize()));// string API
|
||||
UpdateVarMap<int>(rcvKernelSizeKey, channel.GetRcvKernelSize());
|
||||
|
||||
//UpdateVarMap<string>(rateLoggingKey,to_string(channel.GetRateLogging()));// string API
|
||||
UpdateVarMap<int>(rateLoggingKey, channel.GetRateLogging());
|
||||
|
||||
/*
|
||||
LOG(DEBUG) << "Update MQ parameters of variable map";
|
||||
LOG(DEBUG) << "key = " << typeKey <<"\t value = " << GetValue<string>(typeKey);
|
||||
LOG(DEBUG) << "key = " << methodKey <<"\t value = " << GetValue<string>(methodKey);
|
||||
LOG(DEBUG) << "key = " << addressKey <<"\t value = " << GetValue<string>(addressKey);
|
||||
LOG(DEBUG) << "key = " << sndBufSizeKey << "\t value = " << GetValue<int>(sndBufSizeKey);
|
||||
LOG(DEBUG) << "key = " << rcvBufSizeKey <<"\t value = " << GetValue<int>(rcvBufSizeKey);
|
||||
LOG(DEBUG) << "key = " << sndKernelSizeKey << "\t value = " << GetValue<int>(sndKernelSizeKey);
|
||||
LOG(DEBUG) << "key = " << rcvKernelSizeKey <<"\t value = " << GetValue<int>(rcvKernelSizeKey);
|
||||
LOG(DEBUG) << "key = " << rateLoggingKey <<"\t value = " << GetValue<int>(rateLoggingKey);
|
||||
*/
|
||||
index++;
|
||||
}
|
||||
UpdateVarMap<int>(p.first + ".numSockets", index);
|
||||
UpdateVarMap<int>("chans." + p.first + ".numSockets", index);
|
||||
}
|
||||
}
|
||||
|
||||
int FairMQProgOptions::NotifySwitchOption()
|
||||
int FairMQProgOptions::ImmediateOptions()
|
||||
{
|
||||
if (fVarMap.count("help"))
|
||||
{
|
||||
std::cout << fHelpTitle << std::endl << fVisibleOptions;
|
||||
cout << "===== FairMQ Program Options =====" << endl << fVisibleOptions;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fVarMap.count("print-options"))
|
||||
{
|
||||
PrintOptionsRaw();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FairMQProgOptions::FillOptionDescription(boost::program_options::options_description& options)
|
||||
void FairMQProgOptions::InitOptionDescription()
|
||||
{
|
||||
options.add_options()
|
||||
fMQCmdOptions.add_options()
|
||||
("id", po::value<string>(), "Device ID (required argument).")
|
||||
("io-threads", po::value<int >()->default_value(1), "Number of I/O threads.")
|
||||
("transport", po::value<string>()->default_value("zeromq"), "Transport ('zeromq'/'nanomsg').")
|
||||
("config", po::value<string>()->default_value("static"), "Config source ('static'/<config library filename>).")
|
||||
("network-interface", po::value<string>()->default_value("default"), "Network interface to bind on (e.g. eth0, ib0..., default will try to detect the interface of the default route).")
|
||||
("config-key", po::value<string>(), "Use provided value instead of device id for fetching the configuration from the config file.")
|
||||
("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.")
|
||||
|
@ -339,40 +285,16 @@ void FairMQProgOptions::FillOptionDescription(boost::program_options::options_de
|
|||
("session", po::value<string>()->default_value("default"), "Session name.")
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
void FairMQProgOptions::InitOptionDescription()
|
||||
{
|
||||
// Id required in command line if config txt file not enabled
|
||||
if (fUseConfigFile)
|
||||
{
|
||||
FillOptionDescription(fMQOptionsInCmd);
|
||||
|
||||
FillOptionDescription(fMQOptionsInCfg);
|
||||
}
|
||||
else
|
||||
{
|
||||
FillOptionDescription(fMQOptionsInCmd);
|
||||
}
|
||||
|
||||
fMQParserOptions.add_options()
|
||||
("config-xml-string", po::value<vector<string>>()->multitoken(), "XML input as command line string.")
|
||||
// ("config-xml-file", po::value<string>(), "XML input as file.")
|
||||
("config-json-string", po::value<vector<string>>()->multitoken(), "JSON input as command line string.")
|
||||
// ("config-json-file", po::value<string>(), "JSON input as file.")
|
||||
("mq-config", po::value<string>(), "JSON/XML input as file. The configuration object will check xml or json file extention and will call the json or xml parser accordingly")
|
||||
(FairMQParser::SUBOPT::OptionKeyChannelConfig, po::value<std::vector<std::string>>()->multitoken()->composing(), "Configuration of single or multiple channel(s) by comma separated key=value list")
|
||||
(FairMQParser::SUBOPT::OptionKeyChannelConfig, po::value<vector<string>>()->multitoken()->composing(), "Configuration of single or multiple channel(s) by comma separated key=value list")
|
||||
;
|
||||
|
||||
AddToCmdLineOptions(fGenericDesc);
|
||||
AddToCmdLineOptions(fMQOptionsInCmd);
|
||||
AddToCmdLineOptions(fGeneralDesc);
|
||||
AddToCmdLineOptions(fMQCmdOptions);
|
||||
AddToCmdLineOptions(fMQParserOptions);
|
||||
|
||||
if (fUseConfigFile)
|
||||
{
|
||||
AddToCfgFileOptions(fMQOptionsInCfg, false);
|
||||
AddToCfgFileOptions(fMQParserOptions, false);
|
||||
}
|
||||
}
|
||||
|
||||
int FairMQProgOptions::UpdateChannelMap(const string& channelName, int index, const string& member, const string& val)
|
||||
|
@ -409,45 +331,6 @@ int FairMQProgOptions::UpdateChannelMap(const string& channelName, int index, co
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// string API
|
||||
int FairMQProgOptions::UpdateChannelMap(const string& channelName, int index, const string& member, const string& val)
|
||||
{
|
||||
if (member == "type")
|
||||
{
|
||||
fFairMQMap.at(channelName).at(index).UpdateType(val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (member == "method")
|
||||
{
|
||||
fFairMQMap.at(channelName).at(index).UpdateMethod(val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (member == "address")
|
||||
{
|
||||
fFairMQMap.at(channelName).at(index).UpdateAddress(val);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (member == "sndBufSize" || member == "rcvBufSize" || member == "rateLogging")
|
||||
{
|
||||
UpdateChannelMap(channelName,index,member,ConvertTo<int>(val));
|
||||
}
|
||||
|
||||
//if we get there it means something is wrong
|
||||
LOG(ERROR) << "update of FairMQChannel map failed for the following key: "
|
||||
<< channelName<<"."<<index<<"."<<member;
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
int FairMQProgOptions::UpdateChannelMap(const string& channelName, int index, const string& member, int val)
|
||||
{
|
||||
if (member == "sndBufSize")
|
||||
|
@ -470,8 +353,7 @@ int FairMQProgOptions::UpdateChannelMap(const string& channelName, int index, co
|
|||
else
|
||||
{
|
||||
// if we get there it means something is wrong
|
||||
LOG(ERROR) << "update of FairMQChannel map failed for the following key: "
|
||||
<< channelName << "." << index << "." << member;
|
||||
LOG(ERROR) << "update of FairMQChannel map failed for the following key: " << channelName << "." << index << "." << member;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,16 +18,15 @@
|
|||
|
||||
#include <fairmq/EventManager.h>
|
||||
|
||||
#include "FairProgOptions.h"
|
||||
#include "FairMQChannel.h"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
#include "FairProgOptions.h"
|
||||
#include "FairMQChannel.h"
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace mq
|
||||
|
@ -43,17 +42,15 @@ class FairMQProgOptions : public FairProgOptions
|
|||
{
|
||||
protected:
|
||||
using FairMQMap = std::unordered_map<std::string, std::vector<FairMQChannel>>;
|
||||
//using signal_type = boost::signals2::signal<void(const std::string&, const std::string&)>;// string API
|
||||
//using signal_type_ptr = boost::shared_ptr<signal_type>;// string API
|
||||
|
||||
public:
|
||||
FairMQProgOptions();
|
||||
virtual ~FairMQProgOptions();
|
||||
|
||||
void ParseAll(const std::vector<std::string>& cmdLineArgs, bool allowUnregistered);
|
||||
// parse command line and txt/INI configuration file.
|
||||
int ParseAll(const std::vector<std::string>& cmdLineArgs, bool allowUnregistered);
|
||||
// parse command line.
|
||||
// default parser for the mq-configuration file (JSON/XML) is called if command line key mq-config is called
|
||||
virtual void ParseAll(const int argc, char const* const* argv, bool allowUnregistered = false);
|
||||
int ParseAll(const int argc, char const* const* argv, bool allowUnregistered = false) override;
|
||||
|
||||
// external parser, store function
|
||||
template <typename T, typename ...Args>
|
||||
|
@ -81,94 +78,12 @@ class FairMQProgOptions : public FairProgOptions
|
|||
return fChannelInfo;
|
||||
}
|
||||
|
||||
// to customize title of the executable help command line
|
||||
void SetHelpTitle(const std::string& title)
|
||||
{
|
||||
fHelpTitle = title;
|
||||
}
|
||||
// to customize the executable version command line
|
||||
void SetVersion(const std::string& version)
|
||||
{
|
||||
fVersion = version;
|
||||
}
|
||||
|
||||
// store key-value of type T into variable_map.
|
||||
// If key is found in fMQKeyMap, update the FairMQChannelMap accordingly
|
||||
// Note that the fMQKeyMap is filled:
|
||||
// - if UpdateChannelMap(const FairMQMap& map) method is called
|
||||
// - if UserParser template method is called (it is called in the ParseAll method if json or xml MQ-config files is provided)
|
||||
|
||||
|
||||
/* // string API
|
||||
|
||||
//overload for string literal
|
||||
int UpdateValue(const std::string& key, const char* val) // string API
|
||||
{
|
||||
UpdateValue(key,std::string(val));
|
||||
return 0;
|
||||
}
|
||||
// overload for string values
|
||||
int UpdateValue(const std::string& key, const std::string& val) // string API
|
||||
{
|
||||
try
|
||||
{
|
||||
if (fVarMap.count(key))
|
||||
{
|
||||
|
||||
|
||||
if (!FairMQ::is_this_type<std::string>(fVarMap.at(key)))
|
||||
{
|
||||
LOG(ERROR) << "You try to update a value as string (for key="<< key <<") while it has been defined with a different type in the option description.";
|
||||
abort();
|
||||
}
|
||||
|
||||
// update variable map
|
||||
UpdateVarMap(key,val);
|
||||
|
||||
if (fMQKeyMap.count(key))
|
||||
{
|
||||
std::string channelName;
|
||||
int index = 0;
|
||||
std::string member;
|
||||
std::tie(channelName, index, member) = fMQKeyMap.at(key);
|
||||
UpdateChannelMap(channelName, index, member, val);
|
||||
}
|
||||
|
||||
// execute stored function of a given key if exist
|
||||
//if (std::is_same<T, int>::value || std::is_same<T, std::string>::value)//if one wants to restrict type
|
||||
if (fSignalMap.count(key))
|
||||
EmitUpdate(key,val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
LOG(ERROR) <<"UpdatedValue failed because the provided key '"
|
||||
<<key
|
||||
<<"' is not found in the variable map";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
LOG(ERROR) << "Caught exception on key "<<key;
|
||||
abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//overload for string literal
|
||||
/*int UpdateValue(const std::string& key, const char* val) // string API
|
||||
{
|
||||
UpdateValue<std::string>(key,val);
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
|
||||
// specialization/overloading for string, pass by const ref
|
||||
int UpdateValue(const std::string& key, const std::string& val) // string API
|
||||
{
|
||||
|
@ -214,9 +129,7 @@ class FairMQProgOptions : public FairProgOptions
|
|||
}
|
||||
else
|
||||
{
|
||||
LOG(ERROR) << "UpdatedValue failed because the provided key '"
|
||||
<< key
|
||||
<< "' is not found in the variable map";
|
||||
LOG(error) << "UpdateValue failed: key '" << key << "' not found in the variable map";
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -284,30 +197,14 @@ class FairMQProgOptions : public FairProgOptions
|
|||
|
||||
fEvents.Unsubscribe<fair::mq::PropertyChangeAsString, std::string>(subscriber);
|
||||
}
|
||||
/*
|
||||
template <typename F>
|
||||
void Subscribe(const std::string& key, F&& func)
|
||||
{
|
||||
if (fVarMap.count(key))
|
||||
{
|
||||
//if key-value not yet found, then add it
|
||||
if (fSignalMap.find(key) == fSignalMap.end())
|
||||
fSignalMap.emplace(key, boost::make_shared<signal_type>());
|
||||
(*fSignalMap.at(key)).connect(std::forward<F>(func));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// replace FairMQChannelMap, and update variable map accordingly
|
||||
int UpdateChannelMap(const FairMQMap& map);
|
||||
|
||||
protected:
|
||||
po::options_description fMQCmdOptions;
|
||||
po::options_description fMQParserOptions;
|
||||
po::options_description fMQOptionsInCfg;
|
||||
po::options_description fMQOptionsInCmd;
|
||||
FairMQMap fFairMQMap;
|
||||
std::string fHelpTitle;
|
||||
std::string fVersion;
|
||||
|
||||
// map of read channel info - channel name - number of subchannels
|
||||
std::unordered_map<std::string, int> fChannelInfo;
|
||||
|
@ -315,31 +212,15 @@ class FairMQProgOptions : public FairProgOptions
|
|||
using MQKey = std::tuple<std::string, int, std::string>;//store key info
|
||||
std::map<std::string, MQKey> fMQKeyMap;// key=full path - val=key info
|
||||
|
||||
virtual int NotifySwitchOption(); // for custom help & version printing
|
||||
int ImmediateOptions() override; // for custom help & version printing
|
||||
void InitOptionDescription();
|
||||
|
||||
// fill boost option description with the standard options
|
||||
static void FillOptionDescription(po::options_description& options);
|
||||
|
||||
// read FairMQChannelMap and insert/update corresponding values in variable map
|
||||
// create key for variable map as follow : channelName.index.memberName
|
||||
void UpdateMQValues();
|
||||
int Store(const FairMQMap& channels);
|
||||
|
||||
private:
|
||||
/*
|
||||
// string API
|
||||
std::map<std::string, signal_type_ptr > fSignalMap;
|
||||
void EmitUpdate(const std::string& key, const char* val)
|
||||
{
|
||||
EmitUpdate(key,std::string(val));
|
||||
}
|
||||
void EmitUpdate(const std::string& key, const std::string& val)
|
||||
{
|
||||
(*fSignalMap.at(key))(key,val);
|
||||
}
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
void EmitUpdate(const std::string& key, T val)
|
||||
{
|
||||
|
|
|
@ -15,49 +15,30 @@
|
|||
#include "FairProgOptions.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
FairProgOptions::FairProgOptions() :
|
||||
fVarMap(),
|
||||
fGenericDesc("Generic options description"),
|
||||
fConfigDesc("Configuration options description"),
|
||||
fEnvironmentDesc("Environment variables"),
|
||||
fHiddenDesc("Hidden options description"),
|
||||
fCmdLineOptions("Command line options"),
|
||||
fConfigFileOptions("Configuration file options"),
|
||||
fSeverityMap(),
|
||||
fVisibleOptions("Visible options"),
|
||||
fConfigMutex(),
|
||||
fVerbosityLevel("INFO"),
|
||||
fUseConfigFile(false),
|
||||
fConfigFile()
|
||||
FairProgOptions::FairProgOptions()
|
||||
: fVarMap()
|
||||
, fGeneralDesc("General options")
|
||||
, fCmdLineOptions("Command line options")
|
||||
, fVisibleOptions("Visible options")
|
||||
, fConfigMutex()
|
||||
{
|
||||
|
||||
LOG(NOLOG) << "";// temporary hack to prevent throwing exception when accessing empty sinklist --> fixed me
|
||||
fGenericDesc.add_options()
|
||||
fGeneralDesc.add_options()
|
||||
("help,h", "produce help")
|
||||
("version,v", "print version")
|
||||
("verbosity", po::value<std::string>(&fVerbosityLevel)->default_value("DEBUG"), "Verbosity level : TRACE, DEBUG, RESULTS, INFO, WARN, ERROR, STATE, NOLOG")
|
||||
("log-color", po::value<bool>()->default_value(true), "logger color: true or false")
|
||||
("severity", po::value<string>()->default_value("debug"), "Log severity level : trace, debug, info, state, warn, error, fatal, nolog")
|
||||
("verbosity", po::value<string>()->default_value("medium"), "Log verbosity level : veryhigh, high, medium, low")
|
||||
("color", po::value<bool>()->default_value(true), "Log color (true/false)")
|
||||
("print-options", po::value<bool>()->implicit_value(true), "print options in machine-readable format (<option>:<computed-value>:<type>:<description>)");
|
||||
|
||||
fSeverityMap["TRACE"] = fair::mq::logger::SeverityLevel::TRACE;
|
||||
fSeverityMap["DEBUG"] = fair::mq::logger::SeverityLevel::DEBUG;
|
||||
fSeverityMap["RESULTS"] = fair::mq::logger::SeverityLevel::RESULTS;
|
||||
fSeverityMap["INFO"] = fair::mq::logger::SeverityLevel::INFO;
|
||||
fSeverityMap["WARN"] = fair::mq::logger::SeverityLevel::WARN;
|
||||
fSeverityMap["ERROR"] = fair::mq::logger::SeverityLevel::ERROR;
|
||||
fSeverityMap["STATE"] = fair::mq::logger::SeverityLevel::STATE;
|
||||
fSeverityMap["NOLOG"] = fair::mq::logger::SeverityLevel::NOLOG;
|
||||
}
|
||||
|
||||
/// Destructor
|
||||
FairProgOptions::~FairProgOptions()
|
||||
{
|
||||
}
|
||||
|
||||
/// //////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Add option descriptions
|
||||
int FairProgOptions::AddToCmdLineOptions(const po::options_description optDesc, bool visible)
|
||||
{
|
||||
|
@ -69,61 +50,11 @@ int FairProgOptions::AddToCmdLineOptions(const po::options_description optDesc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int FairProgOptions::AddToCfgFileOptions(const po::options_description optDesc, bool visible)
|
||||
{
|
||||
//if UseConfigFile() not yet called, then enable it with required file name to be provided by command line
|
||||
if (!fUseConfigFile)
|
||||
{
|
||||
UseConfigFile();
|
||||
}
|
||||
|
||||
fConfigFileOptions.add(optDesc);
|
||||
if (visible)
|
||||
{
|
||||
fVisibleOptions.add(optDesc);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//*
|
||||
po::options_description& FairProgOptions::GetCmdLineOptions()
|
||||
{
|
||||
return fCmdLineOptions;
|
||||
}
|
||||
|
||||
po::options_description& FairProgOptions::GetCfgFileOptions()
|
||||
{
|
||||
return fConfigFileOptions;
|
||||
}
|
||||
|
||||
po::options_description& FairProgOptions::GetEnvironmentOptions()
|
||||
{
|
||||
return fEnvironmentDesc;
|
||||
}
|
||||
|
||||
int FairProgOptions::AddToEnvironmentOptions(const po::options_description optDesc)
|
||||
{
|
||||
fEnvironmentDesc.add(optDesc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FairProgOptions::UseConfigFile(const string& filename)
|
||||
{
|
||||
fUseConfigFile = true;
|
||||
if (filename.empty())
|
||||
{
|
||||
fConfigDesc.add_options()
|
||||
("config-file", po::value<boost::filesystem::path>(&fConfigFile)->required(), "Path to configuration file (required argument)");
|
||||
AddToCmdLineOptions(fConfigDesc);
|
||||
}
|
||||
else
|
||||
{
|
||||
fConfigFile = filename;
|
||||
}
|
||||
}
|
||||
|
||||
/// //////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Parser
|
||||
|
||||
int FairProgOptions::ParseCmdLine(const int argc, char const* const* argv, const po::options_description& desc, po::variables_map& varmap, bool allowUnregistered)
|
||||
{
|
||||
// get options from cmd line and store in variable map
|
||||
|
@ -140,9 +71,9 @@ int FairProgOptions::ParseCmdLine(const int argc, char const* const* argv, const
|
|||
po::store(po::parse_command_line(argc, argv, desc), varmap);
|
||||
}
|
||||
|
||||
// call the virtual NotifySwitchOption method to handle switch options like e.g. "--help" or "--version"
|
||||
// Handles options like "--help" or "--version"
|
||||
// return 1 if switch options found in varmap
|
||||
if (NotifySwitchOption())
|
||||
if (ImmediateOptions())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
@ -156,89 +87,8 @@ int FairProgOptions::ParseCmdLine(const int argc, char const* const* argv, const
|
|||
return ParseCmdLine(argc, argv, desc, fVarMap, allowUnregistered);
|
||||
}
|
||||
|
||||
int FairProgOptions::ParseCfgFile(ifstream& ifs, const po::options_description& desc, po::variables_map& varmap, bool allowUnregistered)
|
||||
{
|
||||
if (!ifs)
|
||||
{
|
||||
LOG(ERROR) << "can not open configuration file";
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
po::store(parse_config_file(ifs, desc, allowUnregistered), varmap);
|
||||
po::notify(varmap);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FairProgOptions::ParseCfgFile(const string& filename, const po::options_description& desc, po::variables_map& varmap, bool allowUnregistered)
|
||||
{
|
||||
ifstream ifs(filename.c_str());
|
||||
if (!ifs)
|
||||
{
|
||||
LOG(ERROR) << "can not open configuration file: " << filename;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
po::store(parse_config_file(ifs, desc, allowUnregistered), varmap);
|
||||
po::notify(varmap);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FairProgOptions::ParseCfgFile(const string& filename, const po::options_description& desc, bool allowUnregistered)
|
||||
{
|
||||
return ParseCfgFile(filename,desc,fVarMap,allowUnregistered);
|
||||
}
|
||||
|
||||
int FairProgOptions::ParseCfgFile(ifstream& ifs, const po::options_description& desc, bool allowUnregistered)
|
||||
{
|
||||
return ParseCfgFile(ifs,desc,fVarMap,allowUnregistered);
|
||||
}
|
||||
|
||||
int FairProgOptions::ParseEnvironment(const function<string(string)>& environmentMapper)
|
||||
{
|
||||
po::store(po::parse_environment(fEnvironmentDesc, environmentMapper), fVarMap);
|
||||
po::notify(fVarMap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FairProgOptions::PrintHelp() const
|
||||
{
|
||||
cout << fVisibleOptions << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FairProgOptions::PrintOptionsRaw()
|
||||
{
|
||||
MapVarValInfo_t mapInfo;
|
||||
|
||||
for (const auto& m : fVarMap)
|
||||
{
|
||||
mapInfo[m.first] = GetVariableValueInfo(m.second);
|
||||
}
|
||||
|
||||
for (const auto& p : mapInfo)
|
||||
{
|
||||
string keyStr;
|
||||
string valueStr;
|
||||
string typeInfoStr;
|
||||
string defaultStr;
|
||||
string emptyStr;
|
||||
keyStr = p.first;
|
||||
tie(valueStr, typeInfoStr, defaultStr, emptyStr) = p.second;
|
||||
auto option = fCmdLineOptions.find_nothrow(keyStr, false);
|
||||
cout << keyStr << ":" << valueStr << ":" << typeInfoStr << ":" << (option ? option->description() : "<not found>") << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FairProgOptions::PrintOptions()
|
||||
{
|
||||
// //////////////////////////////////
|
||||
// Method to overload.
|
||||
// -> loop over variable map and print its content
|
||||
// -> In this example the following types are supported:
|
||||
|
@ -283,20 +133,27 @@ int FairProgOptions::PrintOptions()
|
|||
|
||||
// formatting and printing
|
||||
|
||||
LOG(DEBUG) << setfill ('*') << setw (totalLength + 3) << "*";// +3 because of string " = "
|
||||
string PrintOptionsTitle = " Configuration ";
|
||||
stringstream ss;
|
||||
ss << "\n";
|
||||
|
||||
ss << setfill('*') << setw(totalLength + 3) << "*" << "\n"; // +3 because of string " = "
|
||||
string title = " Configuration ";
|
||||
|
||||
int leftSpaceLength = 0;
|
||||
int rightSpaceLength = 0;
|
||||
int leftTitleShiftLength = 0;
|
||||
int rightTitleShiftLength = 0;
|
||||
|
||||
leftTitleShiftLength = PrintOptionsTitle.length() / 2;
|
||||
leftTitleShiftLength = title.length() / 2;
|
||||
|
||||
if ((PrintOptionsTitle.length()) % 2)
|
||||
if ((title.length()) % 2)
|
||||
{
|
||||
rightTitleShiftLength = leftTitleShiftLength + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
rightTitleShiftLength = leftTitleShiftLength;
|
||||
}
|
||||
|
||||
leftSpaceLength = (totalLength + 3) / 2 - leftTitleShiftLength;
|
||||
if ((totalLength + 3) % 2)
|
||||
|
@ -308,11 +165,11 @@ int FairProgOptions::PrintOptions()
|
|||
rightSpaceLength = (totalLength + 3) / 2 - rightTitleShiftLength;
|
||||
}
|
||||
|
||||
LOG(DEBUG) << setfill ('*') << setw(leftSpaceLength) << "*"
|
||||
<< setw(PrintOptionsTitle.length()) << PrintOptionsTitle
|
||||
<< setfill ('*') << setw(rightSpaceLength) << "*";
|
||||
ss << setfill ('*') << setw(leftSpaceLength) << "*"
|
||||
<< setw(title.length()) << title
|
||||
<< setfill ('*') << setw(rightSpaceLength) << "*" << "\n";
|
||||
|
||||
LOG(DEBUG) << setfill ('*') << setw (totalLength+3) << "*";
|
||||
ss << setfill ('*') << setw (totalLength+3) << "*" << "\n";
|
||||
|
||||
for (const auto& p : mapinfo)
|
||||
{
|
||||
|
@ -323,7 +180,7 @@ int FairProgOptions::PrintOptions()
|
|||
string emptyStr;
|
||||
keyStr = p.first;
|
||||
tie(valueStr, typeInfoStr, defaultStr, emptyStr) = p.second;
|
||||
LOG(DEBUG) << std::setfill(' ')
|
||||
ss << setfill(' ')
|
||||
<< setw(maxLength1st) << left
|
||||
<< p.first << " = "
|
||||
<< setw(maxLength2nd)
|
||||
|
@ -333,26 +190,36 @@ int FairProgOptions::PrintOptions()
|
|||
<< setw(maxLengthDefault)
|
||||
<< defaultStr
|
||||
<< 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;
|
||||
}
|
||||
|
||||
int FairProgOptions::NotifySwitchOption()
|
||||
int FairProgOptions::PrintOptionsRaw()
|
||||
{
|
||||
// Method to overload.
|
||||
if (fVarMap.count("help"))
|
||||
MapVarValInfo_t mapInfo;
|
||||
|
||||
for (const auto& m : fVarMap)
|
||||
{
|
||||
cout << "***** FAIR Program Options ***** \n" << fVisibleOptions;
|
||||
return 1;
|
||||
mapInfo[m.first] = GetVariableValueInfo(m.second);
|
||||
}
|
||||
|
||||
if (fVarMap.count("version"))
|
||||
for (const auto& p : mapInfo)
|
||||
{
|
||||
cout << "alpha version 0.0\n";
|
||||
return 1;
|
||||
string keyStr;
|
||||
string valueStr;
|
||||
string typeInfoStr;
|
||||
string defaultStr;
|
||||
string emptyStr;
|
||||
keyStr = p.first;
|
||||
tie(valueStr, typeInfoStr, defaultStr, emptyStr) = p.second;
|
||||
auto option = fCmdLineOptions.find_nothrow(keyStr, false);
|
||||
cout << keyStr << ":" << valueStr << ":" << typeInfoStr << ":" << (option ? option->description() : "<not found>") << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -16,20 +16,21 @@
|
|||
#define FAIRPROGOPTIONS_H
|
||||
|
||||
#include "FairMQLogger.h"
|
||||
#include "FairProgOptionsHelper.h"
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include "FairProgOptionsHelper.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
#include <mutex>
|
||||
#include <tuple>
|
||||
|
||||
/*
|
||||
* FairProgOptions abstract base class
|
||||
* parse command line, configuration file options as well as environment variables.
|
||||
* parse command line, configuration file options.
|
||||
*
|
||||
* The user defines in the derived class the option descriptions and
|
||||
* the pure virtual ParseAll() method
|
||||
|
@ -80,13 +81,7 @@ class FairProgOptions
|
|||
|
||||
// add options_description
|
||||
int AddToCmdLineOptions(const po::options_description optDesc, bool visible = true);
|
||||
int AddToCfgFileOptions(const po::options_description optDesc, bool visible = true);
|
||||
int AddToEnvironmentOptions(const po::options_description optDesc);
|
||||
po::options_description& GetCmdLineOptions();
|
||||
po::options_description& GetCfgFileOptions();
|
||||
po::options_description& GetEnvironmentOptions();
|
||||
|
||||
void UseConfigFile(const std::string& filename = "");
|
||||
|
||||
// get value corresponding to the key
|
||||
template<typename T>
|
||||
|
@ -108,9 +103,8 @@ class FairProgOptions
|
|||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
LOG(ERROR) << "Exception thrown for the key '" << key << "'";
|
||||
LOG(ERROR) << e.what();
|
||||
this->PrintHelp();
|
||||
LOG(error) << "Exception thrown for the key '" << key << "'";
|
||||
LOG(error) << e.what();
|
||||
}
|
||||
|
||||
return val;
|
||||
|
@ -168,44 +162,26 @@ class FairProgOptions
|
|||
int ParseCmdLine(const int argc, char const* const* argv, const po::options_description& desc, po::variables_map& varmap, bool allowUnregistered = false);
|
||||
int ParseCmdLine(const int argc, char const* const* argv, const po::options_description& desc, bool allowUnregistered = false);
|
||||
|
||||
int ParseCfgFile(const std::string& filename, const po::options_description& desc, po::variables_map& varmap, bool allowUnregistered = false);
|
||||
int ParseCfgFile(const std::string& filename, const po::options_description& desc, bool allowUnregistered = false);
|
||||
int ParseCfgFile(std::ifstream& ifs, const po::options_description& desc, po::variables_map& varmap, bool allowUnregistered = false);
|
||||
int ParseCfgFile(std::ifstream& ifs, const po::options_description& desc, bool allowUnregistered = false);
|
||||
|
||||
int ParseEnvironment(const std::function<std::string(std::string)>&);
|
||||
|
||||
virtual void ParseAll(const int argc, char const* const* argv, bool allowUnregistered = false) = 0;// TODO change return type to bool and propagate to executable
|
||||
virtual int ParseAll(const int argc, char const* const* argv, bool allowUnregistered = false) = 0;// TODO change return type to bool and propagate to executable
|
||||
|
||||
virtual int PrintOptions();
|
||||
virtual int PrintOptionsRaw();
|
||||
int PrintHelp() const;
|
||||
|
||||
protected:
|
||||
// options container
|
||||
po::variables_map fVarMap;
|
||||
|
||||
// basic description categories
|
||||
po::options_description fGenericDesc;
|
||||
po::options_description fConfigDesc;
|
||||
po::options_description fEnvironmentDesc;
|
||||
po::options_description fHiddenDesc;
|
||||
po::options_description fGeneralDesc;
|
||||
|
||||
// Description of cmd line and simple configuration file (configuration file like txt, but not like xml json ini)
|
||||
po::options_description fCmdLineOptions;
|
||||
po::options_description fConfigFileOptions;
|
||||
|
||||
// Description which is printed in help command line
|
||||
// to handle logger severity
|
||||
std::map<std::string, fair::mq::logger::SeverityLevel> fSeverityMap;
|
||||
po::options_description fVisibleOptions;
|
||||
|
||||
mutable std::mutex fConfigMutex;
|
||||
|
||||
std::string fVerbosityLevel;
|
||||
bool fUseConfigFile;
|
||||
boost::filesystem::path fConfigFile;
|
||||
virtual int NotifySwitchOption();
|
||||
virtual int ImmediateOptions() = 0;
|
||||
|
||||
// UpdateVarMap() and replace() --> helper functions to modify the value of variable map after calling po::store
|
||||
template<typename T>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
<fairMQOptions>
|
||||
<device name="merger" id="merger">
|
||||
<channel name="two_inputs_channel">
|
||||
|
@ -9,7 +8,6 @@
|
|||
<sndBufSize>1000</sndBufSize>
|
||||
<rcvBufSize>1000</rcvBufSize>
|
||||
<rateLogging>1</rateLogging>
|
||||
|
||||
</socket>
|
||||
<socket name="input2">
|
||||
<type>pull</type>
|
||||
|
@ -18,7 +16,6 @@
|
|||
<sndBufSize>1000</sndBufSize>
|
||||
<rcvBufSize>1000</rcvBufSize>
|
||||
<rateLogging>1</rateLogging>
|
||||
|
||||
</socket>
|
||||
</channel>
|
||||
<channel name="one_output_channel">
|
||||
|
@ -45,4 +42,3 @@
|
|||
</channel>
|
||||
</device>
|
||||
</fairMQOptions>
|
||||
|
||||
|
|
|
@ -10,12 +10,6 @@
|
|||
#include "FairMQParser.h"
|
||||
#include "FairMQProgOptions.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// tests
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// Parse xml from file
|
||||
int testXML1(FairMQProgOptions* config)
|
||||
{
|
||||
|
@ -35,7 +29,6 @@ int testXML1(FairMQProgOptions* config)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Parse xml from command line
|
||||
int testXML2(FairMQProgOptions* config)
|
||||
{
|
||||
|
@ -93,10 +86,6 @@ int testJSON2(FairMQProgOptions* config)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
/// main
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
FairMQProgOptions* config= new FairMQProgOptions();
|
||||
|
@ -112,27 +101,35 @@ int main(int argc, char** argv)
|
|||
|
||||
// Parse command line
|
||||
if (config->ParseAll(argc,argv))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set severity level (Default is 0=DEBUG)
|
||||
int verbosity = config->GetValue<int>("verbosity");
|
||||
FairMQLogger::Level lvl=static_cast<FairMQLogger::Level>(verbosity);
|
||||
int severity = config->GetValue<int>("severity");
|
||||
FairMQLogger::Level lvl=static_cast<FairMQLogger::Level>(severity);
|
||||
SET_LOGGER_LEVEL(lvl);
|
||||
|
||||
|
||||
// Parse xml or json from cmd line or file
|
||||
|
||||
if (config->GetVarMap().count("config-xml-file"))
|
||||
{
|
||||
testXML1(config);
|
||||
}
|
||||
|
||||
if (config->GetVarMap().count("config-xml-string"))
|
||||
{
|
||||
testXML2(config);
|
||||
}
|
||||
|
||||
if (config->GetVarMap().count("config-json-file"))
|
||||
{
|
||||
testJSON1(config);
|
||||
}
|
||||
|
||||
if (config->GetVarMap().count("config-json-string"))
|
||||
{
|
||||
testJSON2(config);
|
||||
}
|
||||
|
||||
}
|
||||
catch (std::exception& e)
|
||||
|
@ -142,9 +139,3 @@ int main(int argc, char** argv)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
FairMQProgOptions config;
|
||||
|
@ -39,7 +38,6 @@ int main(int argc, char** argv)
|
|||
config.AddToCmdLineOptions(format_desc,true);
|
||||
config.AddToCmdLineOptions(io_file_opt_desc,true);
|
||||
|
||||
|
||||
config.EnableCfgFile();// UseConfigFile (by default config file is not defined)
|
||||
config.AddToCfgFileOptions(format_desc,false);//false because already added to visible
|
||||
config.AddToCfgFileOptions(io_file_opt_desc,false);
|
||||
|
@ -49,8 +47,8 @@ int main(int argc, char** argv)
|
|||
return 0;
|
||||
|
||||
// Set severity level (Default is 0=DEBUG)
|
||||
int verbosity=config.GetValue<int>("verbosity");
|
||||
FairMQLogger::Level lvl=static_cast<FairMQLogger::Level>(verbosity);
|
||||
int severity = config.GetValue<int>("severity");
|
||||
FairMQLogger::Level lvl = static_cast<FairMQLogger::Level>(severity);
|
||||
SET_LOGGER_LEVEL(lvl);
|
||||
|
||||
// parse XML file
|
||||
|
@ -61,8 +59,6 @@ int main(int argc, char** argv)
|
|||
XMLrootNode=config.GetValue<std::string>("xml.config.node.root");
|
||||
std::string id=config.GetValue<std::string>("id");
|
||||
config.UserParser<FairMQParser::XML>(filename,id,XMLrootNode);
|
||||
|
||||
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
|
@ -71,9 +67,3 @@ int main(int argc, char** argv)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -6,6 +6,6 @@ VERBOSE="DEBUG"
|
|||
JSONCONFIGFILE="@CMAKE_BINARY_DIR@/bin/config/ex1-sampler-sink.json"
|
||||
|
||||
########################## start DEVICE
|
||||
DEVICE="runConfigExample --transport $TRANSPORT --verbosity $VERBOSE"
|
||||
DEVICE="runConfigExample --transport $TRANSPORT --severity $VERBOSE"
|
||||
DEVICE+=" --id sampler1 --mq-config $JSONCONFIGFILE"
|
||||
@CMAKE_BINARY_DIR@/bin/$DEVICE
|
||||
|
|
|
@ -127,43 +127,43 @@ auto Control::InteractiveMode() -> void
|
|||
switch (input)
|
||||
{
|
||||
case 'i':
|
||||
LOG(INFO) << "[i] init device";
|
||||
LOG(INFO) << "\n\n --> [i] init device\n";
|
||||
ChangeDeviceState(DeviceStateTransition::InitDevice);
|
||||
break;
|
||||
case 'j':
|
||||
LOG(INFO) << "[j] init task";
|
||||
LOG(INFO) << "\n\n --> [j] init task\n";
|
||||
ChangeDeviceState(DeviceStateTransition::InitTask);
|
||||
break;
|
||||
case 'p':
|
||||
LOG(INFO) << "[p] pause";
|
||||
LOG(INFO) << "\n\n --> [p] pause\n";
|
||||
ChangeDeviceState(DeviceStateTransition::Pause);
|
||||
break;
|
||||
case 'r':
|
||||
LOG(INFO) << "[r] run";
|
||||
LOG(INFO) << "\n\n --> [r] run\n";
|
||||
ChangeDeviceState(DeviceStateTransition::Run);
|
||||
break;
|
||||
case 's':
|
||||
LOG(INFO) << "[s] stop";
|
||||
LOG(INFO) << "\n\n --> [s] stop\n";
|
||||
ChangeDeviceState(DeviceStateTransition::Stop);
|
||||
break;
|
||||
case 't':
|
||||
LOG(INFO) << "[t] reset task";
|
||||
LOG(INFO) << "\n\n --> [t] reset task\n";
|
||||
ChangeDeviceState(DeviceStateTransition::ResetTask);
|
||||
break;
|
||||
case 'd':
|
||||
LOG(INFO) << "[d] reset device";
|
||||
LOG(INFO) << "\n\n --> [d] reset device\n";
|
||||
ChangeDeviceState(DeviceStateTransition::ResetDevice);
|
||||
break;
|
||||
case 'h':
|
||||
LOG(INFO) << "[h] help";
|
||||
LOG(INFO) << "\n\n --> [h] help\n";
|
||||
PrintInteractiveHelp();
|
||||
break;
|
||||
// case 'x':
|
||||
// LOG(INFO) << "[x] ERROR";
|
||||
// LOG(INFO) << "\n\n --> [x] ERROR\n";
|
||||
// ChangeDeviceState(DeviceStateTransition::ERROR_FOUND);
|
||||
// break;
|
||||
case 'q':
|
||||
LOG(INFO) << "[q] end";
|
||||
LOG(INFO) << "\n\n --> [q] end\n";
|
||||
keepRunning = false;
|
||||
break;
|
||||
default:
|
||||
|
@ -197,8 +197,8 @@ auto Control::InteractiveMode() -> void
|
|||
|
||||
auto Control::PrintInteractiveHelp() -> void
|
||||
{
|
||||
LOG(INFO) << "Use keys to control the state machine:";
|
||||
LOG(INFO) << "[h] help, [p] pause, [r] run, [s] stop, [t] reset task, [d] reset device, [q] end, [j] init task, [i] init device";
|
||||
LOG(INFO) << "Use keys to control the state machine:\n\n"
|
||||
<< "[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
|
||||
|
|
|
@ -65,6 +65,7 @@ SAMPLER+=" --id bsampler1"
|
|||
#SAMPLER+=" --io-threads 2"
|
||||
#SAMPLER+=" --control static"
|
||||
SAMPLER+=" --transport $transport"
|
||||
SAMPLER+=" --severity debug"
|
||||
SAMPLER+=" --msg-size $msgSize"
|
||||
SAMPLER+=" --same-msg $sameMsg"
|
||||
# SAMPLER+=" --msg-rate 1000"
|
||||
|
@ -80,6 +81,7 @@ SINK+=" --id sink1"
|
|||
#SINK+=" --io-threads 2"
|
||||
#SINK+=" --control static"
|
||||
SINK+=" --transport $transport"
|
||||
SINK+=" --severity debug"
|
||||
SINK+=" --max-iterations $maxIterations"
|
||||
SINK+=" --mq-config @CMAKE_BINARY_DIR@/bin/config/benchmark.json"
|
||||
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+=" --id sampler1"
|
||||
SAMPLER+=" --transport $transport"
|
||||
# SAMPLER+=" --verbosity TRACE"
|
||||
# SAMPLER+=" --severity TRACE"
|
||||
SAMPLER+=" --msg-size $msgSize"
|
||||
# SAMPLER+=" --msg-rate 1000"
|
||||
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+=" --id sink1"
|
||||
SINK1+=" --transport $transport"
|
||||
# SINK1+=" --verbose TRACE"
|
||||
# SINK1+=" --severity TRACE"
|
||||
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 &
|
||||
|
||||
# SINK2="shm-prototype-sink"
|
||||
# SINK2+=" --id sink2"
|
||||
# SINK2+=" --transport $transport"
|
||||
# # SINK2+=" --verbose TRACE"
|
||||
# # SINK2+=" --severity TRACE"
|
||||
# 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 &
|
||||
|
||||
# SINK3="shm-prototype-sink"
|
||||
# SINK3+=" --id sink3"
|
||||
# SINK3+=" --transport $transport"
|
||||
# # SINK3+=" --verbose TRACE"
|
||||
# # SINK3+=" --severity TRACE"
|
||||
# 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 &
|
||||
|
||||
# SINK4="shm-prototype-sink"
|
||||
# SINK4+=" --id sink4"
|
||||
# SINK4+=" --transport $transport"
|
||||
# # SINK4+=" --verbose TRACE"
|
||||
# # SINK4+=" --severity TRACE"
|
||||
# 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 &
|
||||
|
|
|
@ -27,7 +27,7 @@ auto RunPoller(string transport, int pollType) -> void
|
|||
stringstream cmd;
|
||||
cmd << runTestDevice
|
||||
<< " --id pollout_"<< transport
|
||||
<< " --control static --verbosity DEBUG --log-color false"
|
||||
<< " --control static --severity DEBUG --color false"
|
||||
<< " --session " << session << " --mq-config \"" << mqConfig << "\"";
|
||||
pollout = execute(cmd.str(), "[POLLOUT]");
|
||||
});
|
||||
|
@ -37,7 +37,7 @@ auto RunPoller(string transport, int pollType) -> void
|
|||
stringstream cmd;
|
||||
cmd << runTestDevice
|
||||
<< " --id pollin_" << transport
|
||||
<< " --control static --verbosity DEBUG --log-color false"
|
||||
<< " --control static --severity DEBUG --color false"
|
||||
<< " --session " << session << " --mq-config \"" << mqConfig << "\" --poll-type " << pollType;
|
||||
pollin = execute(cmd.str(), "[POLLIN]");
|
||||
});
|
||||
|
|
|
@ -25,24 +25,24 @@ auto RunPubSub(string transport) -> void
|
|||
auto pub = execute_result{"", 0};
|
||||
thread pub_thread([&]() {
|
||||
stringstream cmd;
|
||||
cmd << runTestDevice << " --id pub_" << transport << " --control static --verbosity DEBUG "
|
||||
<< "--session " << session << " --log-color false --mq-config \"" << mqConfig << "\"";
|
||||
cmd << runTestDevice << " --id pub_" << transport << " --control static --severity DEBUG "
|
||||
<< "--session " << session << " --color false --mq-config \"" << mqConfig << "\"";
|
||||
pub = execute(cmd.str(), "[PUB]");
|
||||
});
|
||||
|
||||
auto sub1 = execute_result{"", 0};
|
||||
thread sub1_thread([&]() {
|
||||
stringstream cmd;
|
||||
cmd << runTestDevice << " --id sub_1" << transport << " --control static --verbosity DEBUG "
|
||||
<< "--session " << session << " --log-color false --mq-config \"" << mqConfig << "\"";
|
||||
cmd << runTestDevice << " --id sub_1" << transport << " --control static --severity DEBUG "
|
||||
<< "--session " << session << " --color false --mq-config \"" << mqConfig << "\"";
|
||||
sub1 = execute(cmd.str(), "[SUB1]");
|
||||
});
|
||||
|
||||
auto sub2 = execute_result{"", 0};
|
||||
thread sub2_thread([&]() {
|
||||
stringstream cmd;
|
||||
cmd << runTestDevice << " --id sub_2" << transport << " --control static --verbosity DEBUG "
|
||||
<< "--session " << session << " --log-color false --mq-config \"" << mqConfig << "\"";
|
||||
cmd << runTestDevice << " --id sub_2" << transport << " --control static --severity DEBUG "
|
||||
<< "--session " << session << " --color false --mq-config \"" << mqConfig << "\"";
|
||||
sub2 = execute(cmd.str(), "[SUB2]");
|
||||
});
|
||||
|
||||
|
|
|
@ -25,16 +25,16 @@ auto RunPushPull(string transport) -> void
|
|||
auto push = execute_result{"", 100};
|
||||
thread push_thread([&]() {
|
||||
stringstream cmd;
|
||||
cmd << runTestDevice << " --id push_" << transport << " --control static --verbosity DEBUG "
|
||||
<< "--session " << session << " --log-color false --mq-config \"" << mqConfig << "\"";
|
||||
cmd << runTestDevice << " --id push_" << transport << " --control static --severity DEBUG "
|
||||
<< "--session " << session << " --color false --mq-config \"" << mqConfig << "\"";
|
||||
push = execute(cmd.str(), "[PUSH]");
|
||||
});
|
||||
|
||||
auto pull = execute_result{"", 100};
|
||||
thread pull_thread([&]() {
|
||||
stringstream cmd;
|
||||
cmd << runTestDevice << " --id pull_" << transport << " --control static --verbosity DEBUG "
|
||||
<< "--session " << session << " --log-color false --mq-config \"" << mqConfig << "\"";
|
||||
cmd << runTestDevice << " --id pull_" << transport << " --control static --severity DEBUG "
|
||||
<< "--session " << session << " --color false --mq-config \"" << mqConfig << "\"";
|
||||
pull = execute(cmd.str(), "[PULL]");
|
||||
});
|
||||
|
||||
|
|
|
@ -25,24 +25,24 @@ auto RunReqRep(string transport) -> void
|
|||
auto rep = execute_result{ "", 0 };
|
||||
thread rep_thread([&]() {
|
||||
stringstream cmd;
|
||||
cmd << runTestDevice << " --id rep_" << transport << " --control static --verbosity DEBUG "
|
||||
<< "--session " << session << " --log-color false --mq-config \"" << mqConfig << "\"";
|
||||
cmd << runTestDevice << " --id rep_" << transport << " --control static --severity DEBUG "
|
||||
<< "--session " << session << " --color false --mq-config \"" << mqConfig << "\"";
|
||||
rep = execute(cmd.str(), "[REP]");
|
||||
});
|
||||
|
||||
auto req1 = execute_result{ "", 0 };
|
||||
thread req1_thread([&]() {
|
||||
stringstream cmd;
|
||||
cmd << runTestDevice << " --id req_1" << transport << " --control static --verbosity DEBUG "
|
||||
<< "--session " << session << " --log-color false --mq-config \"" << mqConfig << "\"";
|
||||
cmd << runTestDevice << " --id req_1" << transport << " --control static --severity DEBUG "
|
||||
<< "--session " << session << " --color false --mq-config \"" << mqConfig << "\"";
|
||||
req1 = execute(cmd.str(), "[REQ1]");
|
||||
});
|
||||
|
||||
auto req2 = execute_result{ "", 0 };
|
||||
thread req2_thread([&]() {
|
||||
stringstream cmd;
|
||||
cmd << runTestDevice << " --id req_2" << transport << " --control static --verbosity DEBUG "
|
||||
<< "--session " << session << " --log-color false --mq-config \"" << mqConfig << "\"";
|
||||
cmd << runTestDevice << " --id req_2" << transport << " --control static --severity DEBUG "
|
||||
<< "--session " << session << " --color false --mq-config \"" << mqConfig << "\"";
|
||||
req2 = execute(cmd.str(), "[REQ2]");
|
||||
});
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@ auto RunTransferTimeout(string transport) -> void
|
|||
{
|
||||
size_t session{fair::mq::tools::UuidHash()};
|
||||
stringstream cmd;
|
||||
cmd << runTestDevice << " --id transfer_timeout_" << transport << " --control static --verbosity DEBUG "
|
||||
<< "--session " << session << " --log-color false --mq-config \"" << mqConfig << "\"";
|
||||
cmd << runTestDevice << " --id transfer_timeout_" << transport << " --control static --severity DEBUG "
|
||||
<< "--session " << session << " --color false --mq-config \"" << mqConfig << "\"";
|
||||
auto res = execute(cmd.str());
|
||||
|
||||
cerr << res.error_out;
|
||||
|
|
|
@ -40,7 +40,7 @@ auto execute(string cmd, string log_prefix) -> execute_result
|
|||
out << log_prefix << cmd << endl;
|
||||
|
||||
// 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{};
|
||||
while (getline(in, line))
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user