#include "precompile.h" #include "StartUpBase.h" #include #include #include #include #include #include "log_define.h" #include #include #include class StartupLog { public: struct Step { std::string timestamp; std::string event; std::string status; int from; int to; int result; Step(const std::string& ts, const std::string& ev, const std::string t_status, int t_from, int t_to, int t_result) : timestamp(ts), event(ev), status(t_status), from(t_from), to(t_to), result(t_result) {} }; StartupLog(); StartupLog(const std::string& module_entity, int req_id = -1); ~StartupLog(); void initialize(int req_id, const std::string& module_entity); void addStep(const Step& step); std::string toJSON() const; private: int request_id; std::string module_entity_; std::vector steps_; }; class StartupLogManager { public: static StartupLogManager& getInstance(); //StartupLogManager::getInstance().addLog(entityName, entity_id); void addLog(const std::string& module_entity, int idx); // 新增 addLog 方法 bool checkLogExist(int idx); StartupLog& getLog(int idx); /* StartupLogManager::getInstance().addStep(entityName, { GetCurrentTimeStr(), "handle_req" }); */ void addStep(int idx, const StartupLog::Step& step); void removeLog(int idx); private: StartupLogManager(); ~StartupLogManager(); std::map logs_; std::chrono::steady_clock::time_point m_lastUpdateTime; void recordStartTime() { m_lastUpdateTime = std::chrono::steady_clock::now(); } bool isTimeExceeded() { auto current_time = std::chrono::steady_clock::now(); auto duration = std::chrono::duration_cast(current_time - m_lastUpdateTime); return duration.count() >= 2; } }; std::string GetCurrentTimeStr(); SPBASE_API int addStartupLog(const char* module_entity, int idx) { StartupLogManager::getInstance().addLog(module_entity, idx); return 0; } SPBASE_API int addStartupStep(int idx, const char* event, const char* status, int from, int to, int result) { StartupLogManager::getInstance().addStep(idx, StartupLog::Step(GetCurrentTimeStr(), std::string(event), std::string(status), from, to, result)); return 0; } std::string GetCurrentTimeStr() { char unitedNowTime[30] = ""; SYSTEMTIME st; FILETIME utc_ft, local_ft, ft; #ifdef _WIN32 GetSystemTime(&st); SystemTimeToFileTime(&st, &ft); utc_ft.dwLowDateTime = (DWORD)ft.dwLowDateTime; utc_ft.dwHighDateTime = (DWORD)ft.dwHighDateTime; FileTimeToLocalFileTime(&utc_ft, &local_ft); FileTimeToSystemTime(&local_ft, &st); #else GetLocalTime(&st); #endif // _WIN32 sprintf(unitedNowTime, "%02d:%02d:%02d.%03d", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); return std::string(unitedNowTime); } StartupLog::StartupLog() : request_id(0) {} StartupLog::~StartupLog() {} void StartupLog::initialize(int req_id, const std::string& module_entity) { request_id = req_id; module_entity_ = module_entity; } StartupLog::StartupLog(const std::string& module_entity, int req_id) { module_entity_ = module_entity; request_id = req_id; } void StartupLog::addStep(const Step& step) { steps_.push_back(step); } std::string StartupLog::toJSON() const { Json::Value root; root["event"] = "entity_startup"; root["request_id"] = request_id; root["module_entity"] = module_entity_; Json::Value steps_array(Json::arrayValue); for (const auto& step : steps_) { Json::Value step_obj; step_obj["timestamp"] = step.timestamp; step_obj["event"] = step.event; if (!step.status.empty()) { step_obj["status"] = step.status; } if (step.from != 0 && step.to != 0) { step_obj["from"] = step.from; step_obj["to"] = step.to; } if (step.result != 0) { step_obj["result"] = step.result; } steps_array.append(step_obj); } root["steps"] = steps_array; Json::FastWriter writer; std::string jsonReq = writer.write(root); return jsonReq; } StartupLogManager::StartupLogManager() { static std::thread checkTimeThread; recordStartTime(); auto checkStartupEnd = [this] { while (true) { std::this_thread::sleep_for(std::chrono::seconds(5)); if (isTimeExceeded()) { for (auto current : logs_) { std::string resultMsg = current.second.toJSON(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)(resultMsg.c_str()); } logs_.clear(); break; } } }; if (!checkTimeThread.joinable()) { checkTimeThread = std::thread(checkStartupEnd); } } StartupLogManager::~StartupLogManager() {} void StartupLogManager::addLog(const std::string& module_entity, int idx) { recordStartTime(); if (logs_.find(idx) == logs_.end()) { logs_[idx] = StartupLog(module_entity, idx); // 直接拷贝 log 对象 } // 如果已存在,则忽略 } StartupLog& StartupLogManager::getLog(int idx) { if (logs_.find(idx) == logs_.end()) { logs_[idx] = StartupLog("", idx); // 仍然保留隐式创建的逻辑,方便使用 } return logs_[idx]; } bool StartupLogManager::checkLogExist(int idx) { if (logs_.find(idx) == logs_.end()) return false; else return true; } void StartupLogManager::addStep(int idx, const StartupLog::Step& step) { recordStartTime(); if (checkLogExist(idx)) { StartupLog ¤t = getLog(idx); current.addStep(step); if (step.result != 0 || step.status == "startup_end") {//print the logs and remove obj std::string resultMsg = current.toJSON(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)(resultMsg.c_str()); removeLog(idx); } } } void StartupLogManager::removeLog(int idx) { if (logs_.find(idx) == logs_.end()) logs_.erase(idx); } StartupLogManager& StartupLogManager::getInstance() { static StartupLogManager instance; return instance; }