sp_logwithlink.cpp 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018
  1. #include "precompile.h"
  2. #include "SpBase.h"
  3. #include "SpUtility.h"
  4. #include "sp_checkEntity.h"
  5. #include "log_api.h"
  6. #include "log_producer_config.h"
  7. #include "log_producer_client.h"
  8. #include <cstdarg>
  9. #include <map>
  10. #include "sp_def.h"
  11. #include "sp_dir.h"
  12. #include "sp_logwithlinkforc.h"
  13. #include "sp_logwithlink.h"
  14. #include "sp_dbg_export.h"
  15. #include "fileutil.h"
  16. #include "iniutil.h"
  17. #include "charset.h"
  18. #include <vector>
  19. #include <algorithm>
  20. #include "sp_cfg.h"
  21. #include "sp_env.h"
  22. #include <locale>
  23. #include <winpr/file.h>
  24. #include <winpr/wlog.h>
  25. #include "sp_httpDefine.h"
  26. #include <fstream>
  27. #include <iostream>
  28. #include "SpDefine.h"
  29. #include <mutex>
  30. #define TAG SPBASE_TAG("sp_logwithlink")
  31. void* g_logProducer = NULL;//为spshell、spbase共用,所以不放入getEntityResource中
  32. //#define MAX_LOG_LEN 9700 //大致为10 * 1024 - 400(固定头)
  33. #define MAX_LOG_LEN 1900
  34. #define MAX_ENTITY_SAVE_LEN 100
  35. int g_curEntityIdx = 0;
  36. std::map<std::string, int> g_entityDebugLevelArr;
  37. void* g_logProduceSender = NULL;
  38. int curEntityLogLevel = 1;
  39. int g_spbaseLogNor = 1;
  40. std::mutex g_logMtx;
  41. void Log_GetToken(char* channelId, char* token, char *terminalno, char *reserve1) {
  42. sp_env_t* env = sp_get_env();
  43. if (NULL != env && NULL != env->cfg && NULL != env->cfg->shell_ini && env->cfg->shell_ini->channelId != NULL && env->cfg->shell_ini->token != NULL
  44. && NULL != env->cfg->root_ini && NULL != env->cfg->root_ini->terminal_no)
  45. {
  46. snprintf(channelId, 256, "%s", env->cfg->shell_ini->channelId);
  47. snprintf(token, 256, "%s", env->cfg->shell_ini->token);
  48. snprintf(terminalno, 256, "%s", env->cfg->root_ini->terminal_no);
  49. }
  50. }
  51. /*天眼日志实例
  52. {
  53. "appName": "LR04",
  54. "version": "1.0",
  55. "meta_log": {
  56. "baseLogType": "INFO",
  57. "uuid": "ba814f0b-31e3-42ed-bf45-a36e9eb5c1f0",
  58. "needArchived": false
  59. },
  60. "log": {
  61. "type": "SYSTEM_INFO",
  62. "ts": "2023-04-03T12:57:49.000000000Z",
  63. "deployUnitId": "LR04.02@FrameworkLib_PRD_PRD",
  64. "serviceUnitId": "LR04.02_FrameworkLib",
  65. "content": {
  66. "ServName": "Terminal",
  67. "CmptId": "LR04",
  68. "CmptName": "FrameworkLib",
  69. "LogFile": "SI",
  70. "EvenTime": "2023-04-03 12:57:49.000",
  71. "ClientIP": "99.6.149.222",
  72. "Version": "1.0",
  73. "DateTime": "2023-04-03 12:57:49.000",
  74. "ResultCode": "SUC0000",
  75. "LogCode": "",
  76. "API": "",
  77. "TipMsg": "",
  78. "BussID": "",
  79. "SourceType": "",
  80. "ResultMsg": "entity UpgradeManager,cpu ratio:2.031250",
  81. "TraceID": "",
  82. "Item": "52",
  83. "EntityName": "mod_selfchecker",
  84. "LifeID": 331,
  85. "TimeSn": 178,
  86. "TerminalNo": "5710010002",
  87. "SN": "5710010002"
  88. }
  89. }
  90. }
  91. */
  92. //#define GBK_COMPACT
  93. class DbgWithLink::Link_private {
  94. public:
  95. LOG_LEVEL_E Level;
  96. LOG_TYPE_E Type;
  97. CSimpleStringA ResultCode;
  98. CSimpleStringA TraceID;
  99. CSimpleStringA ResultMsg;
  100. CSimpleStringA LogCode;
  101. CSimpleStringA API;
  102. long BeginTime;
  103. long EndTime;
  104. long CostTime;
  105. CSimpleStringA BussID;
  106. CSimpleStringA TipMsg;
  107. CSimpleStringA SourceType;
  108. CSimpleString VtmCode;
  109. void* logProducer;
  110. bool m_doLog;
  111. Link_private(LOG_LEVEL_E t_level, LOG_TYPE_E t_type)
  112. : Level(t_level), Type(t_type), BeginTime(0), EndTime(0), CostTime(0), ResultCode("SUC0000"), m_doLog(true)
  113. {
  114. TraceID = ResultMsg = LogCode = API = BussID = TipMsg = SourceType = VtmCode = "";
  115. logProducer = NULL;
  116. }
  117. bool IsAllowToRecord()
  118. {
  119. return true;
  120. }
  121. };
  122. /*北斗链路实例
  123. {
  124. "businessId": "LR0402ChromiumAutoGen",
  125. "traceId": "d2a04ca0a4834623a1323372b88e4e0a",
  126. "parentSpanId": "0",
  127. "spanId": "db5e25dffa78475c",
  128. "timestamp": "1680504454",
  129. "deployUnitId": "LR04.02_FrameworkLib",
  130. "serviceUnitId": "LR04.02@FrameworkLib_PRD_PRD",
  131. "host": "vtmtlog.paas.cmbchina.cn:8080",
  132. "api": "Exit",
  133. "returnCode": "SUC0000",
  134. "responseTime": "0",
  135. "callStack": [],
  136. "dbStack": [],
  137. "tags": {}
  138. }
  139. */
  140. class DbgToBeidou::Beidou_private {
  141. public:
  142. CSimpleStringA BussID;
  143. CSimpleStringA TraceID;//链路追踪标记,用于标记一笔业务
  144. CSimpleStringA ParentSpanId;//父节点标记
  145. CSimpleStringA SpanId;//当前节点标记
  146. CSimpleStringA Host;
  147. CSimpleStringA Api;
  148. CSimpleStringA ReturnCode;
  149. CSimpleStringA ResponseTime;
  150. CSimpleStringA CallStack;
  151. CSimpleStringA DbStack;
  152. CSimpleStringA Tags;
  153. CSimpleStringA deployUnitId;
  154. CSimpleStringA serviceUnitId;
  155. void* logProducer;
  156. Beidou_private(const linkContext& t_context, CSimpleStringA t_Api)
  157. :logProducer(NULL)
  158. {
  159. BussID = t_context.bussinessId;
  160. TraceID = t_context.traceId;
  161. ParentSpanId = t_context.parentSpanId;
  162. SpanId = t_context.spanId;
  163. Api = t_Api;
  164. ReturnCode = "SUC0000";
  165. ResponseTime = "0";
  166. Host = "vtmtlog.paas.cmbchina.cn:8080";
  167. CallStack = "{\"callStack\":[]}";
  168. DbStack = "{\"dbStack\":[]}";
  169. Tags = "{\"tags\":{}}";
  170. deployUnitId = "";
  171. serviceUnitId = "";
  172. }
  173. };
  174. linkContext EntityResource::m_link;
  175. int EntityResource::m_saveFile(0);
  176. void EntityResource::setLink(const linkContext& cur)
  177. {
  178. m_link = cur;
  179. }
  180. const linkContext& EntityResource::getLink()
  181. {
  182. return m_link;
  183. }
  184. void EntityResource::clearLink()
  185. {
  186. m_link.clear();
  187. }
  188. DbgToBeidou::DbgToBeidou(const linkContext& t_context, CSimpleStringA t_Api)
  189. :m_priPtr(new Beidou_private(t_context, t_Api))
  190. {
  191. strcpy(CharZero, "0");
  192. }
  193. DbgToBeidou::~DbgToBeidou() {
  194. if (m_priPtr)
  195. delete m_priPtr;
  196. }
  197. DbgToBeidou& DbgToBeidou::setHost(CSimpleStringA t_host) {
  198. m_priPtr->Host = t_host;
  199. return *this;
  200. }
  201. DbgToBeidou& DbgToBeidou::setReturnCode(CSimpleStringA t_ReturnCode) {
  202. m_priPtr->ReturnCode = t_ReturnCode;
  203. return *this;
  204. }
  205. DbgToBeidou& DbgToBeidou::setResponseTime(CSimpleStringA t_ResponseTime) {
  206. m_priPtr->ResponseTime = t_ResponseTime;
  207. return *this;
  208. }
  209. DbgToBeidou& DbgToBeidou::setCallStack(CSimpleStringA t_CallStack) {
  210. m_priPtr->CallStack = t_CallStack;
  211. return *this;
  212. }
  213. DbgToBeidou& DbgToBeidou::setDbStack(CSimpleStringA t_DbStack) {
  214. m_priPtr->DbStack = t_DbStack;
  215. return *this;
  216. }
  217. DbgToBeidou& DbgToBeidou::setTags(CSimpleStringA t_Tags) {
  218. m_priPtr->Tags = t_Tags;
  219. return *this;
  220. }
  221. DbgToBeidou& DbgToBeidou::set_deployUnitId(CSimpleString t_deployUnitId) {
  222. m_priPtr->deployUnitId = t_deployUnitId;
  223. return *this;
  224. }
  225. DbgToBeidou& DbgToBeidou::set_serviceUnitId(CSimpleString t_serviceUnitId) {
  226. m_priPtr->serviceUnitId = t_serviceUnitId;
  227. return *this;
  228. }
  229. void DbgToBeidou::operator () () const {
  230. beidou_log_item beidou_log = { 0 };
  231. beidou_log.BussID = (char*)m_priPtr->BussID.GetData();
  232. beidou_log.TraceID = (char*)m_priPtr->TraceID.GetData();
  233. beidou_log.ParentSpanId = (char*)m_priPtr->ParentSpanId.GetData();
  234. beidou_log.SpanId = (char*)m_priPtr->SpanId.GetData();
  235. beidou_log.Host = (char*)m_priPtr->Host.GetData();
  236. beidou_log.Api = (char*)m_priPtr->Api.GetData();
  237. beidou_log.ReturnCode = (char*)m_priPtr->ReturnCode.GetData();
  238. beidou_log.ResponseTime = m_priPtr->ResponseTime.GetLength() == 0 ? (char*)CharZero : (char*)m_priPtr->ResponseTime.GetData();
  239. beidou_log.CallStack = (char*)m_priPtr->CallStack.GetData();
  240. beidou_log.DbStack = (char*)m_priPtr->DbStack.GetData();
  241. beidou_log.Tags = (char*)m_priPtr->Tags.GetData();
  242. if (m_priPtr->deployUnitId.GetLength() > 0)
  243. beidou_log.deployUnitId = (char*)m_priPtr->deployUnitId.GetData();
  244. else
  245. beidou_log.deployUnitId = NULL;
  246. if (m_priPtr->serviceUnitId.GetLength() > 0)
  247. beidou_log.serviceUnitId = (char*)m_priPtr->serviceUnitId.GetData();
  248. else
  249. beidou_log.serviceUnitId = NULL;
  250. log_producer_client* cur = NULL;
  251. if (m_priPtr->logProducer)
  252. cur = (log_producer_client*)m_priPtr->logProducer;
  253. else {
  254. if (NULL != g_logProducer)
  255. cur = (log_producer_client*)g_logProducer;
  256. else
  257. return;
  258. }
  259. auto rst = log_producer_client_add_beidou_log(cur, &beidou_log, 1);
  260. /*
  261. if (!is_log_producer_result_ok(rst))
  262. sp_dbg_errorNoOut("beidou add log to db err: %d, %s", rst);
  263. */
  264. }
  265. DbgToBeidou& DbgToBeidou::withLogProducer(void* t_logProducer) {
  266. m_priPtr->logProducer = t_logProducer;
  267. return *this;
  268. }
  269. ////////////////////////////////////////////////////////////////////////////////////////////////
  270. DbgWithLink::DbgWithLink(LOG_LEVEL_E t_level, LOG_TYPE_E t_type) : m_priPtr(new Link_private(t_level, t_type))
  271. {
  272. auto curLink = EntityResource::getLink();
  273. if (curLink.traceId.GetLength() > 0 && curLink.bussinessId.GetLength() > 0)
  274. {
  275. m_priPtr->TraceID = curLink.traceId;
  276. m_priPtr->BussID = curLink.bussinessId;
  277. }
  278. }
  279. DbgWithLink::~DbgWithLink() {
  280. if (m_priPtr) delete m_priPtr;
  281. }
  282. DbgWithLink& DbgWithLink::setResultCode(CSimpleStringA t_ResultCode) {
  283. m_priPtr->ResultCode = t_ResultCode;
  284. return *this;
  285. }
  286. DbgWithLink& DbgWithLink::setTraceID(CSimpleStringA t_TraceID) {
  287. m_priPtr->TraceID = t_TraceID;
  288. return *this;
  289. }
  290. DbgWithLink& DbgWithLink::setResultMsg(CSimpleStringA t_ResultMsg) {
  291. if (t_ResultMsg.IsNullOrEmpty()) {
  292. m_priPtr->ResultMsg = "";
  293. } else {
  294. if (t_ResultMsg.GetLength() > MAX_LOG_LEN)
  295. t_ResultMsg = t_ResultMsg.SubString(0, MAX_LOG_LEN);
  296. #ifdef GBK_COMPACT
  297. const std::string tmp = SP::Utility::GBK2UTF8(t_ResultMsg.GetData());
  298. m_priPtr->ResultMsg = tmp.c_str();
  299. #else
  300. m_priPtr->ResultMsg = t_ResultMsg;
  301. #endif // GBK_COMPACT
  302. }
  303. return *this;
  304. }
  305. DbgWithLink& DbgWithLink::setLogCode(CSimpleStringA t_LogCode) {
  306. m_priPtr->LogCode = t_LogCode;
  307. return *this;
  308. }
  309. DbgWithLink& DbgWithLink::setAPI(CSimpleStringA t_API) {
  310. #if defined(RVC_OS_WIN)
  311. if (!t_API.IsNullOrEmpty() && t_API.IndexOf("::") != -1
  312. && !t_API.IsStartWith("DevAdapter::") /** treat specially [Gifur@2024730]*/
  313. ) {
  314. int tIdx = 0;
  315. const int nLen = t_API.GetLength();
  316. for (int i = nLen - 1; i > 0; --i) {
  317. if (t_API[i] == ':' && t_API[i - 1] == ':') {
  318. tIdx = i + 1;
  319. break;
  320. }
  321. }
  322. if (tIdx > 0 && tIdx < nLen) {
  323. t_API = t_API.SubString(tIdx);
  324. }
  325. else if (tIdx == nLen) {
  326. t_API.Clear();
  327. t_API = CSimpleStringA(true);
  328. }
  329. }
  330. #endif //RVC_OS_WIN
  331. m_priPtr->API = t_API;
  332. return *this;
  333. }
  334. DbgWithLink& DbgWithLink::setBussID(CSimpleStringA t_BussID) {
  335. m_priPtr->BussID = t_BussID;
  336. return *this;
  337. }
  338. DbgWithLink& DbgWithLink::setTipMsg(CSimpleStringA t_TipMsg) {
  339. m_priPtr->TipMsg = t_TipMsg;
  340. return *this;
  341. }
  342. DbgWithLink& DbgWithLink::setSourceType(CSimpleStringA t_SourceType) {
  343. m_priPtr->SourceType = t_SourceType;
  344. return *this;
  345. }
  346. DbgWithLink& DbgWithLink::setBeginTime(long t_BeginTime) {
  347. m_priPtr->BeginTime = t_BeginTime;
  348. return *this;
  349. }
  350. DbgWithLink& DbgWithLink::setEndTime(long t_EndTime) {
  351. m_priPtr->EndTime = t_EndTime;
  352. return *this;
  353. }
  354. DbgWithLink& DbgWithLink::setCostTime(long t_costTime) {
  355. m_priPtr->CostTime = t_costTime;
  356. return *this;
  357. }
  358. DbgWithLink& DbgWithLink::setVtmCode(CSimpleStringA t_VtmCode) {
  359. m_priPtr->VtmCode = t_VtmCode;
  360. return *this;
  361. }
  362. void DbgWithLink::operator () (const char* str, ...) const {
  363. std::lock_guard<std::mutex> lock(g_logMtx);
  364. if (str == nullptr)
  365. return;
  366. va_list arg;
  367. va_start(arg, str);
  368. int n = _vscprintf(str, arg) + 1;
  369. if (n > MAX_LOG_LEN) {
  370. n = MAX_LOG_LEN;
  371. }
  372. std::vector<char> buf(n + 1, '\0');
  373. vsnprintf(&buf[0], n, str, arg);
  374. va_end(arg);
  375. #ifdef GBK_COMPACT
  376. if (!toolkit_detect_utf8_str((const char*)&buf[0])) {
  377. char* tmp = &buf[0];
  378. const size_t len = toolkit_gbk2utf8(tmp, strlen(tmp) + 1, NULL, 0);
  379. if (len > 0) {
  380. char* temp = new char[len];
  381. if (temp != NULL) {
  382. memset(temp, 0, len);
  383. if (toolkit_gbk2utf8(tmp, strlen(tmp) + 1, temp, len) > 0) {
  384. strcpy(tmp, temp);
  385. }
  386. delete[] temp;
  387. }
  388. }
  389. }
  390. #endif //GBK_COMPACT
  391. if (m_priPtr->IsAllowToRecord()) {
  392. log_item log;
  393. log_producer_result rst;
  394. log.Level = m_priPtr->Level;
  395. log.Type = m_priPtr->Type;
  396. log.LogCode = (char*)m_priPtr->LogCode.GetData();
  397. log.API = (char*)m_priPtr->API.GetData();
  398. log.ResultCode = (char*)m_priPtr->ResultCode.GetData();
  399. log.ResultMsg = &buf[0];
  400. log.TipMsg = (char*)m_priPtr->TipMsg.GetData();
  401. log.BeginTime = m_priPtr->BeginTime;
  402. log.EndTime = m_priPtr->EndTime;
  403. log.CostTime = m_priPtr->CostTime;
  404. log.VtmCode = (char*)m_priPtr->VtmCode.GetData();
  405. log.TraceID = (char*)m_priPtr->TraceID.GetData();
  406. log.BussID = (char*)m_priPtr->BussID.GetData();
  407. log.SourceType = (char*)m_priPtr->SourceType.GetData();
  408. log_producer_client* cur = NULL;
  409. if (m_priPtr->logProducer) {
  410. cur = (log_producer_client*)m_priPtr->logProducer;
  411. } else {
  412. if (NULL != g_logProducer) {
  413. cur = (log_producer_client*)g_logProducer;
  414. }
  415. }
  416. if (cur != NULL) {
  417. if (log.Type == LOG_TYPE_SYSTEM && curEntityLogLevel <= log.Level)
  418. rst = log_producer_client_add_log(cur, &log, 1, time(NULL));
  419. else if (log.Type != LOG_TYPE_SYSTEM)
  420. rst = log_producer_client_add_log(cur, &log, 1, time(NULL));
  421. }
  422. }
  423. //LOG_LEVEL_DEBUG, LOG_LEVEL_INFO, LOG_LEVEL_WARN, LOG_LEVEL_ERROR, LOG_LEVEL_FATAL
  424. if (!m_priPtr->m_doLog) {
  425. return;
  426. }
  427. switch (m_priPtr->Level) {
  428. case LOG_LEVEL_DEBUG:
  429. sp_dbg_debugNoOut("%s", &buf[0]);
  430. break;
  431. case LOG_LEVEL_INFO:
  432. sp_dbg_infoNoOut("%s", &buf[0]);
  433. break;
  434. case LOG_LEVEL_WARN:
  435. sp_dbg_warnNoOut("%s", &buf[0]);
  436. break;
  437. case LOG_LEVEL_ERROR:
  438. sp_dbg_errorNoOut("%s", &buf[0]);
  439. break;
  440. case LOG_LEVEL_FATAL:
  441. sp_dbg_fatalNoOut("%s", &buf[0]);
  442. break;
  443. default:
  444. break;
  445. }
  446. }
  447. void DbgWithLink::operator () () const {
  448. std::lock_guard<std::mutex> lock(g_logMtx);
  449. log_item log;
  450. log.Level = m_priPtr->Level;
  451. log.Type = m_priPtr->Type;
  452. log.LogCode = (char*)m_priPtr->LogCode.GetData();
  453. log.API = (char*)m_priPtr->API.GetData();
  454. log.ResultCode = (char*)m_priPtr->ResultCode.GetData();
  455. if (m_priPtr->ResultMsg.GetLength() > MAX_LOG_LEN)
  456. m_priPtr->ResultMsg = m_priPtr->ResultMsg.SubString(0, MAX_LOG_LEN);
  457. log.ResultMsg = (char*)m_priPtr->ResultMsg.GetData();
  458. log.TipMsg = (char*)m_priPtr->TipMsg.GetData();
  459. log.BeginTime = m_priPtr->BeginTime;
  460. log.EndTime = m_priPtr->EndTime;
  461. log.CostTime = m_priPtr->CostTime;
  462. log.VtmCode = (char*)m_priPtr->VtmCode.GetData();
  463. log.TraceID = (char*)m_priPtr->TraceID.GetData();
  464. log.BussID = (char*)m_priPtr->BussID.GetData();
  465. log.SourceType = (char*)m_priPtr->SourceType.GetData();
  466. log_producer_client* cur = NULL;
  467. if (m_priPtr->logProducer) {
  468. cur = (log_producer_client*)m_priPtr->logProducer;
  469. } else {
  470. if (NULL != g_logProducer) {
  471. cur = (log_producer_client*)g_logProducer;
  472. }
  473. }
  474. if (cur != NULL) {
  475. if (log.Type == LOG_TYPE_SYSTEM && curEntityLogLevel <= log.Level)
  476. log_producer_client_add_log(cur, &log, 1, time(NULL));
  477. else if (log.Type != LOG_TYPE_SYSTEM)
  478. log_producer_client_add_log(cur, &log, 1, time(NULL));
  479. }
  480. if (!m_priPtr->m_doLog)
  481. return;
  482. switch (log.Level) {
  483. case LOG_LEVEL_DEBUG:
  484. sp_dbg_debugNoOut("%s", log.ResultMsg);
  485. break;
  486. case LOG_LEVEL_INFO:
  487. sp_dbg_infoNoOut("%s", log.ResultMsg);
  488. break;
  489. case LOG_LEVEL_WARN:
  490. sp_dbg_warnNoOut("%s", log.ResultMsg);
  491. break;
  492. case LOG_LEVEL_ERROR:
  493. sp_dbg_errorNoOut("%s", log.ResultMsg);
  494. break;
  495. case LOG_LEVEL_FATAL:
  496. sp_dbg_fatalNoOut("%s", log.ResultMsg);
  497. break;
  498. default:
  499. break;
  500. }
  501. }
  502. DbgWithLink& DbgWithLink::withLogProducer(void* t_logProducer)
  503. {
  504. m_priPtr->logProducer = t_logProducer;
  505. return *this;
  506. }
  507. DbgWithLink& DbgWithLink::withExtendLog(bool t_doLog) {
  508. m_priPtr->m_doLog = t_doLog;
  509. return *this;
  510. }
  511. CSimpleString generateDefaultStoragePath()
  512. {
  513. char dirPath[_MAX_PATH] = "";
  514. char tmp[MAX_PATH];
  515. GetModuleFileNameA(NULL, tmp, MAX_PATH);
  516. *strrchr(tmp, SPLIT_SLASH) = 0;
  517. *strrchr(tmp, SPLIT_SLASH) = 0;
  518. *strrchr(tmp, SPLIT_SLASH) = 0;
  519. *strrchr(tmp, SPLIT_SLASH) = 0;
  520. *strrchr(tmp, SPLIT_SLASH) = 0;
  521. sprintf(dirPath, "%s" SPLIT_SLASH_STR "rvc" SPLIT_SLASH_STR "terminaldbstorage", tmp);
  522. if (ExistsDirA(dirPath) || CreateDirectoryA(dirPath, NULL)) {
  523. return dirPath;
  524. }
  525. return "";
  526. }
  527. static CSimpleStringA g_entityName = "SpShell";
  528. void logCallback(const char* message) {
  529. // 在这里执行您的日志记录逻辑
  530. // 在这个示例中,我们简单地将日志消息输出到控制台
  531. WLog_DBG(TAG, "from rvcLogSDK:%s", message);
  532. }
  533. std::string toLowerCase(std::string str) {
  534. std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c) {
  535. return std::tolower(c, std::locale());
  536. });
  537. return str;
  538. }
  539. SPBASE_API void* create_log_producer_storage(CSimpleStringA entityName, CSimpleStringA item, CSimpleStringA filePath, CSimpleStringA CmptId, CSimpleString CmptName)
  540. {
  541. WLog_DBG(TAG, "create log producer storage for %s, %s, %s", entityName.GetData(), item.GetData(), filePath.GetData());
  542. log_producer_config* config = create_log_producer_config();
  543. //TODO: CrossPlaform [Gifur@2025730]
  544. #ifdef _WIN32
  545. std::string t_entityName = toLowerCase(entityName.GetData());
  546. #else
  547. const std::string t_entityName = SP::Utility::ToLower(entityName.GetData());
  548. #endif
  549. if (config == NULL) {
  550. WLog_DBG(TAG, "create_log_producer_config return null!");
  551. return NULL;
  552. }
  553. // set resource params
  554. log_producer_config_set_packet_log_bytes(config, 4 * 1024 * 1024);
  555. log_producer_config_set_packet_log_count(config, 24);//最大发送条数
  556. log_producer_config_set_max_buffer_limit(config, 64 * 1024 * 1024);
  557. // set send thread count
  558. log_producer_config_set_send_thread_count(config, 1);
  559. log_producer_config_set_persistent_max_log_count(config, 20 * 1000);
  560. log_producer_config_set_skyeye_servname(config, (char*)"Terminal");
  561. if(CmptId.GetLength() > 0)
  562. log_producer_config_set_skyeye_cmptId(config, (char*)CmptId.GetData());
  563. else
  564. log_producer_config_set_skyeye_cmptId(config, (char*)SpDefine::cmptId);
  565. if(CmptName.GetLength() > 0)
  566. log_producer_config_set_skyeye_cmptname(config, (char*)CmptName.GetData());
  567. else
  568. log_producer_config_set_skyeye_cmptname(config, (char*)SpDefine::CmptName);
  569. log_producer_config_set_skyeye_version(config, (char*)"1.0");
  570. log_producer_config_set_persistent(config, 1);
  571. sp_env_t* env = sp_get_env();
  572. if (env && env->cfg && env->cfg->args && env->cfg->args->debug_mode) {
  573. //log_producer_config_switch_debug_mode(config, 1);
  574. log_producer_config_set_persistent_encrypt(config, 0);
  575. }
  576. log_producer_config_set_skyeye_entityname(config, (char*)t_entityName.c_str());
  577. g_entityName = t_entityName.c_str();
  578. #ifndef _WIN32
  579. WLog_DBG(TAG, "entity name: %s", t_entityName.c_str());
  580. if (t_entityName.compare("spshell") == 0) {
  581. log_producer_config_memory_deal_type(config, 1);
  582. }
  583. #endif
  584. log_producer_config_set_skyeye_item(config, (char*)item.GetData());
  585. if (filePath.GetLength() == 0) {
  586. auto dstPath = generateDefaultStoragePath();
  587. if (dstPath.GetLength() == 0) {
  588. return NULL;//create db file failed
  589. } else {
  590. log_producer_config_set_persistent_file_path(config, dstPath.GetData());
  591. }
  592. } else {
  593. if (!ExistsDirA(filePath.GetData())) {
  594. CreateDirRecursiveA(filePath.GetData());
  595. }
  596. log_producer_config_set_persistent_file_path(config, filePath.GetData());
  597. }
  598. //新加统一日志配置
  599. log_producer_config_set_united_appname(config, (char*)SpDefine::cmptId);
  600. log_producer_config_set_united_version(config, (char*)"2.0");
  601. log_producer_config_set_united_needArchived(config, 0);
  602. log_producer_config_set_united_deployUnitId(config, (char*)SpDefine::deployUnitId);
  603. log_producer_config_set_united_serviceUnitId(config, (char*)SpDefine::serviceUnitId);
  604. #ifndef _WIN32
  605. //log_producer_config_set_dbgFun(logCallback);
  606. WLog_DBG(TAG, "to create_log_producer_client...");
  607. log_producer_client* result = create_log_producer_client(config, NULL, NULL);
  608. if (result == NULL) {
  609. WLog_ERR(TAG, "create_log_producer_client return null!");
  610. } else {
  611. WLog_DBG(TAG, "to create_log_producer_client done");
  612. }
  613. return result;
  614. #else
  615. return create_log_producer_client(config, NULL, NULL);
  616. #endif
  617. }
  618. SPBASE_API void destroy_log_producer_storage(void* obj)
  619. {
  620. if (obj != NULL) {
  621. log_producer_client* result = (log_producer_client*)obj;
  622. destroy_log_producer_client(result);
  623. }
  624. }
  625. SPBASE_API void* create_log_producer_send(CSimpleStringA endpoint, CSimpleStringA topicSys, CSimpleStringA topicUser, CSimpleStringA topicBeidou, CSimpleStringA bussinessSys, CSimpleStringA bussinessUser, CSimpleStringA topicVTMWeb,
  626. CSimpleStringA terminalNo, CSimpleStringA sn, CSimpleStringA filePath, int sendWaitTime)
  627. {
  628. #ifndef _WIN32
  629. if (NULL != g_logProduceSender) {
  630. return g_logProduceSender;
  631. }
  632. #endif
  633. log_producer_config* config = create_log_producer_config();
  634. log_producer_config_set_endpoint(config, endpoint.GetData());
  635. log_producer_config_set_send_thread_wait_ms(config, sendWaitTime);
  636. // add topic, comment it
  637. log_producer_config_set_beidou_topic(config, topicBeidou.GetData());
  638. log_producer_config_set_skyeye_user_topic(config, topicUser.GetData());
  639. log_producer_config_set_skyeye_sys_topic(config, topicSys.GetData());
  640. log_producer_config_set_business_sys_topic(config, bussinessSys.GetData());
  641. log_producer_config_set_business_user_topic(config, bussinessUser.GetData());
  642. log_producer_config_set_vtmweb_topic(config, topicVTMWeb.GetData());
  643. // set resource params
  644. log_producer_config_set_packet_log_bytes(config, 4 * 1024 * 1024);
  645. log_producer_config_set_packet_log_count(config, 24);
  646. log_producer_config_set_max_buffer_limit(config, 64 * 1024 * 1024);
  647. // set send thread count
  648. log_producer_config_set_send_thread_count(config, 1);
  649. log_producer_config_set_persistent_max_log_count(config, 20 * 1000);
  650. log_producer_config_set_skyeye_servname(config, (char*)"Terminal");
  651. log_producer_config_set_skyeye_cmptId(config, (char*)SpDefine::cmptId);
  652. log_producer_config_set_skyeye_cmptname(config, (char*)SpDefine::CmptName);
  653. log_producer_config_set_skyeye_version(config, (char*)"1.0");
  654. log_producer_config_set_persistent(config, 1);
  655. log_producer_config_set_openDb(config, 1);
  656. log_producer_config_set_tokenCallBack(config, Log_GetToken);
  657. sp_env_t* env = sp_get_env();
  658. if (env && env->cfg && env->cfg->args && env->cfg->args->debug_mode) {
  659. //log_producer_config_switch_debug_mode(config, 1);
  660. log_producer_config_set_persistent_encrypt(config, 0);
  661. }
  662. log_producer_config_set_skyeye_entityname(config, (char*)g_entityName.GetData());
  663. log_producer_config_set_skyeye_item(config, (char*)"upload");
  664. log_producer_config_set_skyeye_terminalNo(config, (char*)terminalNo.GetData());
  665. log_producer_config_set_skyeye_sn(config, (char*)sn.GetData());
  666. if (filePath.GetLength() == 0) {
  667. auto dstPath = generateDefaultStoragePath();
  668. if (dstPath.GetLength() == 0) {
  669. return NULL;//create db file failed
  670. } else {
  671. log_producer_config_set_persistent_file_path(config, dstPath.GetData());
  672. }
  673. } else {
  674. if (!ExistsDirA(filePath.GetData())) {
  675. CreateDirRecursiveA(filePath.GetData());
  676. }
  677. log_producer_config_set_persistent_file_path(config, filePath.GetData());
  678. }
  679. //新加统一日志配置
  680. log_producer_config_set_united_appname(config, (char*)SpDefine::cmptId);
  681. log_producer_config_set_united_version(config, (char*)"2.0");
  682. log_producer_config_set_united_needArchived(config, 0);
  683. log_producer_config_set_united_deployUnitId(config, (char*)SpDefine::deployUnitId);
  684. log_producer_config_set_united_serviceUnitId(config, (char*)SpDefine::serviceUnitId);
  685. log_producer_config_set_enable_guard(config, 1);
  686. #ifndef _WIN32
  687. g_logProduceSender = create_log_producer_client(config, NULL, NULL);
  688. return g_logProduceSender;
  689. #else
  690. return create_log_producer_client(config, NULL, NULL);
  691. #endif
  692. }
  693. SPBASE_API void destroy_log_producer_send()
  694. {
  695. if (g_logProduceSender != NULL) {
  696. log_producer_client* result = (log_producer_client*)g_logProduceSender;
  697. destroy_log_producer_client(result);
  698. g_logProduceSender = NULL;
  699. }
  700. }
  701. SPBASE_API bool refreshLogLevel()
  702. {
  703. sp_env_t* env = sp_get_env();
  704. if (env) {
  705. sp_cfg_t* cfg = env->cfg;
  706. sp_cfg_shell_entity_t* ent = sp_cfg_get_entity_by_idx(cfg, g_curEntityIdx);
  707. if (ent) {
  708. curEntityLogLevel = ent->log_record_level;
  709. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("refreshLogLevel change to EntityLevel:%d", curEntityLogLevel);
  710. }
  711. }
  712. else
  713. {
  714. if (g_entityDebugLevelArr.find("Common") != g_entityDebugLevelArr.end())
  715. {
  716. curEntityLogLevel = g_entityDebugLevelArr["Common"];
  717. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("refreshLogLevel change to Common:%d", curEntityLogLevel);
  718. }
  719. else
  720. {
  721. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("refreshLogLevel change to Default:%d", curEntityLogLevel);
  722. curEntityLogLevel = 1;
  723. }
  724. }
  725. return true;
  726. }
  727. SPBASE_API int getCurLogLevel()
  728. {
  729. return curEntityLogLevel;
  730. }
  731. SPBASE_API void setReduceSpbaseLog(int isNor)
  732. {
  733. g_spbaseLogNor = isNor;
  734. }
  735. SPBASE_API void setTestLogMode()
  736. {
  737. log_producer_set_testLogMode();
  738. }
  739. SPBASE_API int SendTestLog_loki(const char* app, const char* env, const char* body)
  740. {
  741. return log_producer_sendTestLog_loki(app, env, body);
  742. }
  743. int changeDbtoNew()
  744. {
  745. char tmp[MAX_PATH];
  746. GetModuleFileNameA(NULL, tmp, MAX_PATH);
  747. *strrchr(tmp, SPLIT_SLASH) = 0;
  748. *strrchr(tmp, SPLIT_SLASH) = 0;
  749. *strrchr(tmp, SPLIT_SLASH) = 0;
  750. *strrchr(tmp, SPLIT_SLASH) = 0;
  751. *strrchr(tmp, SPLIT_SLASH) = 0;
  752. sprintf(tmp, "%s" SPLIT_SLASH_STR "rvc" SPLIT_SLASH_STR "terminaldbstorage" SPLIT_SLASH_STR "RVC.LogSdk" SPLIT_SLASH_STR "RvcLogSdk.db", tmp);
  753. // 检查文件是否存在
  754. std::string filePath = tmp;
  755. std::ifstream file(filePath);
  756. if (!file.good()) {
  757. return 1;
  758. }
  759. // 检查文件是否被占用
  760. file.close();
  761. // 获取当前日期和时间
  762. time_t now = time(0);
  763. tm* ltm = localtime(&now);
  764. // 格式化日期和时间
  765. char date[11];
  766. strftime(date, 11, "%Y%m%d", ltm);
  767. auto uuidStr = uuid4_generateStr(8);
  768. // 生成新文件名
  769. std::string newFilePath = filePath;
  770. size_t pos = newFilePath.find_last_of('.');
  771. newFilePath.insert(pos, "_" + std::string(date) + "_" + std::string(uuidStr.GetData()));
  772. if (!std::rename(filePath.c_str(), newFilePath.c_str())) {
  773. // 重命名文件失败
  774. return 3;
  775. }
  776. return 0;
  777. }
  778. SPBASE_API int getReduceSpbaseLog()
  779. {
  780. return g_spbaseLogNor;
  781. }
  782. SPBASE_API bool create_log_producer_default(CSimpleStringA entityName, int idx)
  783. {
  784. if (entityName.Compare("SpShell", true) == 0)
  785. changeDbtoNew();
  786. refreshLogLevel();
  787. CSimpleString idxStr = CSimpleString::Format("%d", idx);
  788. #ifndef _WIN32
  789. WLog_DBG(TAG, "create defaut log_producer(create log producer storage) for %s %d", entityName.GetData(), idxStr.GetData());
  790. g_logProducer = create_log_producer_storage(entityName, idxStr, "", "", "");
  791. if (g_logProducer == NULL)
  792. WLog_ERR(TAG, "create log producer storage return null!");
  793. return (NULL != g_logProducer);
  794. #else
  795. return NULL != (g_logProducer = create_log_producer_storage(entityName, idxStr, "", "", ""));
  796. #endif
  797. }
  798. SPBASE_API void destroy_log_producer_default()
  799. {
  800. if (g_logProducer != NULL) {
  801. log_producer_client* result = (log_producer_client*)g_logProducer;
  802. destroy_log_producer_client(result);
  803. g_logProducer = NULL;
  804. }
  805. }
  806. SPBASE_API void DbgWithLinkForC(LOG_LEVEL_E t_level, LOG_TYPE_E t_type, const char* str, ...)
  807. {
  808. if (str == nullptr)
  809. return;
  810. va_list arg;
  811. va_start(arg, str);
  812. int n = _vscprintf(str, arg) + 1;
  813. std::vector<char> buf(n + 1, '\0');
  814. vsnprintf(&buf[0], n, str, arg);
  815. DbgWithLink(t_level, t_type).setResultMsg(&buf[0])();
  816. va_end(arg);
  817. }
  818. extern "C" SPBASE_API void __stdcall setCurEntityIdx(int idx)
  819. {
  820. g_curEntityIdx = idx;
  821. }
  822. void load_debugLevelInCentersetting(const char* fileName)
  823. {
  824. array_header_t* arr_section = inifile_read_section_all(fileName);
  825. g_entityDebugLevelArr.clear();
  826. g_entityDebugLevelArr["Common"] = 1;
  827. if (!arr_section)
  828. return;
  829. for (int i = 0; i < arr_section->nelts; ++i) {
  830. char* sec = ARRAY_IDX(arr_section, i, char*);
  831. array_header_t* arr_key = inifile_read_section_key_all(fileName, sec);
  832. if (!arr_key) continue;
  833. for (int j = 0; j < arr_key->nelts; ++j)
  834. {
  835. char* key = ARRAY_IDX(arr_key, j, char*);
  836. if (_stricmp(key, "UpLoadLogLevel") == 0)
  837. {
  838. std::string secName = sec;
  839. std::transform(secName.begin(), secName.end(), secName.begin(), ::tolower);
  840. g_entityDebugLevelArr[secName] = inifile_read_int(fileName, sec, "UpLoadLogLevel", 2);
  841. }
  842. }
  843. }
  844. }
  845. void load_debugLevelInMem(std::map<std::string, std::map<std::string, std::string>> & tmp_centerConfig)
  846. {
  847. g_entityDebugLevelArr.clear();
  848. const std::string compareStr = "UpLoadLogLevel";
  849. for (auto it = tmp_centerConfig.begin(); it != tmp_centerConfig.end(); it++)
  850. {
  851. auto sectionInfo = it->second;
  852. for (auto obj = sectionInfo.begin(); obj != sectionInfo.end(); obj++)
  853. {
  854. if (obj->first == compareStr)
  855. g_entityDebugLevelArr[it->first] = atoi(obj->second.c_str());
  856. }
  857. }
  858. if (g_entityDebugLevelArr.find("Common") == g_entityDebugLevelArr.end())
  859. g_entityDebugLevelArr["Common"] = 1;
  860. }
  861. int getEntityLogLevel(std::string entityName)
  862. {
  863. if (g_entityDebugLevelArr.size() == 0)
  864. return 1;
  865. if (g_entityDebugLevelArr.find(entityName) != g_entityDebugLevelArr.end())
  866. return g_entityDebugLevelArr[entityName];
  867. else
  868. return g_entityDebugLevelArr["Common"];
  869. }
  870. ErrorCodeEnum GetAllEntityIdx(CAutoArray<CSimpleStringA>& strEntityNames, CAutoArray<WORD>& wEntityDevelopIDs)
  871. {
  872. sp_env_t* env = sp_get_env();
  873. sp_cfg_t* cfg = env->cfg;
  874. array_header_t* arr_entity = cfg->shell_ini->arr_entity;
  875. strEntityNames.Init(arr_entity->nelts - 1);
  876. wEntityDevelopIDs.Init(arr_entity->nelts - 1);
  877. for (int i = 1; i < arr_entity->nelts; ++i) { // from index 1, because zero for special entity, ie. spshell entity
  878. sp_cfg_shell_entity_t* ent = ARRAY_IDX(arr_entity, i, sp_cfg_shell_entity_t*);
  879. strEntityNames[i - 1] = ent->name;
  880. wEntityDevelopIDs[i - 1] = ent->idx;
  881. }
  882. return Error_Succeed;
  883. }