diff --git a/features/options/contract/help.feature b/features/options/contract/help.feature index bfd0a9109..d33a2c65b 100644 --- a/features/options/contract/help.feature +++ b/features/options/contract/help.feature @@ -8,6 +8,7 @@ Feature: osrm-contract command line options: help And stdout should contain "Options:" And stdout should contain "--version" And stdout should contain "--help" + And stdout should contain "--verbosity" And stdout should contain "Configuration:" And stdout should contain "--threads" And stdout should contain "--core" @@ -22,6 +23,7 @@ Feature: osrm-contract command line options: help And stdout should contain "Options:" And stdout should contain "--version" And stdout should contain "--help" + And stdout should contain "--verbosity" And stdout should contain "Configuration:" And stdout should contain "--threads" And stdout should contain "--core" @@ -36,6 +38,7 @@ Feature: osrm-contract command line options: help And stdout should contain "Options:" And stdout should contain "--version" And stdout should contain "--help" + And stdout should contain "--verbosity" And stdout should contain "Configuration:" And stdout should contain "--threads" And stdout should contain "--core" diff --git a/features/options/customize/help.feature b/features/options/customize/help.feature index 504a5199d..02a69e4ce 100644 --- a/features/options/customize/help.feature +++ b/features/options/customize/help.feature @@ -8,6 +8,7 @@ Feature: osrm-customize command line options: help And stdout should contain "Options:" And stdout should contain "--version" And stdout should contain "--help" + And stdout should contain "--verbosity" And stdout should contain "Configuration:" And stdout should contain "--threads" And it should exit with an error @@ -19,6 +20,7 @@ Feature: osrm-customize command line options: help And stdout should contain "Options:" And stdout should contain "--version" And stdout should contain "--help" + And stdout should contain "--verbosity" And stdout should contain "Configuration:" And stdout should contain "--threads" And it should exit successfully @@ -30,6 +32,7 @@ Feature: osrm-customize command line options: help And stdout should contain "Options:" And stdout should contain "--version" And stdout should contain "--help" + And stdout should contain "--verbosity" And stdout should contain "Configuration:" And stdout should contain "--threads" And it should exit successfully diff --git a/features/options/extract/help.feature b/features/options/extract/help.feature index 072c33f57..3d86115e5 100644 --- a/features/options/extract/help.feature +++ b/features/options/extract/help.feature @@ -11,6 +11,7 @@ Feature: osrm-extract command line options: help And stdout should contain "Options:" And stdout should contain "--version" And stdout should contain "--help" + And stdout should contain "--verbosity" And stdout should contain "Configuration:" And stdout should contain "--profile" And stdout should contain "--threads" @@ -24,6 +25,7 @@ Feature: osrm-extract command line options: help And stdout should contain "Options:" And stdout should contain "--version" And stdout should contain "--help" + And stdout should contain "--verbosity" And stdout should contain "Configuration:" And stdout should contain "--profile" And stdout should contain "--threads" @@ -37,6 +39,7 @@ Feature: osrm-extract command line options: help And stdout should contain "Options:" And stdout should contain "--version" And stdout should contain "--help" + And stdout should contain "--verbosity" And stdout should contain "Configuration:" And stdout should contain "--profile" And stdout should contain "--threads" diff --git a/features/options/partition/help.feature b/features/options/partition/help.feature index 90bea6e88..08fb84c35 100644 --- a/features/options/partition/help.feature +++ b/features/options/partition/help.feature @@ -8,6 +8,7 @@ Feature: osrm-partition command line options: help And stdout should contain "Options:" And stdout should contain "--version" And stdout should contain "--help" + And stdout should contain "--verbosity" And stdout should contain "Configuration:" And stdout should contain "--threads" And stdout should contain "--balance" @@ -24,6 +25,7 @@ Feature: osrm-partition command line options: help And stdout should contain "Options:" And stdout should contain "--version" And stdout should contain "--help" + And stdout should contain "--verbosity" And stdout should contain "Configuration:" And stdout should contain "--threads" And stdout should contain "--balance" @@ -40,6 +42,7 @@ Feature: osrm-partition command line options: help And stdout should contain "Options:" And stdout should contain "--version" And stdout should contain "--help" + And stdout should contain "--verbosity" And stdout should contain "Configuration:" And stdout should contain "--threads" And stdout should contain "--balance" diff --git a/features/options/routed/help.feature b/features/options/routed/help.feature index 35dc7d97c..a581be3fe 100644 --- a/features/options/routed/help.feature +++ b/features/options/routed/help.feature @@ -11,6 +11,7 @@ Feature: osrm-routed command line options: help And stdout should contain "Options:" And stdout should contain "--version" And stdout should contain "--help" + And stdout should contain "--verbosity" And stdout should contain "--trial" And stdout should contain "Configuration:" And stdout should contain "--ip" @@ -30,6 +31,7 @@ Feature: osrm-routed command line options: help And stdout should contain "Options:" And stdout should contain "--version" And stdout should contain "--help" + And stdout should contain "--verbosity" And stdout should contain "--trial" And stdout should contain "Configuration:" And stdout should contain "--ip" @@ -49,6 +51,7 @@ Feature: osrm-routed command line options: help And stdout should contain "Options:" And stdout should contain "--version" And stdout should contain "--help" + And stdout should contain "--verbosity" And stdout should contain "--trial" And stdout should contain "Configuration:" And stdout should contain "--ip" diff --git a/include/util/log.hpp b/include/util/log.hpp index dc08e929c..42cb23978 100644 --- a/include/util/log.hpp +++ b/include/util/log.hpp @@ -7,9 +7,10 @@ enum LogLevel { - logINFO, - logWARNING, + logNONE, logERROR, + logWARNING, + logINFO, logDEBUG }; @@ -27,14 +28,20 @@ class LogPolicy bool IsMute() const; + LogLevel GetLevel() const; + void SetLevel(LogLevel level); + void SetLevel(std::string const &level); + static LogPolicy &GetInstance(); + static std::string GetLevels(); LogPolicy(const LogPolicy &) = delete; LogPolicy &operator=(const LogPolicy &) = delete; private: - LogPolicy() : m_is_mute(true) {} + LogPolicy() : m_is_mute(true), m_level(logINFO) {} std::atomic m_is_mute; + LogLevel m_level; }; class Log diff --git a/src/tools/contract.cpp b/src/tools/contract.cpp index 8a6627cb5..ee64b12fc 100644 --- a/src/tools/contract.cpp +++ b/src/tools/contract.cpp @@ -28,11 +28,17 @@ enum class return_code : unsigned exit }; -return_code parseArguments(int argc, char *argv[], contractor::ContractorConfig &contractor_config) +return_code parseArguments(int argc, + char *argv[], + std::string &verbosity, + contractor::ContractorConfig &contractor_config) { // declare a group of options that will be allowed only on command line boost::program_options::options_description generic_options("Options"); - generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message"); + generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")( + "verbosity,l", + boost::program_options::value(&verbosity)->default_value("INFO"), + std::string("Log verbosity level: " + util::LogPolicy::GetLevels()).c_str()); // declare a group of options that will be allowed on command line boost::program_options::options_description config_options("Configuration"); @@ -137,11 +143,11 @@ return_code parseArguments(int argc, char *argv[], contractor::ContractorConfig int main(int argc, char *argv[]) try { - util::LogPolicy::GetInstance().Unmute(); + std::string verbosity; contractor::ContractorConfig contractor_config; - const return_code result = parseArguments(argc, argv, contractor_config); + const return_code result = parseArguments(argc, argv, verbosity, contractor_config); if (return_code::fail == result) { @@ -153,6 +159,8 @@ int main(int argc, char *argv[]) try return EXIT_SUCCESS; } + util::LogPolicy::GetInstance().SetLevel(verbosity); + contractor_config.UseDefaultOutputNames(contractor_config.base_path); if (1 > contractor_config.requested_num_threads) diff --git a/src/tools/customize.cpp b/src/tools/customize.cpp index 239a559e0..d074d2166 100644 --- a/src/tools/customize.cpp +++ b/src/tools/customize.cpp @@ -21,12 +21,17 @@ enum class return_code : unsigned exit }; -return_code -parseArguments(int argc, char *argv[], customizer::CustomizationConfig &customization_config) +return_code parseArguments(int argc, + char *argv[], + std::string &verbosity, + customizer::CustomizationConfig &customization_config) { // declare a group of options that will be allowed only on command line boost::program_options::options_description generic_options("Options"); - generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message"); + generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")( + "verbosity,l", + boost::program_options::value(&verbosity)->default_value("INFO"), + std::string("Log verbosity level: " + util::LogPolicy::GetLevels()).c_str()); // declare a group of options that will be allowed both on command line boost::program_options::options_description config_options("Configuration"); @@ -130,9 +135,10 @@ parseArguments(int argc, char *argv[], customizer::CustomizationConfig &customiz int main(int argc, char *argv[]) try { util::LogPolicy::GetInstance().Unmute(); + std::string verbosity; customizer::CustomizationConfig customization_config; - const auto result = parseArguments(argc, argv, customization_config); + const auto result = parseArguments(argc, argv, verbosity, customization_config); if (return_code::fail == result) { @@ -144,6 +150,8 @@ int main(int argc, char *argv[]) try return EXIT_SUCCESS; } + util::LogPolicy::GetInstance().SetLevel(verbosity); + // set the default in/output names customization_config.UseDefaultOutputNames(customization_config.base_path); diff --git a/src/tools/extract.cpp b/src/tools/extract.cpp index 3ccc2717e..33c3b06c3 100644 --- a/src/tools/extract.cpp +++ b/src/tools/extract.cpp @@ -24,11 +24,17 @@ enum class return_code : unsigned exit }; -return_code parseArguments(int argc, char *argv[], extractor::ExtractorConfig &extractor_config) +return_code parseArguments(int argc, + char *argv[], + std::string &verbosity, + extractor::ExtractorConfig &extractor_config) { - // declare a group of options that will be allowed only on command line + // declare a group of options that will be a llowed only on command line boost::program_options::options_description generic_options("Options"); - generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message"); + generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")( + "verbosity,l", + boost::program_options::value(&verbosity)->default_value("INFO"), + std::string("Log verbosity level: " + util::LogPolicy::GetLevels()).c_str()); // declare a group of options that will be allowed both on command line boost::program_options::options_description config_options("Configuration"); @@ -127,8 +133,9 @@ int main(int argc, char *argv[]) try { util::LogPolicy::GetInstance().Unmute(); extractor::ExtractorConfig extractor_config; + std::string verbosity; - const auto result = parseArguments(argc, argv, extractor_config); + const auto result = parseArguments(argc, argv, verbosity, extractor_config); if (return_code::fail == result) { @@ -140,6 +147,8 @@ int main(int argc, char *argv[]) try return EXIT_SUCCESS; } + util::LogPolicy::GetInstance().SetLevel(verbosity); + extractor_config.UseDefaultOutputNames(extractor_config.input_path); if (1 > extractor_config.requested_num_threads) diff --git a/src/tools/partition.cpp b/src/tools/partition.cpp index 25a88e5d1..155f3a1e0 100644 --- a/src/tools/partition.cpp +++ b/src/tools/partition.cpp @@ -69,11 +69,15 @@ void validate(boost::any &v, const std::vector &values, MaxCellSize v = boost::any(MaxCellSizesArgument{output}); } -return_code parseArguments(int argc, char *argv[], partition::PartitionConfig &config) +return_code +parseArguments(int argc, char *argv[], std::string &verbosity, partition::PartitionConfig &config) { // declare a group of options that will be allowed only on command line boost::program_options::options_description generic_options("Options"); - generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message"); + generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")( + "verbosity,l", + boost::program_options::value(&verbosity)->default_value("INFO"), + std::string("Log verbosity level: " + util::LogPolicy::GetLevels()).c_str()); // declare a group of options that will be allowed both on command line boost::program_options::options_description config_options("Configuration"); @@ -184,9 +188,10 @@ return_code parseArguments(int argc, char *argv[], partition::PartitionConfig &c int main(int argc, char *argv[]) try { util::LogPolicy::GetInstance().Unmute(); + std::string verbosity; partition::PartitionConfig partition_config; - const auto result = parseArguments(argc, argv, partition_config); + const auto result = parseArguments(argc, argv, verbosity, partition_config); if (return_code::fail == result) { @@ -198,6 +203,8 @@ int main(int argc, char *argv[]) try return EXIT_SUCCESS; } + util::LogPolicy::GetInstance().SetLevel(verbosity); + // set the default in/output names partition_config.UseDefaultOutputNames(partition_config.base_path); diff --git a/src/tools/routed.cpp b/src/tools/routed.cpp index 92b01db1b..96b7ead2d 100644 --- a/src/tools/routed.cpp +++ b/src/tools/routed.cpp @@ -68,6 +68,7 @@ static EngineConfig::Algorithm stringToAlgorithm(std::string algorithm) // generate boost::program_options object for the routing part inline unsigned generateServerProgramOptions(const int argc, const char *argv[], + std::string verbosity, boost::filesystem::path &base_path, std::string &ip_address, int &ip_port, @@ -87,9 +88,12 @@ inline unsigned generateServerProgramOptions(const int argc, // declare a group of options that will be allowed only on command line boost::program_options::options_description generic_options("Options"); - generic_options.add_options() // - ("version,v", "Show version")("help,h", "Show this help message") // - ("trial", value(&trial)->implicit_value(true), "Quit after initialization"); + generic_options.add_options() // + ("version,v", "Show version")("help,h", "Show this help message")( + "verbosity,l", + boost::program_options::value(&verbosity)->default_value("INFO"), + std::string("Log verbosity level: " + util::LogPolicy::GetLevels()).c_str())( + "trial", value(&trial)->implicit_value(true), "Quit after initialization"); // declare a group of options that will be allowed on command line boost::program_options::options_description config_options("Configuration"); @@ -202,10 +206,12 @@ int main(int argc, const char *argv[]) try int ip_port, requested_thread_num; EngineConfig config; + std::string verbosity; boost::filesystem::path base_path; std::string algorithm; const unsigned init_result = generateServerProgramOptions(argc, argv, + verbosity, base_path, ip_address, ip_port, @@ -227,6 +233,9 @@ int main(int argc, const char *argv[]) try { return EXIT_FAILURE; } + + util::LogPolicy::GetInstance().SetLevel(verbosity); + if (!base_path.empty()) { config.storage_config = storage::StorageConfig(base_path); diff --git a/src/tools/store.cpp b/src/tools/store.cpp index d6e639d2d..e32f89d70 100644 --- a/src/tools/store.cpp +++ b/src/tools/store.cpp @@ -52,12 +52,16 @@ void springClean() // generate boost::program_options object for the routing part bool generateDataStoreOptions(const int argc, const char *argv[], + std::string &verbosity, boost::filesystem::path &base_path, int &max_wait) { // declare a group of options that will be allowed only on command line boost::program_options::options_description generic_options("Options"); generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")( + "verbosity,l", + boost::program_options::value(&verbosity)->default_value("INFO"), + std::string("Log verbosity level: " + util::LogPolicy::GetLevels()).c_str())( "remove-locks,r", "Remove locks")("spring-clean,s", "Spring-cleaning all shared memory regions"); @@ -157,12 +161,16 @@ int main(const int argc, const char *argv[]) try util::LogPolicy::GetInstance().Unmute(); + std::string verbosity; boost::filesystem::path base_path; int max_wait = -1; - if (!generateDataStoreOptions(argc, argv, base_path, max_wait)) + if (!generateDataStoreOptions(argc, argv, verbosity, base_path, max_wait)) { return EXIT_SUCCESS; } + + util::LogPolicy::GetInstance().SetLevel(verbosity); + storage::StorageConfig config(base_path); if (!config.IsValid()) { diff --git a/src/util/log.cpp b/src/util/log.cpp index 4b28c4c2f..1c17f2bc7 100644 --- a/src/util/log.cpp +++ b/src/util/log.cpp @@ -1,5 +1,6 @@ #include "util/log.hpp" #include "util/isatty.hpp" +#include #include #include #include @@ -29,32 +30,64 @@ void LogPolicy::Mute() { m_is_mute = true; } bool LogPolicy::IsMute() const { return m_is_mute; } +LogLevel LogPolicy::GetLevel() const { return m_level; } + +void LogPolicy::SetLevel(LogLevel level) { m_level = level; } + +void LogPolicy::SetLevel(std::string const &level) +{ + // Keep in sync with LogLevel definition + if (boost::iequals(level, "NONE")) + m_level = logNONE; + else if (boost::iequals(level, "ERROR")) + m_level = logERROR; + else if (boost::iequals(level, "WARNING")) + m_level = logWARNING; + else if (boost::iequals(level, "INFO")) + m_level = logINFO; + else if (boost::iequals(level, "DEBUG")) + m_level = logDEBUG; + else + ; +} + LogPolicy &LogPolicy::GetInstance() { static LogPolicy runningInstance; return runningInstance; } +std::string LogPolicy::GetLevels() +{ + // Keep in sync with LogLevel definition + return "NONE, ERROR, WARNING, INFO, DEBUG"; +} + Log::Log(LogLevel level_, std::ostream &ostream) : level(level_), stream(ostream) { - const bool is_terminal = IsStdoutATTY(); std::lock_guard lock(get_mutex()); - switch (level) + if (!LogPolicy::GetInstance().IsMute() && level <= LogPolicy::GetInstance().GetLevel()) { - case logWARNING: - stream << (is_terminal ? YELLOW : "") << "[warn] "; - break; - case logERROR: - stream << (is_terminal ? RED : "") << "[error] "; - break; - case logDEBUG: + const bool is_terminal = IsStdoutATTY(); + switch (level) + { + case logNONE: + break; + case logWARNING: + stream << (is_terminal ? YELLOW : "") << "[warn] "; + break; + case logERROR: + stream << (is_terminal ? RED : "") << "[error] "; + break; + case logDEBUG: #ifndef NDEBUG - stream << (is_terminal ? MAGENTA : "") << "[debug] "; + stream << (is_terminal ? MAGENTA : "") << "[debug] "; #endif - break; - default: // logINFO: - stream << "[info] "; - break; + break; + default: // logINFO: + stream << "[info] "; + break; + } } } @@ -76,14 +109,16 @@ std::mutex &Log::get_mutex() Log::~Log() { std::lock_guard lock(get_mutex()); - const bool usestd = (&stream == &buffer); - if (!LogPolicy::GetInstance().IsMute()) + if (!LogPolicy::GetInstance().IsMute() && level <= LogPolicy::GetInstance().GetLevel()) { + const bool usestd = (&stream == &buffer); const bool is_terminal = IsStdoutATTY(); if (usestd) { switch (level) { + case logNONE: + break; case logWARNING: case logERROR: std::cerr << buffer.str();