From d1f61aa74372cb8d5046db556241cb53f03c9dad Mon Sep 17 00:00:00 2001 From: TTTTTAAAAAKKKKEEEENNNN <48080812+TTTTTAAAAAKKKKEEEENNNN@users.noreply.github.com> Date: Sun, 14 Mar 2021 23:31:57 +0800 Subject: [PATCH] bugfix #58 use default logger settings when initializing the client and allow user to manually specify one when creating service objects --- include/factory/NacosServiceFactory.h | 5 +++++ src/factory/NacosServiceFactory.cpp | 27 +++++++++++++++++++++++++-- src/log/Logger.cpp | 13 +++++++++++-- src/log/Logger.h | 19 +++++++++++++++++++ 4 files changed, 60 insertions(+), 4 deletions(-) diff --git a/include/factory/NacosServiceFactory.h b/include/factory/NacosServiceFactory.h index 7bf380c..9b59e30 100644 --- a/include/factory/NacosServiceFactory.h +++ b/include/factory/NacosServiceFactory.h @@ -6,6 +6,7 @@ #define NACOS_SDK_CPP_NACOSSERVICEFACTORY_H #include "INacosServiceFactory.h" +#include "src/thread/Mutex.h" namespace nacos{ class AppConfigManager; @@ -18,6 +19,10 @@ class NacosServiceFactory : public INacosServiceFactory { bool configIsSet; bool propsIsSet; + Mutex logSysInitLock; + static volatile bool logSystemInitialized; + void initializeRuntimeLogSettings(AppConfigManager *_appConfigManager); + void checkConfig() throw(InvalidFactoryConfigException); AppConfigManager *buildConfigManager(ObjectConfigData *objectConfigData); diff --git a/src/factory/NacosServiceFactory.cpp b/src/factory/NacosServiceFactory.cpp index 7f39553..548d3d6 100644 --- a/src/factory/NacosServiceFactory.cpp +++ b/src/factory/NacosServiceFactory.cpp @@ -24,6 +24,8 @@ //Unlike Java, in cpp, there's no container, no spring to do the ORM job, so I have to handle it myself namespace nacos{ +volatile bool NacosServiceFactory::logSystemInitialized = false; + void buildSecurityManagerAndHttpDelegate(ObjectConfigData *objectConfigData) { AppConfigManager *appConfigManager = objectConfigData->_appConfigManager; if (appConfigManager->nacosAuthEnabled()) { @@ -53,6 +55,24 @@ AppConfigManager *NacosServiceFactory::buildConfigManager(ObjectConfigData *obje return appConfigManager; } +void NacosServiceFactory::initializeRuntimeLogSettings(AppConfigManager *_appConfigManager) { + if (logSystemInitialized) { + return; + } + + { + LockGuard __lockLogSystem(logSysInitLock); + + if (logSystemInitialized) { + return; + } + + logSystemInitialized = true; + Properties copiedProps = _appConfigManager->getAllConfig(); + Logger::applyLogSettings(copiedProps); + } +} + //FIXME:Memory leak at initializing stage, e.g.: //when a HttpDelegate is allocated in CreateConfigService, after that an EXCEPTION is thrown during the initialization of ServerListManager //the resource for HttpDelegate is never released @@ -63,7 +83,8 @@ NamingService *NacosServiceFactory::CreateNamingService() throw(NacosException) objectConfigData->name = "config"; NacosString encoding = "UTF-8"; - buildConfigManager(objectConfigData); + AppConfigManager *appConfigManager = buildConfigManager(objectConfigData); + initializeRuntimeLogSettings(appConfigManager); //Create http client IHttpCli *httpCli= new HTTPCli(); @@ -107,6 +128,7 @@ ConfigService *NacosServiceFactory::CreateConfigService() throw(NacosException) objectConfigData->name = "name"; AppConfigManager *appConfigManager = buildConfigManager(objectConfigData); + initializeRuntimeLogSettings(appConfigManager); //Create http client IHttpCli *httpCli = NULL; @@ -139,7 +161,8 @@ NamingMaintainService *NacosServiceFactory::CreateNamingMaintainService() throw( objectConfigData->name = "config"; NacosString encoding = "UTF-8"; - buildConfigManager(objectConfigData); + AppConfigManager *appConfigManager = buildConfigManager(objectConfigData); + initializeRuntimeLogSettings(appConfigManager); //Create http client IHttpCli *httpCli= new HTTPCli(); diff --git a/src/log/Logger.cpp b/src/log/Logger.cpp index 9a83044..315d8ed 100644 --- a/src/log/Logger.cpp +++ b/src/log/Logger.cpp @@ -148,9 +148,18 @@ void Logger::deInit() { void Logger::initializeLogSystem() { Properties props; - //if we failed to read log settings - props = ConfigParserUtils::parseConfigFile(DirUtils::getCwd() + ConfigConstant::FILE_SEPARATOR + ConfigConstant::DEFAULT_CONFIG_FILE); + try { + props = ConfigParserUtils::parseConfigFile(DirUtils::getCwd() + ConfigConstant::FILE_SEPARATOR + ConfigConstant::DEFAULT_CONFIG_FILE); + } catch (IOException &e) { + //if we failed to read log settings + //use default settings as backup + } + + applyLogSettings(props); +} + +void Logger::applyLogSettings(Properties &props) { if (!props.contains(PropertyKeyConst::LOG_PATH)) { NacosString homedir = DirUtils::getHome(); Logger::setBaseDir(homedir + ConfigConstant::FILE_SEPARATOR + "nacos" + ConfigConstant::FILE_SEPARATOR + "logs"); diff --git a/src/log/Logger.h b/src/log/Logger.h index 184193c..10ec9b5 100644 --- a/src/log/Logger.h +++ b/src/log/Logger.h @@ -5,6 +5,7 @@ #include #include "NacosString.h" #include "src/thread/Mutex.h" +#include "Properties.h" #define DETAILED_DEBUG_INFO @@ -34,6 +35,23 @@ enum LOG_LEVEL { NONE }; +/** + * Logger + * Author: Liu, Hanyu + * This piece of code is a little bit weird, I have to admit + * Actually there are 2 stages which need logging: + * 1. The nacos-client is up but no client service is created, need to log issues when creating client service object + * 2. client service is created, now need to log issue for the client service + * + * stage #1 is called the bootstrap stage + * stage #2 is called the runtime stage + * + * On stage #1, the log will be written to: + * homedir(~)/nacos/logs/nacos-sdk-cpp.log + * + * On stage #2, the path can be configured AT MOST ONCE + * The path will be implicitly configured when the first client service object is created, so if you don't specify it, the default setting(same as #1) will be used + */ class Logger { private: static LOG_LEVEL _CUR_SYS_LOG_LEVEL; @@ -51,6 +69,7 @@ class Logger { public: + static void applyLogSettings(Properties &props); static void setRotateTime(int64_t rotateTime); static void setBaseDir(const NacosString &baseDir); static void setLogLevel(LOG_LEVEL level);