#ifndef RVC_MOD_UPLOG_FSM_H_ #define RVC_MOD_UPLOG_FSM_H_ #include "SpBase.h" #include "SpFSM.h" #include "SpSecureClient.h" #include #include #include "json/json.h" #define USER_EVT_JMP_CONNECT EVT_USER+1 #define USER_EVT_JMP_START EVT_USER+2 #define USER_EVT_JMP_SENDLOG EVT_USER+3 #define USER_EVT_DISCONNECT_SUCC EVT_USER+4 #define USER_EVT_UPLOG_ANS EVT_USER+5 #define USER_EVT_DISCONNECT_FAIL EVT_USER+6 struct UpLogReq1 { char TerminalNo[16]; int logLen; char logdata[2048]; }; struct UpLogReq2 { char TerminalNo[16]; int logLen; char logdata[32768]; }; struct UpLogReply { int ResultCode; }; #pragma pack() enum UpLogCtlCode { Finish = 0, //完成 Error = 1, //错误 }; struct log_t { char* TerminalNo;//终端号 char* EntityName;//实体名 char* Item;//实体ID char* LogTime;//日志时间 int SN;//各实体记录行号 char* SysCode;//系统错误码 char* UserCode;//用户错误码 int LogType;//日志类型 int Level;//日志级别 char* Msg;//日志描述 }; const int UPLOG_MAX_COUNT = 5000;//队列长度 const int EACH_SEND_COUNT_SINGLE = 200;//单条发送每次最大发送次数 const int EACH_SEND_COUNT_MULTI = 10;//批量发送每次发送次数 const int CONNECT_FAIL_WAIT_TIME=10*1000; const int CONNECT_SUCC_WAIT_TIME=3*1000; struct UpLogAnsEvent : public FSMEvent { UpLogAnsEvent(BYTE *pBuf, int nLen) : FSMEvent(USER_EVT_UPLOG_ANS) { memcpy(&m_reply, pBuf, sizeof(UpLogReply)); } virtual ~UpLogAnsEvent() {} UpLogReply m_reply; }; class UpLogConnection; class UpLogFSM : public FSMImpl, public IFSMStateHooker, public ISysVarListener { public: enum {s0,s1,s2,s3}; BEGIN_FSM_STATE(UpLogFSM) FSM_STATE_ENTRY(s0,"Start",s0_on_entry,s0_on_exit,s0_on_event) FSM_STATE_ENTRY(s1, "Connect", s1_on_entry, s1_on_exit, s1_on_event) FSM_STATE_ENTRY(s2, "sendLog", s2_on_entry, s2_on_exit, s2_on_event) END_FSM_STATE() BEGIN_FSM_RULE(UpLogFSM,s0) FSM_RULE_ENTRY_ANY(s0, s1, USER_EVT_JMP_CONNECT) FSM_RULE_ENTRY_ANY(s1, s2, USER_EVT_JMP_SENDLOG) FSM_RULE_ENTRY_ANY(s2, s0, USER_EVT_JMP_START) FSM_RULE_ENTRY_ANY(s2, s1, USER_EVT_JMP_CONNECT) END_FSM_RULE() UpLogFSM(); ~UpLogFSM(); virtual void OnStateTrans(int iSrcState, int iDstState); virtual void OnSysVarEvent(const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName); virtual ErrorCodeEnum OnInit(); virtual ErrorCodeEnum OnExit(); void s0_on_entry(); void s0_on_exit(); unsigned int s0_on_event(FSMEvent* event); void s1_on_entry(); void s1_on_exit(); unsigned int s1_on_event(FSMEvent* event); void s2_on_entry(); void s2_on_exit(); unsigned int s2_on_event(FSMEvent* event); public: //加锁添加日志 void addUplog(log_t* logt); //加锁取出日志 log_t* removeUplog(); bool isSend(){ return m_isSendLog; } bool isType(const LogTypeEnum eLogType);//是否符合日志定义类型 void delLog(log_t* logt);//删除释放日志内存 char* mallocStr( const char* s); int getEntityRow (const char* entityName); bool getJsonStr(UpLogReq1* req);//0: 无数据 1:成功 2:获取jsonstr失败 bool getJsonStr(UpLogReq2* req);//0: 无数据 1:成功 2:获取jsonstr失败 void printDebugLog(const char* debugStr);//内部使用的一个打印日志方法 void addRecSum(); private: CRITICAL_SECTION cs;//队列锁 CRITICAL_SECTION csRec;//添加计数锁 UpLogConnection *m_pConnection; CSimpleString m_logTypeList;//日志级别,集中配置文件 bool m_isSendLog;//该终端是否上传日志 bool m_branchSendLog;//分行上传日志开关,集中配置文件 map m_entityRowSet;//各实体记录行号map public: int m_SendMode;//发送模式:0 单条发送(2k) 1 批量发送(最大32k) int m_iEachMaxSend;//每次连接最大发送次数 vector m_logList;//日志记录列表 //统计数量 int m_iSub;//订阅总数 int m_iRec;//队列接收总数 int m_iSend;//队列发送总数 int m_iThrow;//队列丢弃总数 int m_iFail;//发送失败总次数 int m_iSucc;//发送成功总次数 int m_iEachSend;//每次连接发送的数量 }; class UpLogConnection : public SpSecureClient { public: UpLogConnection(CEntityBase *pEntity, UpLogFSM *pFSM) : SpSecureClient(pEntity), m_pFSM(pFSM) {} virtual ~UpLogConnection() {} void SendLog() { m_pFSM->m_iSend++; CSmartPointer pkt = CreateNewPackage("UPLOG"); //Dbg("m_SendMode=%d",m_pFSM->m_SendMode); //m_pFSM->printDebugLog(CSimpleStringA::Format("m_SendMode=%d",m_pFSM->m_SendMode)); if(m_pFSM->m_SendMode==0){ //单条数据 UpLogReq1* req1 = new UpLogReq1(); memset(req1, 0, sizeof(UpLogReq1)); if(m_pFSM->getJsonStr(req1)){ pkt->AddStruct("LOGREQ1", false, true, (LPBYTE)req1, sizeof(UpLogReq1)); if (SendPackage(pkt) == "") { //Dbg("send uplog fail:sendPackage fail"); m_pFSM->printDebugLog(CSimpleStringA::Format("send uplog fail:sendPackage fail")); m_pFSM->m_iFail++; m_pFSM->PostEventFIFO(new FSMEvent(USER_EVT_DISCONNECT_FAIL));//失败,等下次发送 } }else{ //Dbg("send uplog fail:get jsonStr fail"); m_pFSM->printDebugLog(CSimpleStringA::Format("send uplog fail:get jsonStr fail")); m_pFSM->m_iFail++; m_pFSM->PostEventFIFO(new FSMEvent(USER_EVT_DISCONNECT_FAIL));//失败,等下次发送 } if(req1!=NULL) { delete req1; } }else{ //多条数据 UpLogReq2* req2 = new UpLogReq2(); memset(req2, 0, sizeof(UpLogReq2)); if(m_pFSM->getJsonStr(req2)){ pkt->AddStruct("LOGREQ2", false, true, (LPBYTE)req2, sizeof(UpLogReq2)); if (SendPackage(pkt) == "") { //Dbg("send uplog fail:sendPackage fail"); m_pFSM->printDebugLog(CSimpleStringA::Format("send uplog fail:sendPackage fail")); m_pFSM->m_iFail++; m_pFSM->PostEventFIFO(new FSMEvent(USER_EVT_DISCONNECT_FAIL));//失败,等下次发送 } }else{ //Dbg("send uplog fail:get jsonStr fail"); m_pFSM->printDebugLog(CSimpleStringA::Format("send uplog fail:get jsonStr fail")); m_pFSM->m_iFail++; m_pFSM->PostEventFIFO(new FSMEvent(USER_EVT_DISCONNECT_FAIL));//失败,等下次发送 } if(req2!=NULL) { delete req2; } } } protected: virtual void OnPkgAnswer(const CSmartPointer &pRecvPkg) { string serviceCode = pRecvPkg->GetServiceCode(); if (serviceCode == "UPLOG") { //Dbg("receive pkg"); DWORD dwSysCode, dwUserCode; string strErrMsg; ErrorCodeEnum rc = Error_Succeed; if (pRecvPkg->GetErrMsg(dwSysCode, dwUserCode, strErrMsg)) { rc = (ErrorCodeEnum)dwSysCode; LogWarn(Severity_Middle, rc, dwUserCode, CSimpleStringA::Format("create up packet Fail!, %s", strErrMsg.c_str())); m_pFSM->printDebugLog(CSimpleStringA::Format("create up packet Fail!, %s", strErrMsg.c_str()));//记录到日志中 m_pFSM->m_iFail++;//失败 OnDisconnect();//10s }else{ int nLen = pRecvPkg->GetStructLen("LOGRET"); if (nLen > 0) { BYTE *pBuf = new BYTE[nLen]; memset(pBuf, 0, nLen); int nArrayNum = 0; if (pRecvPkg->GetStructData("LOGRET", pBuf, &nLen, &nArrayNum)) { FSMEvent *evt = new UpLogAnsEvent(pBuf, nLen); m_pFSM->PostEventFIFO(evt);//跳转到结果判断 } else { //Dbg("create invalid UpLog upans packet!"); m_pFSM->printDebugLog(CSimpleStringA::Format("create invalid UpLog upans packet!")); m_pFSM->m_iFail++;//失败 OnDisconnect();//10s } delete[] pBuf; }else{ //nlen增加跳出分支 //Dbg("upans packet len is error len=%d",nLen); m_pFSM->printDebugLog(CSimpleStringA::Format("upans packet len is error len=%d",nLen)); m_pFSM->m_iFail++;//失败 OnDisconnect();//10s } } }else{ //Dbg("unknown service code! code= %s",serviceCode.c_str()); m_pFSM->printDebugLog(CSimpleStringA::Format("unknown service code! code= %s",serviceCode.c_str())); OnDisconnect();//失败//10s } }; virtual void OnDisconnect() { m_pFSM->PostEventFIFO(new FSMEvent(USER_EVT_DISCONNECT_FAIL)); } private: UpLogFSM *m_pFSM; }; #endif //RVC_MOD_UPLOG_FSM_H_