log.cpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. #include "precompile.h"
  2. #include "SpBase.h"
  3. #include "log.h"
  4. #include "app.h"
  5. #include "sp_log.h"
  6. #include "sp_svc.h"
  7. #include "sp_iom.h"
  8. #include "sp_cfg.h"
  9. #include "sp_env.h"
  10. #include "fileutil.h"
  11. #include "strutil.h"
  12. #include "dbgutil.h"
  13. #include <winpr/file.h>
  14. #ifdef _WIN32
  15. #include "SpShellConsole.h"
  16. #endif //_WIN32
  17. #define MAX_LOGFILE_SIZE (1<<20)
  18. typedef struct log_t {
  19. SYSTEMTIME tm_start;
  20. FILE *fp;
  21. int file_seq;// non-zero when file is already exist
  22. int last_error;
  23. sp_log_daemon_t *log_daemon;
  24. }log_t;
  25. static const char *str_types[] = {
  26. "Nil",
  27. "Evt",
  28. "Wrn",
  29. "Err",
  30. "Dbg",
  31. };
  32. static const char *str_severity[] = {
  33. "Nil",
  34. "low",
  35. "mid",
  36. "hgh",
  37. };
  38. static BOOL __log_need_change(log_t *log, LPSYSTEMTIME now)
  39. {
  40. TOOLKIT_ASSERT(now);
  41. /* if error occurs, may be Hard Disk broken or space is run out. so no need to change file */
  42. if (log->last_error)
  43. return FALSE;
  44. /* fp currently is null, when system start */
  45. if (!log->fp)
  46. return TRUE;
  47. /* a new day come */
  48. if (log->tm_start.wYear != now->wYear ||
  49. log->tm_start.wMonth != now->wMonth ||
  50. log->tm_start.wDay != now->wDay)
  51. return TRUE;
  52. /* file size has exceed MAX_LOGFILE_SIZE */
  53. if (ftell(log->fp) > MAX_LOGFILE_SIZE) {
  54. return TRUE;
  55. }
  56. /* 10 minutes pass */
  57. {
  58. int diff = (now->wHour - log->tm_start.wHour) * 3600;
  59. diff += (now->wMinute - log->tm_start.wMinute) * 60;
  60. diff += (now->wSecond - log->tm_start.wSecond);
  61. if (diff >= 600) {
  62. return TRUE;
  63. }
  64. }
  65. return FALSE;
  66. }
  67. static const char *get_temp_path(char *buf, LPSYSTEMTIME now, int seq)
  68. {
  69. sp_env_t *env = sp_get_env();
  70. sp_cfg_t *cfg = env->cfg;
  71. sp_cfg_root_ini_t *root_cfg = cfg->root_ini;
  72. const char *dir = root_cfg->ref_syslog_path;
  73. if (dir != NULL && strlen(dir) > 0) {
  74. if (seq) {
  75. sprintf(buf, "%s" SPLIT_SLASH_STR "%08X_%02d-%02d-%02d_%02d-%02d-%02d(%03d)", dir,
  76. cfg->install_ini->current_startup_time,
  77. now->wYear, now->wMonth, now->wDay,
  78. now->wHour, now->wMinute, now->wSecond, seq % 1000);
  79. } else {
  80. sprintf(buf, "%s" SPLIT_SLASH_STR "%08X_%02d-%02d-%02d_%02d-%02d-%02d", dir,
  81. cfg->install_ini->current_startup_time,
  82. now->wYear, now->wMonth, now->wDay,
  83. now->wHour, now->wMinute, now->wSecond);
  84. }
  85. }
  86. return buf;
  87. }
  88. static const char *new_tmp_path(char *buf, LPSYSTEMTIME now, int *file_seq)
  89. {
  90. int seq = 0;
  91. int i;
  92. const int max_tries = 1000;
  93. for (i = 0; i < max_tries; ++i) {
  94. get_temp_path(buf, now, seq);
  95. strcat(buf, ".xml");
  96. if (ExistsFileA(buf)) {
  97. seq++;
  98. } else {
  99. break;
  100. }
  101. }
  102. if (i == max_tries) {
  103. return NULL;
  104. }
  105. //buf[strlen(buf) - 4] = 0;
  106. *file_seq = seq;
  107. return buf;
  108. }
  109. static BOOL rename_file1(LPSYSTEMTIME tm_start, int file_seq)
  110. {
  111. char x[MAX_PATH];
  112. char y[MAX_PATH];
  113. get_temp_path(x, tm_start, file_seq);
  114. strcpy(y, x);
  115. strcat(y, ".xml");
  116. return MoveFileExA(x, y, MOVEFILE_REPLACE_EXISTING);
  117. }
  118. static void __log_change_file(log_t *log, LPSYSTEMTIME now)
  119. {
  120. char tmp[MAX_PATH];
  121. if (log->fp) {
  122. fflush(log->fp);
  123. fclose(log->fp);
  124. log->fp = NULL;
  125. }
  126. if (!new_tmp_path(tmp, now, &log->file_seq)) {
  127. log->last_error = -1;
  128. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("cannot create log tmp file");
  129. return;
  130. }
  131. log->fp = fopen(tmp, "wb");
  132. if (!log->fp) {
  133. log->last_error = -1;
  134. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("cannot fopen log tmp file %s", tmp);
  135. return;
  136. } else {
  137. memcpy(&log->tm_start, now, sizeof(SYSTEMTIME));
  138. }
  139. }
  140. static void __log_write_record(log_t *log,
  141. u__int64_t log_id,
  142. LPSYSTEMTIME tm,
  143. int log_type,
  144. u__int64_t prev_rsn,
  145. u__int64_t curr_rsn,
  146. int original_rsn_type,
  147. int rsn_depth,
  148. int log_severity,
  149. int log_sys_error,
  150. int log_usr_error,
  151. const char *module,
  152. const char *entity,
  153. const char *msg)
  154. {
  155. int n;
  156. n = fprintf(log->fp,
  157. //"<Log SN=\"0x%llX\" Time=\"%02d:%02d:%02d\" LogType=\"%d\" CRS=\"0x%llX\" LRS=\"0x%llX\" ORS=\"0x%X\" RunCount=\"%d\" SeverityLevel=\"%d\" SysCode=\"0x%X\" UserCode=\"0x%X\" SpName=\"%s\" Entity=\"%s\">%s</Log>\r\n",
  158. "<Log SN=\"0x%llX\" Time=\"%02d:%02d:%02d\" LogType=\"%d\" SeverityLevel=\"%d\" SysCode=\"0x%X\" UserCode=\"0x%X\" SpName=\"%s\" Entity=\"%s\">%s</Log>\r\n",
  159. log_id,
  160. tm->wHour, tm->wMinute, tm->wSecond,
  161. log_type,
  162. /*curr_rsn,
  163. prev_rsn,
  164. original_rsn_type,
  165. rsn_depth, */
  166. log_severity,
  167. log_sys_error,
  168. log_usr_error,
  169. module,
  170. entity,
  171. msg);
  172. if (n < 0) {
  173. log->last_error = -1;
  174. fclose(log->fp);
  175. log->fp = NULL;
  176. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("write log record failed!");
  177. }
  178. }
  179. static void on_log(void *inst,
  180. int nsub,
  181. u__int64_t *sub,
  182. int client_id,
  183. int log_epid,
  184. int client_instance_id,
  185. u__int64_t log_id,
  186. u__int64_t prev_rsn,
  187. u__int64_t curr_rsn,
  188. int original_rsn_type,
  189. int rsn_depth,
  190. unsigned int log_time,
  191. int log_type,
  192. int log_severity,
  193. int log_sys_error,
  194. int log_usr_error,
  195. int param_cnt,
  196. int *params,
  197. const char *msg,
  198. void *user_data,
  199. const char* bussId, const char* traceId, const char* spanId, const char* parentSpanId)
  200. {
  201. sp_env_t *env = sp_get_env();
  202. sp_cfg_t *cfg = env->cfg;
  203. sp_cfg_shell_entity_t *ent = sp_cfg_get_entity_by_idx(cfg, client_id);
  204. sp_cfg_shell_module_t *mod = ent ? ent->mod : sp_cfg_get_module_by_idx(cfg, log_epid);
  205. log_t *log = (log_t*)user_data;
  206. app_t *app = get_app_instance();
  207. if (cfg == NULL || ent == NULL || mod == NULL || log == NULL || app == NULL)
  208. return;
  209. #ifdef RVC_OS_WIN
  210. // 在调试控制台显示已订阅实体日志
  211. if (app->pConsole != NULL && app->pConsole->HasSubLogCnn()) {
  212. app->pConsole->OutputLog(client_id, ent->name, msg);
  213. }
  214. #endif //RVC_OS_WIN
  215. if(app->bsc_gui != NULL) {
  216. CSimpleStringA msgContent(true);
  217. int notifyType = 0;
  218. const bool needTosendNormal = (ent->debug_level > 0);
  219. if (log_type == 1 && needTosendNormal) { // Log_Event
  220. notifyType = GUI_DISPLAY_ELEM_LOG_EVENT;
  221. msgContent = CSimpleStringA::Format("[%s] I:{%s}(uc:0x%X)", ent->name, msg, log_usr_error);
  222. }
  223. else if (log_type == 2 && (needTosendNormal || log_severity == 3 /*Severity_High*/)) { //Log_Warning
  224. notifyType = GUI_DISPLAY_ELEM_LOG_WARN;
  225. msgContent = CSimpleString::Format("[%s] W:{%s}(sc:0x%X, uc:0x%X)", ent->name, msg, log_sys_error, log_usr_error);
  226. }
  227. else if (log_type == 3) {// Log_Error
  228. notifyType = GUI_DISPLAY_ELEM_LOG_ERROR;
  229. msgContent = CSimpleString::Format("[%s] E:{%s}(sc:0x%X, uc:0x%X)", ent->name, msg, log_sys_error, log_usr_error);
  230. }
  231. else if ((log_type == 4 || log_type == 0) && needTosendNormal) {// Log_Debug
  232. notifyType = GUI_DISPLAY_ELEM_LOG_DEBUG;
  233. msgContent = CSimpleString::Format("[%s] D:{%s}", ent->name, msg);
  234. }
  235. else if (log_type == 5) {// Log_Fatal
  236. notifyType = GUI_DISPLAY_ELEM_LOG_FATAL;
  237. msgContent = CSimpleString::Format("[%s] F:{%s}(sc:0x%X, uc:0x%X)", ent->name, msg, log_sys_error, log_usr_error);
  238. }
  239. else if (log_type == 6) {//Log_Notify
  240. notifyType = GUI_DISPLAY_ELEM_NOTIFY_INFO;
  241. if (log_severity == 2) {//Notify_Warn
  242. notifyType = GUI_DISPLAY_ELEM_NOTIFY_WARN;
  243. } else if (log_severity == 3) {
  244. notifyType = GUI_DISPLAY_ELEM_NOTIFY_ERROR;
  245. }
  246. #if defined(_MSC_VER)
  247. msgContent = CSimpleString::Format("[%s] N:{%s}(sc:0x%X, uc:0x%X)", ent->name, msg, log_sys_error, log_usr_error);
  248. #else
  249. CSimpleStringA strMsg = CSimpleStringA::Format("%s V%d.%d.%d", ent->name, ent->version.major, ent->version.minor, ent->version.revision);
  250. strMsg += ":][:"; /** arrange with QtGUIConsole to split entity name and msg content [Gifur@202133]*/
  251. msgContent = CSimpleString::Format("%s%s", strMsg.GetData(), msg);
  252. #endif //_MSC_VER
  253. }
  254. if (notifyType != 0) {
  255. #if defined(_MSC_VER)
  256. sp_gui_show_running_info(app->bsc_gui, msgContent, notifyType);
  257. #else
  258. app->bsc_gui->show_running_info(app->bsc_gui->gui_inst, msgContent, notifyType);
  259. #endif //_MSC_VER
  260. }
  261. }
  262. /** 不打印SystemLog [Gifur@2022516]*/
  263. //SYSTEMTIME st;
  264. //y2k_to_localtime(log_time, &st);
  265. //if (__log_need_change(log, &st)) {
  266. // __log_change_file(log, &st);
  267. //}
  268. //if (!log->last_error && log->fp) {
  269. // LARGE_INTEGER t;
  270. // char *escape = str_xml_escape(msg);
  271. // t.QuadPart = log_id;
  272. // __log_write_record(log,
  273. // log_id, &st, log_type,
  274. // prev_rsn, curr_rsn, original_rsn_type, rsn_depth,
  275. // log_severity, log_sys_error, log_usr_error,
  276. // mod->name, ent ? ent->name : "$Anonymous$", escape);
  277. // FREE(escape);
  278. //}
  279. }
  280. // user send flush command
  281. static void on_flush(void *inst,
  282. int client_id,
  283. LPSYSTEMTIME lst,
  284. void *user_data)
  285. {
  286. log_t *log = (log_t*)user_data;
  287. if (log->fp) {
  288. fflush(log->fp);
  289. /*fclose(log->fp);
  290. log->fp = NULL;*/
  291. }
  292. }
  293. static void on_timeout_interval(void *inst, LPSYSTEMTIME lst, void *user_data)
  294. {
  295. /** 不打印SystemLog [Gifur@2022516]*/
  296. //log_t *log = (log_t*)user_data;
  297. //if (log->fp) {
  298. // if (__log_need_change(log, lst)) {
  299. // fclose(log->fp);
  300. // log->fp = NULL;
  301. // } else {
  302. // fflush(log->fp);
  303. // }
  304. //}
  305. }
  306. int log_create(sp_svc_t *svc, log_t **p_log)
  307. {
  308. log_t *log = ZALLOC_T(log_t);
  309. sp_env_t *env = sp_get_env();
  310. sp_cfg_t *cfg = env->cfg;
  311. sp_cfg_root_ini_t *root_cfg = cfg->root_ini;
  312. //const char *dir = root_cfg->ref_syslog_path;
  313. int rc;
  314. rc = sp_log_daemon_create(&on_log, &on_flush, &on_timeout_interval, log, svc, &log->log_daemon);
  315. if (rc == 0) {
  316. *p_log = log;
  317. } else {
  318. free(log);
  319. }
  320. return rc;
  321. }
  322. int log_destroy(log_t *log)
  323. {
  324. int rc;
  325. rc = sp_log_daemon_destroy(log->log_daemon);
  326. if (rc == 0) {
  327. if (log->fp) {
  328. fflush(log->fp);
  329. fclose(log->fp);
  330. log->fp = NULL;
  331. }
  332. free(log);
  333. }
  334. return 0;
  335. }