diff --git a/cpp/CHANGELOG.md b/cpp/CHANGELOG.md index c0dedf4aff2b0acee095e967e8d699a9f0c2e3c1..ee089e3dd210d4682406d90ddfd33559709c0a98 100644 --- a/cpp/CHANGELOG.md +++ b/cpp/CHANGELOG.md @@ -31,6 +31,7 @@ Please mark all change in change log and use the ticket from JIRA. - MS-453 - GPU search error when nprobe set more than 1024 - MS-510 - unittest out of memory and crashed - MS-119 - The problem of combining the log files +- MS-121 - The problem that user can't change the time zone ## Improvement - MS-327 - Clean code for milvus diff --git a/cpp/conf/server_config.template b/cpp/conf/server_config.template index ecfcd25f784fd5c7a6dd41344c55819099824038..121d15d1d84bc4ab8a3da8bc1fdc991d9ce45d89 100644 --- a/cpp/conf/server_config.template +++ b/cpp/conf/server_config.template @@ -3,6 +3,7 @@ server_config: port: 19530 # the port milvus listen to, default: 19530, range: 1025 ~ 65534 gpu_index: 0 # the gpu milvus use, default: 0, range: 0 ~ gpu number - 1 mode: single # milvus deployment type: single, cluster, read_only + time_zone: UTC+8 # Use the UTC-x or UTC+x to specify a time zone. eg. UTC+8 for China Standard Time db_config: db_path: @MILVUS_DB_PATH@ # milvus data storage path diff --git a/cpp/src/main.cpp b/cpp/src/main.cpp index ec536c2ee2e0a20dc3c67602466202a38681699b..8590da27be24be5a6de8427d59a643b0dea3eb44 100644 --- a/cpp/src/main.cpp +++ b/cpp/src/main.cpp @@ -16,7 +16,6 @@ #include "utils/SignalUtil.h" #include "utils/CommonUtil.h" -#include "utils/LogUtil.h" INITIALIZE_EASYLOGGINGPP @@ -98,10 +97,8 @@ main(int argc, char *argv[]) { } } - zilliz::milvus::server::InitLog(log_config_file); - server::Server* server_ptr = server::Server::Instance(); - server_ptr->Init(start_daemonized, pid_filename, config_filename); + server_ptr->Init(start_daemonized, pid_filename, config_filename, log_config_file); return server_ptr->Start(); } diff --git a/cpp/src/server/Server.cpp b/cpp/src/server/Server.cpp index 449c2d422df8edfd27a3a7d0421968341a42928a..4a456ff726e9e857ab03728b53c5c0d658033183 100644 --- a/cpp/src/server/Server.cpp +++ b/cpp/src/server/Server.cpp @@ -7,6 +7,7 @@ #include "Server.h" #include "server/grpc_impl/GrpcMilvusServer.h" #include "utils/Log.h" +#include "utils/LogUtil.h" #include "utils/SignalUtil.h" #include "utils/TimeRecorder.h" #include "metrics/Metrics.h" @@ -24,11 +25,12 @@ #include "metrics/Metrics.h" #include "DBWrapper.h" + namespace zilliz { namespace milvus { namespace server { -Server* +Server * Server::Instance() { static Server server; return &server; @@ -42,10 +44,14 @@ Server::~Server() { } void -Server::Init(int64_t daemonized, const std::string& pid_filename, const std::string& config_filename) { +Server::Init(int64_t daemonized, + const std::string &pid_filename, + const std::string &config_filename, + const std::string &log_config_file) { daemonized_ = daemonized; pid_filename_ = pid_filename; config_filename_ = config_filename; + log_config_file_ = log_config_file; } void @@ -54,7 +60,7 @@ Server::Daemonize() { return; } - SERVER_LOG_INFO << "Milvus server run in daemonize mode"; + std::cout << "Milvus server run in daemonize mode"; // std::string log_path(GetLogDirFullPath()); // log_path += "zdb_server.(INFO/WARNNING/ERROR/CRITICAL)"; @@ -101,7 +107,7 @@ Server::Daemonize() { // Change the working directory to root int ret = chdir("/"); - if(ret != 0){ + if (ret != 0) { return; } @@ -110,7 +116,7 @@ Server::Daemonize() { close(fd); } - SERVER_LOG_INFO << "Redirect stdin/stdout/stderr to /dev/null"; + std::cout << "Redirect stdin/stdout/stderr to /dev/null"; // Redirect stdin/stdout/stderr to /dev/null stdin = fopen("/dev/null", "r"); @@ -120,17 +126,17 @@ Server::Daemonize() { if (!pid_filename_.empty()) { pid_fd = open(pid_filename_.c_str(), O_RDWR | O_CREAT, 0640); if (pid_fd < 0) { - SERVER_LOG_INFO << "Can't open filename: " + pid_filename_ + ", Error: " + strerror(errno); + std::cout << "Can't open filename: " + pid_filename_ + ", Error: " + strerror(errno); exit(EXIT_FAILURE); } if (lockf(pid_fd, F_TLOCK, 0) < 0) { - SERVER_LOG_INFO << "Can't lock filename: " + pid_filename_ + ", Error: " + strerror(errno); + std::cout << "Can't lock filename: " + pid_filename_ + ", Error: " + strerror(errno); exit(EXIT_FAILURE); } std::string pid_file_context = std::to_string(getpid()); ssize_t res = write(pid_fd, pid_file_context.c_str(), pid_file_context.size()); - if(res != 0){ + if (res != 0) { return; } } @@ -146,7 +152,7 @@ Server::Start() { do { try { // Read config file - if(LoadConfig() != SERVER_SUCCESS) { + if (LoadConfig() != SERVER_SUCCESS) { return 1; } @@ -154,6 +160,27 @@ Server::Start() { ServerConfig &config = ServerConfig::GetInstance(); ConfigNode server_config = config.GetConfig(CONFIG_SERVER); + std::string time_zone = server_config.GetValue(CONFIG_TIME_ZONE, "UTC+8"); + if (time_zone.length() == 3) { + time_zone = "CUT"; + } else { + int time_bias = std::stoi(time_zone.substr(3, std::string::npos)); + if (time_bias == 0) + time_zone = "CUT"; + else if (time_bias > 0) { + time_zone = "CUT" + std::to_string(-time_bias); + } else { + time_zone = "CUT+" + std::to_string(-time_bias); + } + } + + if (setenv("TZ", time_zone.c_str(), 1) != 0) { + return -1; + } + tzset(); + + InitLog(log_config_file_); + // Handle Signal signal(SIGINT, SignalUtil::HandleSignal); signal(SIGHUP, SignalUtil::HandleSignal); @@ -164,12 +191,12 @@ Server::Start() { std::cout << "Milvus server start successfully." << std::endl; StartService(); - } catch(std::exception& ex){ - SERVER_LOG_ERROR << "Milvus server encounter exception: " << std::string(ex.what()) - << "Is another server instance running?"; + } catch (std::exception &ex) { + std::cerr << "Milvus server encounter exception: " << std::string(ex.what()) + << "Is another server instance running?"; break; } - } while(false); + } while (false); Stop(); return 0; @@ -182,12 +209,12 @@ Server::Stop() { // Unlock and close lockfile if (pid_fd != -1) { int ret = lockf(pid_fd, F_ULOCK, 0); - if(ret != 0){ + if (ret != 0) { std::cout << "Can't lock file: " << strerror(errno) << std::endl; exit(0); } ret = close(pid_fd); - if(ret != 0){ + if (ret != 0) { std::cout << "Can't close file: " << strerror(errno) << std::endl; exit(0); } @@ -196,7 +223,7 @@ Server::Stop() { // Try to delete lockfile if (!pid_filename_.empty()) { int ret = unlink(pid_filename_.c_str()); - if(ret != 0){ + if (ret != 0) { std::cout << "Can't unlink file: " << strerror(errno) << std::endl; exit(0); } @@ -214,7 +241,7 @@ ErrorCode Server::LoadConfig() { ServerConfig::GetInstance().LoadConfigFile(config_filename_); ErrorCode err = ServerConfig::GetInstance().ValidateConfig(); - if(err != SERVER_SUCCESS){ + if (err != SERVER_SUCCESS) { exit(0); } diff --git a/cpp/src/server/Server.h b/cpp/src/server/Server.h index c54f90a1980d2cb735f97f376f2b8dfc2ba9a8cd..c5ea076fb95bd73fae0f3222abef51bddf90a291 100644 --- a/cpp/src/server/Server.h +++ b/cpp/src/server/Server.h @@ -18,7 +18,7 @@ class Server { public: static Server* Instance(); - void Init(int64_t daemonized, const std::string& pid_filename, const std::string& config_filename); + void Init(int64_t daemonized, const std::string& pid_filename, const std::string& config_filename, const std::string &log_config_file); int Start(); void Stop(); @@ -40,6 +40,7 @@ class Server { int pid_fd = -1; std::string pid_filename_; std::string config_filename_; + std::string log_config_file_; }; // Server } // server diff --git a/cpp/src/server/ServerConfig.cpp b/cpp/src/server/ServerConfig.cpp index c506b318919a6f90b6a4018bed56df006598a30d..1e430583662ad985c97b0697949bdc8acac183b5 100644 --- a/cpp/src/server/ServerConfig.cpp +++ b/cpp/src/server/ServerConfig.cpp @@ -15,23 +15,24 @@ #include "utils/CommonUtil.h" #include "utils/ValidationUtil.h" + namespace zilliz { namespace milvus { namespace server { -constexpr uint64_t MB = 1024*1024; -constexpr uint64_t GB = MB*1024; +constexpr uint64_t MB = 1024 * 1024; +constexpr uint64_t GB = MB * 1024; -ServerConfig& +ServerConfig & ServerConfig::GetInstance() { static ServerConfig config; return config; } ErrorCode -ServerConfig::LoadConfigFile(const std::string& config_filename) { +ServerConfig::LoadConfigFile(const std::string &config_filename) { std::string filename = config_filename; - if(filename.empty()){ + if (filename.empty()) { std::cout << "ERROR: a config file is required" << std::endl; exit(1);//directly exit program if config file not specified } @@ -43,14 +44,14 @@ ServerConfig::LoadConfigFile(const std::string& config_filename) { } try { - ConfigMgr* mgr = const_cast(ConfigMgr::GetInstance()); + ConfigMgr *mgr = const_cast(ConfigMgr::GetInstance()); ErrorCode err = mgr->LoadConfigFile(filename); - if(err != 0) { + if (err != 0) { std::cout << "Server failed to load config file" << std::endl; exit(1);//directly exit program if the config file is illegal } } - catch (YAML::Exception& e) { + catch (YAML::Exception &e) { std::cout << "Server failed to load config file: " << std::endl; return SERVER_UNEXPECTED_ERROR; } @@ -104,8 +105,7 @@ ServerConfig::CheckServerConfig() { if (ValidationUtil::ValidateStringIsNumber(port_str) != SERVER_SUCCESS) { std::cerr << "Error: port " << port_str << " is not a number" << std::endl; okay = false; - } - else { + } else { int32_t port = std::stol(port_str); if (port < 1025 | port > 65534) { std::cerr << "Error: port " << port_str << " out of range [1025, 65534]" << std::endl; @@ -117,10 +117,9 @@ ServerConfig::CheckServerConfig() { if (ValidationUtil::ValidateStringIsNumber(gpu_index_str) != SERVER_SUCCESS) { std::cerr << "Error: gpu_index " << gpu_index_str << " is not a number" << std::endl; okay = false; - } - else { + } else { int32_t gpu_index = std::stol(gpu_index_str); - if(ValidationUtil::ValidateGpuIndex(gpu_index) != SERVER_SUCCESS) { + if (ValidationUtil::ValidateGpuIndex(gpu_index) != SERVER_SUCCESS) { std::cerr << "Error: invalid gpu_index " << gpu_index_str << std::endl; okay = false; } @@ -132,6 +131,25 @@ ServerConfig::CheckServerConfig() { okay = false; } + std::string time_zone = server_config.GetValue(CONFIG_TIME_ZONE, "UTC+8"); + int flag = 0; + if(time_zone.length() < 3) + flag = 1; + else if(time_zone.substr(0, 3) != "UTC") + flag = 1; + else if(time_zone.length() > 3){ + try { + stoi(time_zone.substr(3, std::string::npos)); + } + catch (std::invalid_argument &) { + flag = 1; + } + } + if(flag == 1){ + std::cerr << "ERROR: time_zone " << time_zone << " is not in a right format" << std::endl; + okay = false; + } + return (okay ? SERVER_SUCCESS : SERVER_INVALID_ARGUMENT); } @@ -190,13 +208,12 @@ ServerConfig::CheckDBConfig() { if (ValidationUtil::ValidateStringIsNumber(insert_buffer_size_str) != SERVER_SUCCESS) { std::cerr << "Error: insert_buffer_size " << insert_buffer_size_str << " is not a number" << std::endl; okay = false; - } - else { - uint64_t insert_buffer_size = (uint64_t)std::stol(insert_buffer_size_str); + } else { + uint64_t insert_buffer_size = (uint64_t) std::stol(insert_buffer_size_str); insert_buffer_size *= GB; unsigned long total_mem = 0, free_mem = 0; CommonUtil::GetSystemMemInfo(total_mem, free_mem); - if(insert_buffer_size >= total_mem) { + if (insert_buffer_size >= total_mem) { std::cerr << "Error: insert_buffer_size exceed system memory" << std::endl; okay = false; } @@ -254,21 +271,19 @@ ServerConfig::CheckCacheConfig() { if (ValidationUtil::ValidateStringIsNumber(cpu_cache_capacity_str) != SERVER_SUCCESS) { std::cerr << "Error: cpu_cache_capacity " << cpu_cache_capacity_str << " is not a number" << std::endl; okay = false; - } - else { - uint64_t cpu_cache_capacity = (uint64_t)std::stol(cpu_cache_capacity_str); + } else { + uint64_t cpu_cache_capacity = (uint64_t) std::stol(cpu_cache_capacity_str); cpu_cache_capacity *= GB; unsigned long total_mem = 0, free_mem = 0; CommonUtil::GetSystemMemInfo(total_mem, free_mem); if (cpu_cache_capacity >= total_mem) { std::cerr << "Error: cpu_cache_capacity exceed system memory" << std::endl; okay = false; - } - else if(cpu_cache_capacity > (double)total_mem*0.9) { + } else if (cpu_cache_capacity > (double) total_mem * 0.9) { std::cerr << "Warning: cpu_cache_capacity value is too aggressive" << std::endl; } - uint64_t insert_buffer_size = (uint64_t)GetConfig(CONFIG_DB).GetInt32Value(CONFIG_DB_INSERT_BUFFER_SIZE, 4); + uint64_t insert_buffer_size = (uint64_t) GetConfig(CONFIG_DB).GetInt32Value(CONFIG_DB_INSERT_BUFFER_SIZE, 4); insert_buffer_size *= GB; if (insert_buffer_size + cpu_cache_capacity >= total_mem) { std::cerr << "Error: sum of cpu_cache_capacity and insert_buffer_size exceed system memory" << std::endl; @@ -281,8 +296,7 @@ ServerConfig::CheckCacheConfig() { if (ValidationUtil::ValidateStringIsDouble(cpu_cache_free_percent_str, cpu_cache_free_percent) != SERVER_SUCCESS) { std::cerr << "Error: cpu_cache_free_percent " << cpu_cache_free_percent_str << " is not a double" << std::endl; okay = false; - } - else if (cpu_cache_free_percent < std::numeric_limits::epsilon() || cpu_cache_free_percent > 1.0) { + } else if (cpu_cache_free_percent < std::numeric_limits::epsilon() || cpu_cache_free_percent > 1.0) { std::cerr << "Error: invalid cpu_cache_free_percent " << cpu_cache_free_percent_str << std::endl; okay = false; } @@ -297,22 +311,19 @@ ServerConfig::CheckCacheConfig() { if (ValidationUtil::ValidateStringIsNumber(gpu_cache_capacity_str) != SERVER_SUCCESS) { std::cerr << "Error: gpu_cache_capacity " << gpu_cache_capacity_str << " is not a number" << std::endl; okay = false; - } - else { - uint64_t gpu_cache_capacity = (uint64_t)std::stol(gpu_cache_capacity_str); + } else { + uint64_t gpu_cache_capacity = (uint64_t) std::stol(gpu_cache_capacity_str); gpu_cache_capacity *= GB; int gpu_index = GetConfig(CONFIG_SERVER).GetInt32Value(CONFIG_GPU_INDEX, 0); size_t gpu_memory; if (ValidationUtil::GetGpuMemory(gpu_index, gpu_memory) != SERVER_SUCCESS) { std::cerr << "Error: could not get gpu memory for device " << gpu_index << std::endl; okay = false; - } - else if (gpu_cache_capacity >= gpu_memory) { + } else if (gpu_cache_capacity >= gpu_memory) { std::cerr << "Error: gpu_cache_capacity " << gpu_cache_capacity << " exceed total gpu memory " << gpu_memory << std::endl; okay = false; - } - else if(gpu_cache_capacity > (double)gpu_memory*0.9) { + } else if (gpu_cache_capacity > (double) gpu_memory * 0.9) { std::cerr << "Warning: gpu_cache_capacity value is too aggressive" << std::endl; } } @@ -322,8 +333,7 @@ ServerConfig::CheckCacheConfig() { if (ValidationUtil::ValidateStringIsDouble(gpu_cache_free_percent_str, gpu_cache_free_percent) != SERVER_SUCCESS) { std::cerr << "Error: gpu_cache_free_percent " << gpu_cache_free_percent_str << " is not a double" << std::endl; okay = false; - } - else if (gpu_cache_free_percent < std::numeric_limits::epsilon() || gpu_cache_free_percent > 1.0) { + } else if (gpu_cache_free_percent < std::numeric_limits::epsilon() || gpu_cache_free_percent > 1.0) { std::cerr << "Error: invalid gpu_cache_free_percent " << gpu_cache_free_percent << std::endl; okay = false; } @@ -334,8 +344,7 @@ ServerConfig::CheckCacheConfig() { if (ValidationUtil::ValidateStringIsNumber(gpu_id) != SERVER_SUCCESS) { std::cerr << "Error: gpu_id " << gpu_id << " is not a number" << std::endl; okay = false; - } - else if (ValidationUtil::ValidateGpuIndex(std::stol(gpu_id)) != SERVER_SUCCESS) { + } else if (ValidationUtil::ValidateGpuIndex(std::stol(gpu_id)) != SERVER_SUCCESS) { std::cerr << "Error: gpu_id " << gpu_id << " is valid" << std::endl; okay = false; } @@ -364,12 +373,12 @@ ServerConfig::CheckEngineConfig() { if (ValidationUtil::ValidateStringIsNumber(omp_thread_num_str) != SERVER_SUCCESS) { std::cerr << "Error: omp_thread_num " << omp_thread_num_str << " is not a number" << std::endl; okay = false; - } - else { + } else { int32_t omp_thread = std::stol(omp_thread_num_str); uint32_t sys_thread_cnt = 8; - if(omp_thread > CommonUtil::GetSystemAvailableThreads(sys_thread_cnt)) { - std::cerr << "Error: omp_thread_num " << omp_thread_num_str << " > system available thread " << sys_thread_cnt << std::endl; + if (omp_thread > CommonUtil::GetSystemAvailableThreads(sys_thread_cnt)) { + std::cerr << "Error: omp_thread_num " << omp_thread_num_str << " > system available thread " + << sys_thread_cnt << std::endl; okay = false; } } @@ -446,14 +455,13 @@ ServerConfig::CheckResourceConfig() { resource_list.emplace(resource.first); auto &resource_conf = resource.second; auto type = resource_conf.GetValue(CONFIG_RESOURCE_TYPE); - + std::string device_id_str = resource_conf.GetValue(CONFIG_RESOURCE_DEVICE_ID, "0"); int32_t device_id; if (ValidationUtil::ValidateStringIsNumber(device_id_str) != SERVER_SUCCESS) { std::cerr << "Error: device_id " << device_id_str << " is not a number" << std::endl; okay = false; - } - else { + } else { device_id = std::stol(device_id_str); } @@ -465,16 +473,14 @@ ServerConfig::CheckResourceConfig() { if (type == "DISK") { hasDisk = true; - } - else if (type == "CPU") { + } else if (type == "CPU") { hasCPU = true; if (resource_conf.GetBoolValue(CONFIG_RESOURCE_ENABLE_EXECUTOR, false)) { hasExecutor = true; } - } - else if(type == "GPU") { + } else if (type == "GPU") { int build_index_gpu_index = GetConfig(CONFIG_SERVER).GetInt32Value(CONFIG_GPU_INDEX, 0); - if(device_id == build_index_gpu_index) { + if (device_id == build_index_gpu_index) { resource_valid_flag = true; } if (resource_conf.GetBoolValue(CONFIG_RESOURCE_ENABLE_EXECUTOR, false)) { @@ -498,7 +504,7 @@ ServerConfig::CheckResourceConfig() { } } - if(!resource_valid_flag) { + if (!resource_valid_flag) { std::cerr << "Building index GPU can't be found in resource config." << std::endl; okay = false; } @@ -510,7 +516,7 @@ ServerConfig::CheckResourceConfig() { std::cerr << "No CPU or GPU resource has executor enabled" << std::endl; okay = false; } - + auto connections = resource_config.GetChild(CONFIG_RESOURCE_CONNECTIONS).GetChildren(); for (auto &connection : connections) { auto &connection_conf = connection.second; @@ -527,8 +533,7 @@ ServerConfig::CheckResourceConfig() { if (delimiter_pos == std::string::npos) { std::cerr << "Error: invalid endpoint format: " << endpoint_str << std::endl; okay = false; - } - else { + } else { std::string left_resource = endpoint_str.substr(0, delimiter_pos); if (resource_list.find(left_resource) == resource_list.end()) { std::cerr << "Error: left resource " << left_resource << " does not exist" << std::endl; @@ -547,7 +552,7 @@ ServerConfig::CheckResourceConfig() { void ServerConfig::PrintAll() const { - if(const ConfigMgr* mgr = ConfigMgr::GetInstance()) { + if (const ConfigMgr *mgr = ConfigMgr::GetInstance()) { std::string str = mgr->DumpString(); // SERVER_LOG_INFO << "\n" << str; std::cout << "\n" << str << std::endl; @@ -555,16 +560,16 @@ ServerConfig::PrintAll() const { } ConfigNode -ServerConfig::GetConfig(const std::string& name) const { - const ConfigMgr* mgr = ConfigMgr::GetInstance(); - const ConfigNode& root_node = mgr->GetRootNode(); +ServerConfig::GetConfig(const std::string &name) const { + const ConfigMgr *mgr = ConfigMgr::GetInstance(); + const ConfigNode &root_node = mgr->GetRootNode(); return root_node.GetChild(name); } -ConfigNode& -ServerConfig::GetConfig(const std::string& name) { - ConfigMgr* mgr = ConfigMgr::GetInstance(); - ConfigNode& root_node = mgr->GetRootNode(); +ConfigNode & +ServerConfig::GetConfig(const std::string &name) { + ConfigMgr *mgr = ConfigMgr::GetInstance(); + ConfigNode &root_node = mgr->GetRootNode(); return root_node.GetChild(name); } diff --git a/cpp/src/server/ServerConfig.h b/cpp/src/server/ServerConfig.h index de7c719d98c15f12fba2d44ad95597d5368c5925..b49d788ba942c87c52fcb570ec711d6f6627c99c 100644 --- a/cpp/src/server/ServerConfig.h +++ b/cpp/src/server/ServerConfig.h @@ -19,6 +19,7 @@ static const char* CONFIG_SERVER_ADDRESS = "address"; static const char* CONFIG_SERVER_PORT = "port"; static const char* CONFIG_CLUSTER_MODE = "mode"; static const char* CONFIG_GPU_INDEX = "gpu_index"; +static const char* CONFIG_TIME_ZONE = "time_zone"; static const char* CONFIG_DB = "db_config"; static const char* CONFIG_DB_URL = "db_backend_url";