From 253a379813ea72e0e41a58c4f4761b5a9fdaaeb2 Mon Sep 17 00:00:00 2001 From: Aregtech <49253642+aregtech@users.noreply.github.com> Date: Sun, 20 Oct 2024 01:30:26 +0200 Subject: [PATCH] An option to load config file from command line (#401) * Added an option to load config file in command line. This give flexibility to load config file in any location, not just the hardcoded file path. --- .github/workflows/cmake.yml | 2 +- framework/aregextend/console/OptionParser.hpp | 12 +++- .../console/private/OptionParser.cpp | 17 +++++- .../aregextend/service/NESystemService.hpp | 59 +++++++++++-------- .../service/ServiceApplicationBase.hpp | 5 +- .../aregextend/service/SystemServiceBase.hpp | 4 ++ .../private/ServiceApplicationBase.cpp | 4 +- .../service/private/SystemServiceBase.cpp | 50 +++++++++++++--- framework/areglogger.vcxproj | 5 +- framework/areglogger.vcxproj.filters | 10 ++-- .../client/private/LogObserverApi.cpp | 6 +- framework/logger/app/Logger.hpp | 35 +++++------ framework/logger/app/private/Logger.cpp | 10 +++- framework/logobserver/app/LogObserver.hpp | 44 ++++++++------ .../logobserver/app/private/LogObserver.cpp | 40 +++++++++---- framework/mcrouter/app/MulticastRouter.hpp | 28 +++++---- .../mcrouter/app/private/MulticastRouter.cpp | 14 +++-- 17 files changed, 227 insertions(+), 118 deletions(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 0d710c5d..158e35fb 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -405,7 +405,7 @@ jobs: run: | mkdir ./${{matrix.config.name}}/ cp -R ./${{env.BUILD_DEST}}/bin/ ./${{matrix.config.name}}/ - cp -R {{env.INSTALL_DEST}} ./${{matrix.config.name}}/ + cp -R ./${{env.INSTALL_DEST}}/ ./${{matrix.config.name}}/ - name: Upload artifacts if tests fail. Ignore if unit tests are not compiled if: failure() && matrix.config.test == 'ON' diff --git a/framework/aregextend/console/OptionParser.hpp b/framework/aregextend/console/OptionParser.hpp index 60f0c9fe..40bee869 100644 --- a/framework/aregextend/console/OptionParser.hpp +++ b/framework/aregextend/console/OptionParser.hpp @@ -403,7 +403,7 @@ class OptionParser * \return Returns true if succeeded to parse without error. * Otherwise, returns false. **/ - bool parseCommandLine( const char ** cmdLine, uint32_t count); + bool parseCommandLine( const char ** cmdLine, uint32_t count ); bool parseCommandLine( const wchar_t ** cmdLine, uint32_t count ); bool parseCommandLine( char** IN cmdLine, uint32_t count); bool parseCommandLine( wchar_t** IN cmdLine, uint32_t count); @@ -430,6 +430,16 @@ class OptionParser **/ bool parseOptions( StrList & optList ); + /** + * \brief Searches in the command list the option of specified ID. + * Returns valid index if found the option. + * Otherwise, returns invalid index (NECommon::INVALID_POSITION). + * \param optId The ID of an option to search in list. + * \return Returns valid index if found an option with specified ID. + * Otherwise, returns invalid index (NECommon::INVALID_POSITION). + **/ + uint32_t findOption(int optId) const; + /** * \ brief Returns the list of parsed options. **/ diff --git a/framework/aregextend/console/private/OptionParser.cpp b/framework/aregextend/console/private/OptionParser.cpp index 2a21b9bc..cba25289 100644 --- a/framework/aregextend/console/private/OptionParser.cpp +++ b/framework/aregextend/console/private/OptionParser.cpp @@ -167,7 +167,7 @@ namespace optList.push_back( str ); } } -} +} // namespace const OptionParser::sOptionSetup OptionParser::getDefaultOptionSetup( void ) { @@ -389,6 +389,21 @@ bool OptionParser::parseOptions( StrList & optList ) return result; } +uint32_t OptionParser::findOption(int optId) const +{ + uint32_t result{ NECommon::INVALID_POSITION }; + for (uint32_t i = 0; i < mInputOptions.getSize(); ++i) + { + if (mInputOptions.getAt(i).inCommand == optId) + { + result = i; + break; + } + } + + return result; +} + OptionParser::sOption OptionParser::_setupInput( bool isShort, String cmdLine, uint32_t refSetup ) { ASSERT( (refSetup >= 0) && (refSetup < mSetupOptions.getSize()) ); diff --git a/framework/aregextend/service/NESystemService.hpp b/framework/aregextend/service/NESystemService.hpp index 33010e94..4948477a 100644 --- a/framework/aregextend/service/NESystemService.hpp +++ b/framework/aregextend/service/NESystemService.hpp @@ -33,15 +33,18 @@ namespace NESystemService * \brief NESystemService::eServiceOption * Message routing service options. **/ - enum class eServiceOption + enum class eServiceOption : int32_t { CMD_Undefined //!< Option is undefined. + , CMD_Console //!< Option is to execute process as console application. + , CMD_Help //!< Option is to display help on console. + , CMD_Load //!< Option is to start the process and load configuration from specified file , CMD_Install //!< Option is to install (register) service in the system. - , CMD_Uninstall //!< Option is to uninstall (unregister) service in the system. , CMD_Service //!< Option is to execute process as a system service (in background). - , CMD_Console //!< Option is to execute process as console application. + , CMD_Uninstall //!< Option is to uninstall (unregister) service in the system. , CMD_Verbose //!< Option is to display the data rate when execute process as console application. - , CMD_Help //!< Option is to display help on console. + + , CMD_Custom //!< No option, reserved for the custom options. }; /** @@ -54,27 +57,29 @@ namespace NESystemService **/ const OptionParser::sOptionSetup ServiceOptionSetup[ ] { - //!< Default command. - { "" , "" , static_cast(eServiceOption::CMD_Console) , OptionParser::NO_DATA, {}, {}, {} } - //!< Command to install service. Valid for Windows OS, ignored in other cases. - , { "-i", "--install" , static_cast(eServiceOption::CMD_Install) , OptionParser::NO_DATA, {}, {}, {} } - //!< Command to uninstall service. Valid for Windows OS, ignored in other cases. - , { "-u", "--uninstall", static_cast(eServiceOption::CMD_Uninstall) , OptionParser::NO_DATA, {}, {}, {} } - //!< Command to run process as a system service process. - , { "-s", "--service" , static_cast(eServiceOption::CMD_Service) , OptionParser::NO_DATA, {}, {}, {} } - //!< Command to run process as a console application. - , { "-c", "--console" , static_cast(eServiceOption::CMD_Console) , OptionParser::NO_DATA, {}, {}, {} } - //!< Command to display data rate when run as console application. - , { "-v", "--verbose" , static_cast(eServiceOption::CMD_Verbose) , OptionParser::NO_DATA, {}, {}, {} } - //!< Command to display help on console. - , { "-h", "--help" , static_cast(eServiceOption::CMD_Help) , OptionParser::NO_DATA, {}, {}, {} } + //!< Default command. + { "" , "" , static_cast(eServiceOption::CMD_Console) , OptionParser::NO_DATA , {}, {}, {} } + //!< Command to run process as a console application. + , { "-c", "--console" , static_cast(eServiceOption::CMD_Console) , OptionParser::NO_DATA , {}, {}, {} } + //!< Command to display help on console. + , { "-h", "--help" , static_cast(eServiceOption::CMD_Help) , OptionParser::NO_DATA , {}, {}, {} } + //!< Command to display the error message. + , { "-l", "--load" , static_cast(eServiceOption::CMD_Load) , OptionParser::STRING_NO_RANGE , {}, {}, {} } + //!< Command to install service. Valid for Windows OS, ignored in other cases. + , { "-i", "--install" , static_cast(eServiceOption::CMD_Install) , OptionParser::NO_DATA , {}, {}, {} } + //!< Command to run process as a system service process. + , { "-s", "--service" , static_cast(eServiceOption::CMD_Service) , OptionParser::NO_DATA , {}, {}, {} } + //!< Command to uninstall service. Valid for Windows OS, ignored in other cases. + , { "-u", "--uninstall" , static_cast(eServiceOption::CMD_Uninstall) , OptionParser::NO_DATA , {}, {}, {} } + //!< Command to display data rate when run as console application. + , { "-v", "--verbose" , static_cast(eServiceOption::CMD_Verbose) , OptionParser::NO_DATA , {}, {}, {} } }; /** * \brief NESystemService::eSystemServiceState * Describes the system service state. **/ - enum class eSystemServiceState + enum class eSystemServiceState : int32_t { ServiceStopped //!< Service is stopped. , ServiceStarting //!< Service is in starting process. @@ -189,18 +194,20 @@ inline const char * NESystemService::getString( NESystemService::eServiceOption { case NESystemService::eServiceOption::CMD_Undefined: return "NESystemService::CMD_Undefined"; + case NESystemService::eServiceOption::CMD_Console: + return "NESystemService::CMD_Console"; + case NESystemService::eServiceOption::CMD_Help: + return "NESystemService::CMD_Help"; + case NESystemService::eServiceOption::CMD_Load: + return "NESystemService::CMD_Load"; case NESystemService::eServiceOption::CMD_Install: return "NESystemService::CMD_Install"; - case NESystemService::eServiceOption::CMD_Uninstall: - return "NESystemService::CMD_Uninstall"; case NESystemService::eServiceOption::CMD_Service: return "NESystemService::CMD_Service"; - case NESystemService::eServiceOption::CMD_Console: - return "NESystemService::CMD_Console"; + case NESystemService::eServiceOption::CMD_Uninstall: + return "NESystemService::eServiceOption::CMD_Uninstall"; case NESystemService::eServiceOption::CMD_Verbose: - return "NESystemService::CMD_Verbose"; - case NESystemService::eServiceOption::CMD_Help: - return "NESystemService::eServiceOption::CMD_Help"; + return "NESystemService::eServiceOption::CMD_Verbose"; default: ASSERT( false ); return "ERR: Unexpected NESystemService::eServiceOption value!"; diff --git a/framework/aregextend/service/ServiceApplicationBase.hpp b/framework/aregextend/service/ServiceApplicationBase.hpp index 1cebe4d4..83f3bdba 100644 --- a/framework/aregextend/service/ServiceApplicationBase.hpp +++ b/framework/aregextend/service/ServiceApplicationBase.hpp @@ -261,7 +261,7 @@ class ServiceApplicationBase : public SystemServiceBase private: /** - * \brief OS specific validity check of logger service. + * \brief OS specific validity check of the service. **/ bool _osIsValid( void ) const; @@ -270,6 +270,9 @@ class ServiceApplicationBase : public SystemServiceBase **/ void _osFreeResources( void ); + /** + * \brief OS specific initialization of the service. + **/ bool _osInitializeService( void ); /** diff --git a/framework/aregextend/service/SystemServiceBase.hpp b/framework/aregextend/service/SystemServiceBase.hpp index d6599bd5..80d62a5f 100644 --- a/framework/aregextend/service/SystemServiceBase.hpp +++ b/framework/aregextend/service/SystemServiceBase.hpp @@ -327,6 +327,10 @@ class SystemServiceBase * \brief OS specific service manager handle. **/ void * mSeMHandle; + /** + * \brief The relative or full path to the configuration file. By default, NEApplication::DEFAULT_CONFIG_FILE + **/ + String mFileConfig; ////////////////////////////////////////////////////////////////////////// // Forbidden calls diff --git a/framework/aregextend/service/private/ServiceApplicationBase.cpp b/framework/aregextend/service/private/ServiceApplicationBase.cpp index 12755f24..8d250a8f 100644 --- a/framework/aregextend/service/private/ServiceApplicationBase.cpp +++ b/framework/aregextend/service/private/ServiceApplicationBase.cpp @@ -37,6 +37,7 @@ ServiceApplicationBase::ServiceApplicationBase(ServiceCommunicatonBase& commBase int ServiceApplicationBase::serviceMain(int argc, char** argv) { int result{ RESULT_SUCCEEDED }; + Application::setWorkingDirectory(nullptr); if (parseOptions(argc, argv, NESystemService::ServiceOptionSetup, MACRO_ARRAYLEN(NESystemService::ServiceOptionSetup)) == false) { resetDefaultOptions(); @@ -56,6 +57,7 @@ int ServiceApplicationBase::serviceMain(int argc, char** argv) break; case NESystemService::eServiceOption::CMD_Service: // fall through + case NESystemService::eServiceOption::CMD_Load: // fall through case NESystemService::eServiceOption::CMD_Console: result = SystemServiceBase::serviceMain(static_cast(argc), argv); mCommunication.waitToComplete(); @@ -82,7 +84,7 @@ bool ServiceApplicationBase::serviceInitialize(int /* argc */, char** /* argv */ , false , true , false - , NEApplication::DEFAULT_CONFIG_FILE.data() + , mFileConfig.isEmpty() ? NEApplication::DEFAULT_CONFIG_FILE.data() : mFileConfig.getString() , static_cast(this)); return _osInitializeService(); } diff --git a/framework/aregextend/service/private/SystemServiceBase.cpp b/framework/aregextend/service/private/SystemServiceBase.cpp index c7fdcec9..881955e1 100644 --- a/framework/aregextend/service/private/SystemServiceBase.cpp +++ b/framework/aregextend/service/private/SystemServiceBase.cpp @@ -14,6 +14,8 @@ ************************************************************************/ #include "aregextend/service/SystemServiceBase.hpp" +#include "areg/appbase/Application.hpp" +#include "areg/base/File.hpp" #include "areg/trace/GETrace.h" #include "aregextend/console/Console.hpp" @@ -33,12 +35,14 @@ SystemServiceBase::SystemServiceBase( ServiceCommunicatonBase & commBase ) , mSystemServiceOption ( NESystemService::DEFAULT_OPTION ) , mSvcHandle ( nullptr ) , mSeMHandle ( nullptr ) + , mFileConfig ( NEApplication::DEFAULT_CONFIG_FILE ) { } void SystemServiceBase::resetDefaultOptions(void) { mSystemServiceOption = NESystemService::DEFAULT_OPTION; + mFileConfig = NEApplication::DEFAULT_CONFIG_FILE; mCommunication.enableCalculateDataRate(NESystemService::DEFAULT_VERBOSE); } @@ -49,7 +53,7 @@ bool SystemServiceBase::parseOptions( int argc, const char ** argv, const Option if (argc > 1) { OptionParser parser(optSetup, optCount); - if (parser.parseCommandLine(static_cast(argv), argc > 1 ? static_cast(argc) : 0)) + if (parser.parseCommandLine(argv, argc > 1 ? static_cast(argc) : 0)) { result = prepareOptions(parser.getOptions()); } @@ -70,8 +74,28 @@ bool SystemServiceBase::parseOptions( int argc, const char ** argv, const Option bool SystemServiceBase::parseOptions(int argc, char** argv, const OptionParser::sOptionSetup* optSetup, uint32_t optCount) { - const char* temp{ argv != nullptr ? static_cast(*argv) : nullptr }; - return (temp != nullptr ? parseOptions(argc, &temp, optSetup, optCount) : false); + bool result{ false }; + + if (argc > 1) + { + OptionParser parser(optSetup, optCount); + if (parser.parseCommandLine(argv, argc > 1 ? static_cast(argc) : 0)) + { + result = prepareOptions(parser.getOptions()); + } + else + { + printHelp(true); + result = false; + } + } + else if (argc == 1) + { + resetDefaultOptions(); + result = true; + } + + return result; } bool SystemServiceBase::prepareOptions(const OptionParser::InputOptionList& opts) @@ -84,14 +108,25 @@ bool SystemServiceBase::prepareOptions(const OptionParser::InputOptionList& opts const OptionParser::sOption& opt = opts[i]; switch (static_cast(opt.inCommand)) { - case NESystemService::eServiceOption::CMD_Install: - case NESystemService::eServiceOption::CMD_Uninstall: - case NESystemService::eServiceOption::CMD_Service: - case NESystemService::eServiceOption::CMD_Console: + case NESystemService::eServiceOption::CMD_Install: // fall through + case NESystemService::eServiceOption::CMD_Uninstall:// fall through + case NESystemService::eServiceOption::CMD_Service: // fall through + case NESystemService::eServiceOption::CMD_Console: // fall through result = true; setCurrentOption(static_cast(opt.inCommand)); break; + case NESystemService::eServiceOption::CMD_Load: + { + result = true; + String filePath(opt.inString[0]); + if (File::existFile(filePath)) + { + mFileConfig = filePath; + } + } + break; + case NESystemService::eServiceOption::CMD_Verbose: mCommunication.enableCalculateDataRate(true); setCurrentOption(NESystemService::eServiceOption::CMD_Console); @@ -122,7 +157,6 @@ bool SystemServiceBase::prepareOptions(const OptionParser::InputOptionList& opts int SystemServiceBase::serviceMain( int argc, char ** argv ) { int result{ RESULT_SUCCEEDED }; - if (serviceInitialize(argc, argv)) { TRACE_SCOPE( utilities_service_base_SystemServiceBase_serviceMain ); diff --git a/framework/areglogger.vcxproj b/framework/areglogger.vcxproj index 67d1a5ac..9c58b8f7 100644 --- a/framework/areglogger.vcxproj +++ b/framework/areglogger.vcxproj @@ -25,6 +25,7 @@ Windows + areglogger/resources/areglogger.def @@ -51,10 +52,10 @@ - + - + diff --git a/framework/areglogger.vcxproj.filters b/framework/areglogger.vcxproj.filters index 8a7fa2dc..d486adaf 100644 --- a/framework/areglogger.vcxproj.filters +++ b/framework/areglogger.vcxproj.filters @@ -51,14 +51,14 @@ - - - Source Files - - Resource Files + + + Source Files + + \ No newline at end of file diff --git a/framework/areglogger/client/private/LogObserverApi.cpp b/framework/areglogger/client/private/LogObserverApi.cpp index 70481399..89d9c7a8 100644 --- a/framework/areglogger/client/private/LogObserverApi.cpp +++ b/framework/areglogger/client/private/LogObserverApi.cpp @@ -24,13 +24,13 @@ // Use these options if compile for Windows with MSVC #ifdef WINDOWS - #pragma comment(lib, "areg") - #pragma comment(lib, "aregextend") + #pragma comment(lib, "areg.lib") + #pragma comment(lib, "aregextend.lib") #if defined(USE_SQLITE_PACKAGE) && (USE_SQLITE_PACKAGE != 0) #pragma comment(lib, "sqlite3") #else // defined(USE_SQLITE_PACKAGE) && (USE_SQLITE_PACKAGE != 0) - #pragma comment(lib, "aregsqlite3") + #pragma comment(lib, "aregsqlite3.lib") #endif //defined(USE_SQLITE_PACKAGE) && (USE_SQLITE_PACKAGE != 0) #endif // WINDOWS diff --git a/framework/logger/app/Logger.hpp b/framework/logger/app/Logger.hpp index fab87e7f..52502e9b 100644 --- a/framework/logger/app/Logger.hpp +++ b/framework/logger/app/Logger.hpp @@ -50,23 +50,24 @@ class Logger : public ServiceApplicationBase **/ enum class eLoggerOptions : int32_t { - CMD_LogUndefined //!< Undefined command. - , CMD_LogPause //!< Pause logger. - , CMD_LogRestart //!< Restart logger. - , CMD_LogInstances //!< Display the names of connected instances. - , CMD_LogVerbose //!< Display data rate information if possible. Functions only with extended features. - , CMD_LogSilent //!< Silent mode, no data rate is displayed. - , CMD_LogPrintHelp //!< Output help message. - , CMD_LogQuit //!< Quit logger. - , CMD_LogConsole //!< Run as console application. Valid only as a command line option. - , CMD_LogInstall //!< Install as service. Valid only as a command line option in Windows OS. - , CMD_LogUninstall //!< Uninstall as a service. Valid only as a command line option in Windows OS. - , CMD_LogQueryScopes //!< Query the list of scopes - , CMD_LogService //!< Start logger as a service. Valid only as a command line option in Windows OS. - , CMD_LogUpdateScope //!< Set the scope priorities. - , CMD_LogSaveLogs //!< Logger save logs in the file. - , CMD_LogSaveLogsStop //!< Cancel saving logs in the file. - , CMD_LogSaveConfig //!< Save the log configuration in the config file. + CMD_LogUndefined = static_cast(NESystemService::eServiceOption::CMD_Undefined) //!< Undefined command. + , CMD_LogConsole = static_cast(NESystemService::eServiceOption::CMD_Console) //!< Run as console application. Valid only as a command line option. + , CMD_LogPrintHelp = static_cast(NESystemService::eServiceOption::CMD_Help) //!< Output help message. + , CMD_LogLoad = static_cast(NESystemService::eServiceOption::CMD_Load) //!< Start the service by loading initialization instructions from configuration file. + , CMD_LogInstall = static_cast(NESystemService::eServiceOption::CMD_Install) //!< Install as service. Valid only as a command line option in Windows OS. + , CMD_LogService = static_cast(NESystemService::eServiceOption::CMD_Service) //!< Start logger as a service. Valid only as a command line option in Windows OS. + , CMD_LogUninstall = static_cast(NESystemService::eServiceOption::CMD_Uninstall) //!< Uninstall as a service. Valid only as a command line option in Windows OS. + , CMD_LogVerbose = static_cast(NESystemService::eServiceOption::CMD_Verbose) //!< Display data rate information if possible. Functions only with extended features. + , CMD_LogPause = static_cast(NESystemService::eServiceOption::CMD_Custom) //!< Pause logger. + , CMD_LogRestart //!< Restart logger. + , CMD_LogInstances //!< Display the names of connected log provider and log observer instances. + , CMD_LogSilent //!< Silent mode, no data rate is displayed. + , CMD_LogQuit //!< Quit logger. + , CMD_LogQueryScopes //!< Query the list of scopes + , CMD_LogUpdateScope //!< Set the scope priorities. + , CMD_LogSaveLogs //!< Logger save logs in the file. + , CMD_LogSaveLogsStop //!< Stop saving logs in the file. + , CMD_LogSaveConfig //!< Save the log configuration in the config file. }; /** diff --git a/framework/logger/app/private/Logger.cpp b/framework/logger/app/private/Logger.cpp index 15cf7aa5..f6fab948 100644 --- a/framework/logger/app/private/Logger.cpp +++ b/framework/logger/app/private/Logger.cpp @@ -60,18 +60,20 @@ namespace {"Usage of AREG Log collector (logger) :"} , NESystemService::MSG_SEPARATOR , {"-a, --save : Command to save logs in the file. Used in console application. Usage: --save"} + , {"-b, --unsave : Command to stop saving logs in the file. Used in console application. Usage: --unsave"} , {"-c, --console : Command to run logger as a console application (default option). Usage: \'logger --console\'"} , {"-e, --query : Command to query the list of logging scopes. Used in console application. Usage (\'*\' can be a cookie number): --query *"} , {"-f, --config : Command to save current configuration, including log scopes in the config file. Used in console application. Usage: --config"} , {"-h, --help : Command to display this message on console."} , {"-i, --install : Command to install logger as a service. Valid only for Windows OS. Usage: \'logger --install\'"} - , {"-l, --silent : Command option to stop displaying data rate. Used in console application. Usage: --silent"} + , {"-l, --load : Command to initialize from specified file. Used to start application. Usage: \'logger --load=\'"} , {"-n, --instances : Command option to display list of connected instances. Used in console application. Usage: --instances"} , {"-o, --scope : Command to update log scope priority. Used in console application. Usage (\'*\' can be a cookie number): --scope *::areg_base_NESocket=NOTSET"} , {"-p, --pause : Command option to pause connection. Used in console application. Usage: --pause"} , {"-q, --quit : Command option to stop logger and quit application. Used in console application. Usage: --quit"} , {"-r, --restart : Command option to restart connection. Used in console application. Usage: --restart"} , {"-s, --service : Command to run logger as a system service. Usage: \'logger --service\'"} + , {"-t, --silent : Command option to stop displaying data rate. Used in console application. Usage: --silent"} , {"-u, --uninstall : Command to uninstall logger as a service. Valid only for Windows OS. Usage: \'logger --uninstall\'"} , {"-v, --verbose : Command option to display data rate. Used in console application. Usage: --verbose"} , NESystemService::MSG_SEPARATOR @@ -104,13 +106,14 @@ const OptionParser::sOptionSetup Logger::ValidOptions[ ] , { "-f", "--config" , static_cast(eLoggerOptions::CMD_LogSaveConfig) , OptionParser::STRING_NO_RANGE , {}, {}, {} } , { "-h", "--help" , static_cast(eLoggerOptions::CMD_LogPrintHelp) , OptionParser::NO_DATA , {}, {}, {} } , { "-i", "--install" , static_cast(eLoggerOptions::CMD_LogInstall) , OptionParser::NO_DATA , {}, {}, {} } - , { "-l", "--silent" , static_cast(eLoggerOptions::CMD_LogSilent) , OptionParser::NO_DATA , {}, {}, {} } + , { "-l", "--load" , static_cast(eLoggerOptions::CMD_LogLoad) , OptionParser::STRING_NO_RANGE , {}, {}, {} } , { "-n", "--instances" , static_cast(eLoggerOptions::CMD_LogInstances) , OptionParser::NO_DATA , {}, {}, {} } , { "-o", "--scope" , static_cast(eLoggerOptions::CMD_LogUpdateScope) , OptionParser::STRING_NO_RANGE , {}, {}, {} } , { "-p", "--pause" , static_cast(eLoggerOptions::CMD_LogPause) , OptionParser::NO_DATA , {}, {}, {} } , { "-q", "--quit" , static_cast(eLoggerOptions::CMD_LogQuit) , OptionParser::NO_DATA , {}, {}, {} } , { "-r", "--restart" , static_cast(eLoggerOptions::CMD_LogRestart) , OptionParser::NO_DATA , {}, {}, {} } , { "-s", "--service" , static_cast(eLoggerOptions::CMD_LogService) , OptionParser::NO_DATA , {}, {}, {} } + , { "-t", "--silent" , static_cast(eLoggerOptions::CMD_LogSilent) , OptionParser::NO_DATA , {}, {}, {} } , { "-u", "--uninstall" , static_cast(eLoggerOptions::CMD_LogUninstall) , OptionParser::NO_DATA , {}, {}, {} } , { "-v", "--verbose" , static_cast(eLoggerOptions::CMD_LogVerbose) , OptionParser::NO_DATA , {}, {}, {} } }; @@ -353,7 +356,8 @@ bool Logger::_checkCommand(const String& cmd) case eLoggerOptions::CMD_LogConsole: // fall through case eLoggerOptions::CMD_LogInstall: // fall through case eLoggerOptions::CMD_LogUninstall: // fall through - case eLoggerOptions::CMD_LogService: + case eLoggerOptions::CMD_LogService: // fall through + case eLoggerOptions::CMD_LogLoad: Logger::_outputInfo("This command should be used in command line ..."); break; diff --git a/framework/logobserver/app/LogObserver.hpp b/framework/logobserver/app/LogObserver.hpp index 45fece34..50b4edb1 100644 --- a/framework/logobserver/app/LogObserver.hpp +++ b/framework/logobserver/app/LogObserver.hpp @@ -53,15 +53,16 @@ class LogObserver **/ enum class eLoggerOptions : int32_t { - CMD_LogUndefined = 0 //!< Undefined command. - , CMD_LogQueryScopes //!< Query the list of scopes - , CMD_LogSaveConfig //!< Save the configuration file. + CMD_LogUndefined = 0//!< Undefined command. , CMD_LogPrintHelp //!< Output help message. - , CMD_LogInformation //!< Display the list of logging source instances. + , CMD_LogLoad //!< Start the application by loading initialization instructions from configuration file. + , CMD_LogPause //!< Pause log observer + , CMD_LogRestart //!< Start / Restart log observer + , CMD_LogInstances //!< Display the list of log providers + , CMD_LogQuit //!< Quit logger. + , CMD_LogQueryScopes //!< Query the list of scopes , CMD_LogUpdateScope //!< Set and update the log scope priorities. - , CMD_LogPause //!< Pause log observer. - , CMD_LogQuit //!< Quit log observer. - , CMD_LogRestart //!< Restart / continue log observer . + , CMD_LogSaveConfig //!< Save the configuration file. , CMD_LogStop //!< Stop log observer. }; @@ -85,24 +86,29 @@ class LogObserver **/ static constexpr sObserverStatus ObserverStatus[] { + // ---------------------------------------------------------------------------------------------------- + // | Option | status | error | + // ---------------------------------------------------------------------------------------------------- //!< No status, no error - { eLoggerOptions::CMD_LogUndefined , "", "" } - //!< The status and error message when query scopes. - , { eLoggerOptions::CMD_LogQueryScopes , "Log observer queries scopes." , "Log observer failed to query scopes." } - //!< The status and error message when request to save configuration - , { eLoggerOptions::CMD_LogSaveConfig , "Log observer requested to save configuration." , "Log observer failed to request save config." } + { eLoggerOptions::CMD_LogUndefined , "" , "" } //!< No status or error when output print help - , { eLoggerOptions::CMD_LogPrintHelp , "", "" } - //!< The status or error message when request to output list of connected instances. - , { eLoggerOptions::CMD_LogInformation , "List of connected instances ..." , "" } - //!< The status or error message when request to update scopes. - , { eLoggerOptions::CMD_LogUpdateScope , "Log observer requested to update scopes." , "Log observer failed to request update scopes." } + , { eLoggerOptions::CMD_LogPrintHelp , "" , "" } + //!< No status or error when Start the application by loading initialization instructions from configuration file. + , { eLoggerOptions::CMD_LogLoad , "" , "The configuration file does not exist or wrong, make default initialization." } //!< The status or error message when request to pause logging. , { eLoggerOptions::CMD_LogPause , "Log observer is paused, type \'-r\' to resume." , "" } - //!< No status or error when request to quit log observer - , { eLoggerOptions::CMD_LogQuit , "", "" } //!< The status or error message when request to start or resume log observer. , { eLoggerOptions::CMD_LogRestart , "Log observer triggered connection." , "Log observer failed to trigger connection. Check initialization." } + //!< The status or error message when request to output list of connected instances. + , { eLoggerOptions::CMD_LogInstances , "List of connected instances ..." , "" } + //!< No status or error when request to quit log observer + , { eLoggerOptions::CMD_LogQuit , "", "" } + //!< The status and error message when query scopes. + , { eLoggerOptions::CMD_LogQueryScopes , "Log observer queries scopes." , "Log observer failed to query scopes." } + //!< The status or error message when request to update scopes. + , { eLoggerOptions::CMD_LogUpdateScope , "Log observer requested to update scopes." , "Log observer failed to request update scopes." } + //!< The status and error message when request to save configuration + , { eLoggerOptions::CMD_LogSaveConfig , "Log observer requested to save configuration." , "Log observer failed to request save config." } //!< The status or error message when request to stop logging. , { eLoggerOptions::CMD_LogStop , "Log observer stops, type \'-r\' to resume." , "Log observer failed to stop. Restart application." } }; diff --git a/framework/logobserver/app/private/LogObserver.cpp b/framework/logobserver/app/private/LogObserver.cpp index cf022818..2f517a04 100644 --- a/framework/logobserver/app/private/LogObserver.cpp +++ b/framework/logobserver/app/private/LogObserver.cpp @@ -20,11 +20,10 @@ #include "areg/appbase/Application.hpp" #include "areg/base/DateTime.hpp" +#include "areg/base/File.hpp" #include "areg/base/String.hpp" #include "areg/persist/ConfigManager.hpp" - #include "aregextend/service/NESystemService.hpp" - #include "areglogger/client/LogObserverApi.h" #include @@ -45,12 +44,13 @@ namespace , {"-e, --query : Query the list of logging scopes. Usage: --query *, \'*\' can be a cookie ID."} , {"-f, --config : Save current configuration. Usage: --config"} , {"-h, --help : Display this message on console. Usage: --help"} - , {"-i, --info : Display list of log instances. Usage: --info"} + , {"-n, --instances : Display list of log instances. Usage: --instances"} + , {"-l, --load : Command line option to configure. Usage: \'./logobserver --load=\'"} , {"-o, --scope : Update log scope priorities. Usage: --scope *::areg_base_NESocket=NOTSET, \'*\' can be a cookie."} , {"-p, --pause : Pause the log observer. Usage: --pause"} , {"-q, --quit : Stop and quit the log observer. Usage: --quit"} , {"-r, --restart : Start / continue log observer. Usage: --restart"} - , {"-s, --stop : Stop log observer. Usage: --stop"} + , {"-x, --stop : Stop log observer. Usage: --stop"} , NESystemService::MSG_SEPARATOR }; @@ -79,12 +79,13 @@ const OptionParser::sOptionSetup LogObserver::ValidOptions[ ] { "-e", "--query" , static_cast(eLoggerOptions::CMD_LogQueryScopes) , OptionParser::STRING_NO_RANGE , {}, {}, {} } , { "-f", "--config" , static_cast(eLoggerOptions::CMD_LogSaveConfig) , OptionParser::STRING_NO_RANGE , {}, {}, {} } , { "-h", "--help" , static_cast(eLoggerOptions::CMD_LogPrintHelp) , OptionParser::NO_DATA , {}, {}, {} } - , { "-i", "--info" , static_cast(eLoggerOptions::CMD_LogInformation) , OptionParser::NO_DATA , {}, {}, {} } + , { "-l", "--load" , static_cast(eLoggerOptions::CMD_LogLoad) , OptionParser::STRING_NO_RANGE , {}, {}, {} } + , { "-n", "--instances" , static_cast(eLoggerOptions::CMD_LogInstances) , OptionParser::NO_DATA , {}, {}, {} } , { "-o", "--scope" , static_cast(eLoggerOptions::CMD_LogUpdateScope) , OptionParser::STRING_NO_RANGE , {}, {}, {} } , { "-p", "--pause" , static_cast(eLoggerOptions::CMD_LogPause) , OptionParser::NO_DATA , {}, {}, {} } , { "-q", "--quit" , static_cast(eLoggerOptions::CMD_LogQuit) , OptionParser::NO_DATA , {}, {}, {} } , { "-r", "--restart" , static_cast(eLoggerOptions::CMD_LogRestart) , OptionParser::NO_DATA , {}, {}, {} } - , { "-s", "--stop" , static_cast(eLoggerOptions::CMD_LogStop) , OptionParser::NO_DATA , {}, {}, {} } + , { "-x", "--stop" , static_cast(eLoggerOptions::CMD_LogStop) , OptionParser::NO_DATA , {}, {}, {} } }; LogObserver & LogObserver::getInstance(void) @@ -279,7 +280,7 @@ void LogObserver::callbackLogMessageEx(const unsigned char* logBuffer, uint32_t } } -void LogObserver::logMain( int /* argc */, char ** /* argv */ ) +void LogObserver::logMain( int argc, char ** argv ) { sObserverEvents evts { @@ -296,7 +297,23 @@ void LogObserver::logMain( int /* argc */, char ** /* argv */ ) , &LogObserver::callbackLogMessageEx }; - ::logObserverInitialize(&evts, nullptr); + Application::setWorkingDirectory(nullptr); + String fileConfig(NEApplication::DEFAULT_CONFIG_FILE); + OptionParser parser(LogObserver::ValidOptions, MACRO_ARRAYLEN(LogObserver::ValidOptions)); + if (parser.parseCommandLine(argv, argc)) + { + uint32_t pos = parser.findOption(static_cast(LogObserver::eLoggerOptions::CMD_LogLoad)); + if (pos != NECommon::INVALID_POSITION) + { + String filePath{ parser.getOptions().getAt(pos).inString[0] }; + if (File::existFile(filePath)) + { + fileConfig = filePath; + } + } + } + + ::logObserverInitialize(&evts, fileConfig.getString()); _runConsoleInputExtended(); @@ -339,9 +356,9 @@ bool LogObserver::_checkCommand(const String& cmd) status = &ObserverStatus[static_cast(eLoggerOptions::CMD_LogPrintHelp)]; break; - case LogObserver::eLoggerOptions::CMD_LogInformation: + case LogObserver::eLoggerOptions::CMD_LogInstances: processed = LogObserver::_processInfoInstances(); - status = &ObserverStatus[static_cast(eLoggerOptions::CMD_LogInformation)]; + status = &ObserverStatus[static_cast(eLoggerOptions::CMD_LogInstances)]; break; case LogObserver::eLoggerOptions::CMD_LogUpdateScope: @@ -368,7 +385,8 @@ bool LogObserver::_checkCommand(const String& cmd) status = &ObserverStatus[static_cast(eLoggerOptions::CMD_LogStop)]; break; - case LogObserver::eLoggerOptions::CMD_LogUndefined: + case LogObserver::eLoggerOptions::CMD_LogLoad: // fall through + case LogObserver::eLoggerOptions::CMD_LogUndefined: // fall through default: hasError = true; break; diff --git a/framework/mcrouter/app/MulticastRouter.hpp b/framework/mcrouter/app/MulticastRouter.hpp index e53189da..fd041ba8 100644 --- a/framework/mcrouter/app/MulticastRouter.hpp +++ b/framework/mcrouter/app/MulticastRouter.hpp @@ -22,9 +22,10 @@ #include "aregextend/service/ServiceApplicationBase.hpp" #include "areg/base/SynchObjects.hpp" +#include "aregextend/console/OptionParser.hpp" +#include "aregextend/service/NESystemService.hpp" #include "mcrouter/app/NEMulticastRouterSettings.hpp" #include "mcrouter/service/RouterServerService.hpp" -#include "aregextend/console/OptionParser.hpp" #include @@ -50,18 +51,19 @@ class MulticastRouter final : public ServiceApplicationBase **/ enum class eRouterOptions : int32_t { - CMD_RouterUndefined //!< Undefined command. - , CMD_RouterPause //!< Pause router. - , CMD_RouterRestart //!< Restart router. - , CMD_RouterInstances //!< Display list of connected instances. - , CMD_RouterVerbose //!< Display data rate information if possible. Functions only with extended features - , CMD_RouterSilent //!< Silent mode, no data rate is displayed. - , CMD_RouterPrintHelp //!< Print help. - , CMD_RouterQuit //!< Quit router. - , CMD_RouterConsole //!< Run as console application. Valid only as a command line option - , CMD_RouterInstall //!< Install as service. Valid only as a command line option in Windows OS - , CMD_RouterUninstall //!< Uninstall as a service. Valid only as a command line option in Windows OS - , CMD_RouterService //!< Start router as a service. Valid only as a command line option in Windows OS + CMD_RouterUndefined = static_cast(NESystemService::eServiceOption::CMD_Undefined) //!< Undefined command. + , CMD_RouterConsole = static_cast(NESystemService::eServiceOption::CMD_Console) //!< Run as console application. Valid only as a command line option + , CMD_RouterPrintHelp = static_cast(NESystemService::eServiceOption::CMD_Help) //!< Print help. + , CMD_RouterLoad = static_cast(NESystemService::eServiceOption::CMD_Load) //!< Start the service by loading initialization instructions from configuration file. + , CMD_RouterInstall = static_cast(NESystemService::eServiceOption::CMD_Install) //!< Install as service. Valid only as a command line option in Windows OS + , CMD_RouterService = static_cast(NESystemService::eServiceOption::CMD_Service) //!< Start router as a service. Valid only as a command line option in Windows OS + , CMD_RouterUninstall = static_cast(NESystemService::eServiceOption::CMD_Uninstall) //!< Uninstall as a service. Valid only as a command line option in Windows OS + , CMD_RouterVerbose = static_cast(NESystemService::eServiceOption::CMD_Verbose) //!< Display data rate information if possible. Functions only with extended features + , CMD_RouterPause = static_cast(NESystemService::eServiceOption::CMD_Custom) //!< Pause router. + , CMD_RouterRestart //!< Start / Restart router. + , CMD_RouterInstances //!< Display list of connected instances. + , CMD_RouterSilent //!< Silent mode, no data rate is displayed. + , CMD_RouterQuit //!< Quit router. }; /** diff --git a/framework/mcrouter/app/private/MulticastRouter.cpp b/framework/mcrouter/app/private/MulticastRouter.cpp index a92ea596..181376b1 100644 --- a/framework/mcrouter/app/private/MulticastRouter.cpp +++ b/framework/mcrouter/app/private/MulticastRouter.cpp @@ -62,12 +62,13 @@ namespace , {"-c, --console : Command to run mcrouter as a console application (default option). Usage: \'mcrouter --console\'"} , {"-h, --help : Command to display this message on console."} , {"-i, --install : Command to install mcrouter as a service. Valid only for Windows OS. Usage: \'mcrouter --install\'"} - , {"-l, --silent : Command option to stop displaying data rate. Used in console application. Usage: --silent"} + , {"-l, --load : Command to initialize from specified file. Used to start application. Usage: \'mcrouter --load=\'"} , {"-n, --instances : Command option to display list of connected instances. Used in console application. Usage: --instances"} , {"-p, --pause : Command option to pause connection. Used in console application. Usage: --pause"} , {"-q, --quit : Command option to stop router and quit application. Used in console application. Usage: --quit"} , {"-r, --restart : Command option to restart connection. Used in console application. Usage: --restart"} , {"-s, --service : Command to run mcrouter as a system service. Usage: \'mcrouter --service\'"} + , {"-t, --silent : Command option to stop displaying data rate. Used in console application. Usage: --silent"} , {"-u, --uninstall : Command to uninstall mcrouter as a service. Valid only for Windows OS. Usage: \'mcrouter --uninstall\'"} , {"-v, --verbose : Command option to display data rate. Used in console application. Usage: --verbose"} , NESystemService::MSG_SEPARATOR @@ -96,12 +97,12 @@ const OptionParser::sOptionSetup MulticastRouter::ValidOptions[ ] { "-c", "--console" , static_cast(eRouterOptions::CMD_RouterConsole) , OptionParser::NO_DATA , {}, {}, {} } , { "-h", "--help" , static_cast(eRouterOptions::CMD_RouterPrintHelp) , OptionParser::NO_DATA , {}, {}, {} } , { "-i", "--install" , static_cast(eRouterOptions::CMD_RouterInstall) , OptionParser::NO_DATA , {}, {}, {} } - , { "-l", "--silent" , static_cast(eRouterOptions::CMD_RouterSilent) , OptionParser::NO_DATA , {}, {}, {} } , { "-n", "--instances" , static_cast(eRouterOptions::CMD_RouterInstances) , OptionParser::NO_DATA , {}, {}, {} } , { "-p", "--pause" , static_cast(eRouterOptions::CMD_RouterPause) , OptionParser::NO_DATA , {}, {}, {} } , { "-q", "--quit" , static_cast(eRouterOptions::CMD_RouterQuit) , OptionParser::NO_DATA , {}, {}, {} } , { "-r", "--restart" , static_cast(eRouterOptions::CMD_RouterRestart) , OptionParser::NO_DATA , {}, {}, {} } , { "-s", "--service" , static_cast(eRouterOptions::CMD_RouterService) , OptionParser::NO_DATA , {}, {}, {} } + , { "-t", "--silent" , static_cast(eRouterOptions::CMD_RouterSilent) , OptionParser::NO_DATA , {}, {}, {} } , { "-u", "--uninstall" , static_cast(eRouterOptions::CMD_RouterUninstall) , OptionParser::NO_DATA , {}, {}, {} } , { "-v", "--verbose" , static_cast(eRouterOptions::CMD_RouterVerbose) , OptionParser::NO_DATA , {}, {}, {} } }; @@ -325,10 +326,11 @@ bool MulticastRouter::_checkCommand(const String& cmd) quit = true; break; - case MulticastRouter::eRouterOptions::CMD_RouterConsole: // pass through - case MulticastRouter::eRouterOptions::CMD_RouterInstall: // pass through - case MulticastRouter::eRouterOptions::CMD_RouterUninstall: // pass through - case MulticastRouter::eRouterOptions::CMD_RouterService: + case MulticastRouter::eRouterOptions::CMD_RouterConsole: // pass through + case MulticastRouter::eRouterOptions::CMD_RouterInstall: // pass through + case MulticastRouter::eRouterOptions::CMD_RouterUninstall: // pass through + case MulticastRouter::eRouterOptions::CMD_RouterService: // pass through + case MulticastRouter::eRouterOptions::CMD_RouterLoad: MulticastRouter::_outputInfo("This command should be used in command line ..."); break;