StartUpBase.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. #include "precompile.h"
  2. #include "StartUpBase.h"
  3. #include <json/json.h>
  4. #include <winpr/sysinfo.h>
  5. #include <string>
  6. #include <vector>
  7. #include <map>
  8. #include "log_define.h"
  9. #include <SpBase.h>
  10. #include <chrono>
  11. #include <thread>
  12. class StartupLog {
  13. public:
  14. struct Step {
  15. std::string timestamp;
  16. std::string event;
  17. std::string status;
  18. int from;
  19. int to;
  20. int result;
  21. Step(const std::string& ts, const std::string& ev, const std::string t_status, int t_from, int t_to, int t_result)
  22. : timestamp(ts), event(ev), status(t_status), from(t_from), to(t_to), result(t_result) {}
  23. };
  24. StartupLog();
  25. StartupLog(const std::string& module_entity, int req_id = -1);
  26. ~StartupLog();
  27. void initialize(int req_id, const std::string& module_entity);
  28. void addStep(const Step& step);
  29. std::string toJSON() const;
  30. private:
  31. int request_id;
  32. std::string module_entity_;
  33. std::vector<Step> steps_;
  34. };
  35. class StartupLogManager {
  36. public:
  37. static StartupLogManager& getInstance();
  38. //StartupLogManager::getInstance().addLog(entityName, entity_id);
  39. void addLog(const std::string& module_entity, int idx); // 新增 addLog 方法
  40. bool checkLogExist(int idx);
  41. StartupLog& getLog(int idx);
  42. /*
  43. StartupLogManager::getInstance().addStep(entityName, { GetCurrentTimeStr(), "handle_req" });
  44. */
  45. void addStep(int idx, const StartupLog::Step& step);
  46. void removeLog(int idx);
  47. private:
  48. StartupLogManager();
  49. ~StartupLogManager();
  50. std::map<int, StartupLog> logs_;
  51. std::chrono::steady_clock::time_point m_lastUpdateTime;
  52. void recordStartTime() {
  53. m_lastUpdateTime = std::chrono::steady_clock::now();
  54. }
  55. bool isTimeExceeded() {
  56. auto current_time = std::chrono::steady_clock::now();
  57. auto duration = std::chrono::duration_cast<std::chrono::minutes>(current_time - m_lastUpdateTime);
  58. return duration.count() >= 2;
  59. }
  60. };
  61. std::string GetCurrentTimeStr();
  62. SPBASE_API int addStartupLog(const char* module_entity, int idx)
  63. {
  64. StartupLogManager::getInstance().addLog(module_entity, idx);
  65. return 0;
  66. }
  67. SPBASE_API int addStartupStep(int idx, const char* event, const char* status, int from, int to, int result)
  68. {
  69. StartupLogManager::getInstance().addStep(idx, StartupLog::Step(GetCurrentTimeStr(), std::string(event), std::string(status), from, to, result));
  70. return 0;
  71. }
  72. std::string GetCurrentTimeStr()
  73. {
  74. char unitedNowTime[30] = "";
  75. SYSTEMTIME st;
  76. FILETIME utc_ft, local_ft, ft;
  77. #ifdef _WIN32
  78. GetSystemTime(&st);
  79. SystemTimeToFileTime(&st, &ft);
  80. utc_ft.dwLowDateTime = (DWORD)ft.dwLowDateTime;
  81. utc_ft.dwHighDateTime = (DWORD)ft.dwHighDateTime;
  82. FileTimeToLocalFileTime(&utc_ft, &local_ft);
  83. FileTimeToSystemTime(&local_ft, &st);
  84. #else
  85. GetLocalTime(&st);
  86. #endif // _WIN32
  87. sprintf(unitedNowTime, "%02d:%02d:%02d.%03d",
  88. st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
  89. return std::string(unitedNowTime);
  90. }
  91. StartupLog::StartupLog() : request_id(0) {}
  92. StartupLog::~StartupLog() {}
  93. void StartupLog::initialize(int req_id, const std::string& module_entity) {
  94. request_id = req_id;
  95. module_entity_ = module_entity;
  96. }
  97. StartupLog::StartupLog(const std::string& module_entity, int req_id)
  98. {
  99. module_entity_ = module_entity;
  100. request_id = req_id;
  101. }
  102. void StartupLog::addStep(const Step& step) {
  103. steps_.push_back(step);
  104. }
  105. std::string StartupLog::toJSON() const {
  106. Json::Value root;
  107. root["event"] = "entity_startup";
  108. root["request_id"] = request_id;
  109. root["module_entity"] = module_entity_;
  110. Json::Value steps_array(Json::arrayValue);
  111. for (const auto& step : steps_) {
  112. Json::Value step_obj;
  113. step_obj["timestamp"] = step.timestamp;
  114. step_obj["event"] = step.event;
  115. if (!step.status.empty()) {
  116. step_obj["status"] = step.status;
  117. }
  118. if (step.from != 0 && step.to != 0) {
  119. step_obj["from"] = step.from;
  120. step_obj["to"] = step.to;
  121. }
  122. if (step.result != 0) {
  123. step_obj["result"] = step.result;
  124. }
  125. steps_array.append(step_obj);
  126. }
  127. root["steps"] = steps_array;
  128. Json::FastWriter writer;
  129. std::string jsonReq = writer.write(root);
  130. return jsonReq;
  131. }
  132. StartupLogManager::StartupLogManager()
  133. {
  134. static std::thread checkTimeThread;
  135. recordStartTime();
  136. auto checkStartupEnd = [this] {
  137. while (true)
  138. {
  139. std::this_thread::sleep_for(std::chrono::seconds(5));
  140. if (isTimeExceeded())
  141. {
  142. for (auto current : logs_)
  143. {
  144. std::string resultMsg = current.second.toJSON();
  145. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)(resultMsg.c_str());
  146. }
  147. logs_.clear();
  148. break;
  149. }
  150. }
  151. };
  152. if (!checkTimeThread.joinable()) {
  153. checkTimeThread = std::thread(checkStartupEnd);
  154. }
  155. }
  156. StartupLogManager::~StartupLogManager() {}
  157. void StartupLogManager::addLog(const std::string& module_entity, int idx) {
  158. recordStartTime();
  159. if (logs_.find(idx) == logs_.end()) {
  160. logs_[idx] = StartupLog(module_entity, idx); // 直接拷贝 log 对象
  161. } // 如果已存在,则忽略
  162. }
  163. StartupLog& StartupLogManager::getLog(int idx) {
  164. if (logs_.find(idx) == logs_.end()) {
  165. logs_[idx] = StartupLog("", idx); // 仍然保留隐式创建的逻辑,方便使用
  166. }
  167. return logs_[idx];
  168. }
  169. bool StartupLogManager::checkLogExist(int idx)
  170. {
  171. if (logs_.find(idx) == logs_.end())
  172. return false;
  173. else
  174. return true;
  175. }
  176. void StartupLogManager::addStep(int idx, const StartupLog::Step& step) {
  177. recordStartTime();
  178. if (checkLogExist(idx))
  179. {
  180. StartupLog &current = getLog(idx);
  181. current.addStep(step);
  182. if (step.result != 0 || step.status == "startup_end")
  183. {//print the logs and remove obj
  184. std::string resultMsg = current.toJSON();
  185. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)(resultMsg.c_str());
  186. removeLog(idx);
  187. }
  188. }
  189. }
  190. void StartupLogManager::removeLog(int idx)
  191. {
  192. if (logs_.find(idx) == logs_.end())
  193. logs_.erase(idx);
  194. }
  195. StartupLogManager& StartupLogManager::getInstance() {
  196. static StartupLogManager instance;
  197. return instance;
  198. }