UpLogFSM.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. #ifndef RVC_MOD_UPLOG_FSM_H_
  2. #define RVC_MOD_UPLOG_FSM_H_
  3. #include "SpBase.h"
  4. #include "SpFSM.h"
  5. #include "SpSecureClient.h"
  6. #include <map>
  7. #include <vector>
  8. #include "json/json.h"
  9. #define USER_EVT_JMP_CONNECT EVT_USER+1
  10. #define USER_EVT_JMP_START EVT_USER+2
  11. #define USER_EVT_JMP_SENDLOG EVT_USER+3
  12. #define USER_EVT_DISCONNECT_SUCC EVT_USER+4
  13. #define USER_EVT_UPLOG_ANS EVT_USER+5
  14. #define USER_EVT_DISCONNECT_FAIL EVT_USER+6
  15. struct UpLogReq1
  16. {
  17. char TerminalNo[16];
  18. int logLen;
  19. char logdata[2048];
  20. };
  21. struct UpLogReq2
  22. {
  23. char TerminalNo[16];
  24. int logLen;
  25. char logdata[32768];
  26. };
  27. struct UpLogReply
  28. {
  29. int ResultCode;
  30. };
  31. #pragma pack()
  32. enum UpLogCtlCode
  33. {
  34. Finish = 0, //完成
  35. Error = 1, //错误
  36. };
  37. struct log_t
  38. {
  39. char* TerminalNo;//终端号
  40. char* EntityName;//实体名
  41. char* Item;//实体ID
  42. char* LogTime;//日志时间
  43. int SN;//各实体记录行号
  44. char* SysCode;//系统错误码
  45. char* UserCode;//用户错误码
  46. int LogType;//日志类型
  47. int Level;//日志级别
  48. char* Msg;//日志描述
  49. };
  50. const int UPLOG_MAX_COUNT = 5000;//队列长度
  51. const int EACH_SEND_COUNT_SINGLE = 200;//单条发送每次最大发送次数
  52. const int EACH_SEND_COUNT_MULTI = 10;//批量发送每次发送次数
  53. const int CONNECT_FAIL_WAIT_TIME=10*1000;
  54. const int CONNECT_SUCC_WAIT_TIME=3*1000;
  55. struct UpLogAnsEvent : public FSMEvent
  56. {
  57. UpLogAnsEvent(BYTE *pBuf, int nLen) : FSMEvent(USER_EVT_UPLOG_ANS)
  58. {
  59. memcpy(&m_reply, pBuf, sizeof(UpLogReply));
  60. }
  61. virtual ~UpLogAnsEvent() {}
  62. UpLogReply m_reply;
  63. };
  64. class UpLogConnection;
  65. class UpLogFSM : public FSMImpl<UpLogFSM>, public IFSMStateHooker, public ISysVarListener
  66. {
  67. public:
  68. enum {s0,s1,s2,s3};
  69. BEGIN_FSM_STATE(UpLogFSM)
  70. FSM_STATE_ENTRY(s0,"Start",s0_on_entry,s0_on_exit,s0_on_event)
  71. FSM_STATE_ENTRY(s1, "Connect", s1_on_entry, s1_on_exit, s1_on_event)
  72. FSM_STATE_ENTRY(s2, "sendLog", s2_on_entry, s2_on_exit, s2_on_event)
  73. END_FSM_STATE()
  74. BEGIN_FSM_RULE(UpLogFSM,s0)
  75. FSM_RULE_ENTRY_ANY(s0, s1, USER_EVT_JMP_CONNECT)
  76. FSM_RULE_ENTRY_ANY(s1, s2, USER_EVT_JMP_SENDLOG)
  77. FSM_RULE_ENTRY_ANY(s2, s0, USER_EVT_JMP_START)
  78. FSM_RULE_ENTRY_ANY(s2, s1, USER_EVT_JMP_CONNECT)
  79. END_FSM_RULE()
  80. UpLogFSM();
  81. ~UpLogFSM();
  82. virtual void OnStateTrans(int iSrcState, int iDstState);
  83. virtual void OnSysVarEvent(const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName);
  84. virtual ErrorCodeEnum OnInit();
  85. virtual ErrorCodeEnum OnExit();
  86. void s0_on_entry();
  87. void s0_on_exit();
  88. unsigned int s0_on_event(FSMEvent* event);
  89. void s1_on_entry();
  90. void s1_on_exit();
  91. unsigned int s1_on_event(FSMEvent* event);
  92. void s2_on_entry();
  93. void s2_on_exit();
  94. unsigned int s2_on_event(FSMEvent* event);
  95. public:
  96. //加锁添加日志
  97. void addUplog(log_t* logt);
  98. //加锁取出日志
  99. log_t* removeUplog();
  100. bool isSend(){
  101. return m_isSendLog;
  102. }
  103. bool isType(const LogTypeEnum eLogType);//是否符合日志定义类型
  104. void delLog(log_t* logt);//删除释放日志内存
  105. char* mallocStr( const char* s);
  106. int getEntityRow (const char* entityName);
  107. bool getJsonStr(UpLogReq1* req);//0: 无数据 1:成功 2:获取jsonstr失败
  108. bool getJsonStr(UpLogReq2* req);//0: 无数据 1:成功 2:获取jsonstr失败
  109. void printDebugLog(const char* debugStr);//内部使用的一个打印日志方法
  110. void addRecSum();
  111. private:
  112. CRITICAL_SECTION cs;//队列锁
  113. CRITICAL_SECTION csRec;//添加计数锁
  114. UpLogConnection *m_pConnection;
  115. CSimpleString m_logTypeList;//日志级别,集中配置文件
  116. bool m_isSendLog;//该终端是否上传日志
  117. bool m_branchSendLog;//分行上传日志开关,集中配置文件
  118. map<CSimpleString,int> m_entityRowSet;//各实体记录行号map
  119. public:
  120. int m_SendMode;//发送模式:0 单条发送(2k) 1 批量发送(最大32k)
  121. int m_iEachMaxSend;//每次连接最大发送次数
  122. vector<log_t*> m_logList;//日志记录列表
  123. //统计数量
  124. int m_iSub;//订阅总数
  125. int m_iRec;//队列接收总数
  126. int m_iSend;//队列发送总数
  127. int m_iThrow;//队列丢弃总数
  128. int m_iFail;//发送失败总次数
  129. int m_iSucc;//发送成功总次数
  130. int m_iEachSend;//每次连接发送的数量
  131. };
  132. class UpLogConnection : public SpSecureClient
  133. {
  134. public:
  135. UpLogConnection(CEntityBase *pEntity, UpLogFSM *pFSM) : SpSecureClient(pEntity), m_pFSM(pFSM) {}
  136. virtual ~UpLogConnection() {}
  137. void SendLog()
  138. {
  139. m_pFSM->m_iSend++;
  140. CSmartPointer<IPackage> pkt = CreateNewPackage("UPLOG");
  141. //Dbg("m_SendMode=%d",m_pFSM->m_SendMode);
  142. //m_pFSM->printDebugLog(CSimpleStringA::Format("m_SendMode=%d",m_pFSM->m_SendMode));
  143. if(m_pFSM->m_SendMode==0){
  144. //单条数据
  145. UpLogReq1* req1 = new UpLogReq1();
  146. memset(req1, 0, sizeof(UpLogReq1));
  147. if(m_pFSM->getJsonStr(req1)){
  148. pkt->AddStruct("LOGREQ1", false, true, (LPBYTE)req1, sizeof(UpLogReq1));
  149. if (SendPackage(pkt) == "")
  150. {
  151. //Dbg("send uplog fail:sendPackage fail");
  152. m_pFSM->printDebugLog(CSimpleStringA::Format("send uplog fail:sendPackage fail"));
  153. m_pFSM->m_iFail++;
  154. m_pFSM->PostEventFIFO(new FSMEvent(USER_EVT_DISCONNECT_FAIL));//失败,等下次发送
  155. }
  156. }else{
  157. //Dbg("send uplog fail:get jsonStr fail");
  158. m_pFSM->printDebugLog(CSimpleStringA::Format("send uplog fail:get jsonStr fail"));
  159. m_pFSM->m_iFail++;
  160. m_pFSM->PostEventFIFO(new FSMEvent(USER_EVT_DISCONNECT_FAIL));//失败,等下次发送
  161. }
  162. if(req1!=NULL)
  163. {
  164. delete req1;
  165. }
  166. }else{
  167. //多条数据
  168. UpLogReq2* req2 = new UpLogReq2();
  169. memset(req2, 0, sizeof(UpLogReq2));
  170. if(m_pFSM->getJsonStr(req2)){
  171. pkt->AddStruct("LOGREQ2", false, true, (LPBYTE)req2, sizeof(UpLogReq2));
  172. if (SendPackage(pkt) == "")
  173. {
  174. //Dbg("send uplog fail:sendPackage fail");
  175. m_pFSM->printDebugLog(CSimpleStringA::Format("send uplog fail:sendPackage fail"));
  176. m_pFSM->m_iFail++;
  177. m_pFSM->PostEventFIFO(new FSMEvent(USER_EVT_DISCONNECT_FAIL));//失败,等下次发送
  178. }
  179. }else{
  180. //Dbg("send uplog fail:get jsonStr fail");
  181. m_pFSM->printDebugLog(CSimpleStringA::Format("send uplog fail:get jsonStr fail"));
  182. m_pFSM->m_iFail++;
  183. m_pFSM->PostEventFIFO(new FSMEvent(USER_EVT_DISCONNECT_FAIL));//失败,等下次发送
  184. }
  185. if(req2!=NULL)
  186. {
  187. delete req2;
  188. }
  189. }
  190. }
  191. protected:
  192. virtual void OnPkgAnswer(const CSmartPointer<IPackage> &pRecvPkg) {
  193. string serviceCode = pRecvPkg->GetServiceCode();
  194. if (serviceCode == "UPLOG")
  195. {
  196. //Dbg("receive pkg");
  197. DWORD dwSysCode, dwUserCode;
  198. string strErrMsg;
  199. ErrorCodeEnum rc = Error_Succeed;
  200. if (pRecvPkg->GetErrMsg(dwSysCode, dwUserCode, strErrMsg))
  201. {
  202. rc = (ErrorCodeEnum)dwSysCode;
  203. LogWarn(Severity_Middle, rc, dwUserCode, CSimpleStringA::Format("create up packet Fail!, %s", strErrMsg.c_str()));
  204. m_pFSM->printDebugLog(CSimpleStringA::Format("create up packet Fail!, %s", strErrMsg.c_str()));//记录到日志中
  205. m_pFSM->m_iFail++;//失败
  206. OnDisconnect();//10s
  207. }else{
  208. int nLen = pRecvPkg->GetStructLen("LOGRET");
  209. if (nLen > 0)
  210. {
  211. BYTE *pBuf = new BYTE[nLen];
  212. memset(pBuf, 0, nLen);
  213. int nArrayNum = 0;
  214. if (pRecvPkg->GetStructData("LOGRET", pBuf, &nLen, &nArrayNum))
  215. {
  216. FSMEvent *evt = new UpLogAnsEvent(pBuf, nLen);
  217. m_pFSM->PostEventFIFO(evt);//跳转到结果判断
  218. }
  219. else
  220. {
  221. //Dbg("create invalid UpLog upans packet!");
  222. m_pFSM->printDebugLog(CSimpleStringA::Format("create invalid UpLog upans packet!"));
  223. m_pFSM->m_iFail++;//失败
  224. OnDisconnect();//10s
  225. }
  226. delete[] pBuf;
  227. }else{
  228. //nlen增加跳出分支
  229. //Dbg("upans packet len is error len=%d",nLen);
  230. m_pFSM->printDebugLog(CSimpleStringA::Format("upans packet len is error len=%d",nLen));
  231. m_pFSM->m_iFail++;//失败
  232. OnDisconnect();//10s
  233. }
  234. }
  235. }else{
  236. //Dbg("unknown service code! code= %s",serviceCode.c_str());
  237. m_pFSM->printDebugLog(CSimpleStringA::Format("unknown service code! code= %s",serviceCode.c_str()));
  238. OnDisconnect();//失败//10s
  239. }
  240. };
  241. virtual void OnDisconnect()
  242. {
  243. m_pFSM->PostEventFIFO(new FSMEvent(USER_EVT_DISCONNECT_FAIL));
  244. }
  245. private:
  246. UpLogFSM *m_pFSM;
  247. };
  248. #endif //RVC_MOD_UPLOG_FSM_H_