diff --git a/server/src/main.cpp b/server/src/main.cpp index 9eb6a4a..743fe91 100644 --- a/server/src/main.cpp +++ b/server/src/main.cpp @@ -117,13 +117,9 @@ void CMain::OnDelClient(int ClientNetID) Client(ClientID)->m_ClientNetType = NETTYPE_INVALID; mem_zero(&Client(ClientID)->m_Stats, sizeof(CClient::CStats)); } - //copy offline message for watchdog - WatchdogMessage(ClientNetID, - 0, 0, 0, 0, 0, 0, - 0, 0, 0,0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0,0, 0, 0, - 0, 0, 0, 0); + m_OfflineAlarmThreadData.pClients = m_aClients; + m_OfflineAlarmThreadData.pWatchDogs = m_aCWatchDogs; + thread_create(offlineAlarmThread, &m_OfflineAlarmThreadData); } int CMain::HandleMessage(int ClientNetID, char *pMessage) @@ -503,6 +499,105 @@ void CMain::JSONUpdateThread(void *pUser) fs_rename(pConfig->m_aJSONFile, aJSONFileTmp); } +void CMain::offlineAlarmThread(void *pUser) +{ + CJSONUpdateThreadData *m_OfflineAlarmThreadData = (CJSONUpdateThreadData *)pUser; + CClient *pClients = m_OfflineAlarmThreadData->pClients; + CWatchDog *pWatchDogs = m_OfflineAlarmThreadData->pWatchDogs; + thread_sleep(6000); + if(!pClients->m_Connected) + { + int ID = 0; + while (strcmp(pWatchDogs[ID].m_aName, "NULL")) + { + typedef exprtk::symbol_table<double> symbol_table_t; + typedef exprtk::expression<double> expression_t; + typedef exprtk::parser<double> parser_t; + const std::string expression_string = pWatchDogs[ID].m_aRule; + std::string username = pClients->m_aUsername; + std::string name = pClients->m_aName; + std::string type = pClients->m_aType; + std::string host = pClients->m_aHost; + std::string location = pClients->m_aLocation; + std::double_t online4 = pClients->m_Stats.m_Online4; + std::double_t online6 = pClients->m_Stats.m_Online6; + + symbol_table_t symbol_table; + symbol_table.add_stringvar("username", username); + symbol_table.add_stringvar("name", name); + symbol_table.add_stringvar("type", type); + symbol_table.add_stringvar("host", host); + symbol_table.add_stringvar("location", location); + symbol_table.add_variable("online4",online4); + symbol_table.add_variable("online6",online6); + symbol_table.add_constants(); + + expression_t expression; + expression.register_symbol_table(symbol_table); + + parser_t parser; + parser.compile(expression_string,expression); + + if (expression.value() > 0) + { + time_t currentStamp = (long long)time(/*ago*/0); + if ((currentStamp-pClients->m_AlarmLastTime) > pWatchDogs[ID].m_aInterval) + { + printf("客户端下线, Client disconnects and sends alert information\n"); + pClients->m_AlarmLastTime = currentStamp; + CURL *curl; + CURLcode res; + curl_global_init(CURL_GLOBAL_ALL); + + curl = curl_easy_init(); + if(curl) { + //standard time + char standardTime[32]= { 0 }; + strftime(standardTime, sizeof(standardTime), "%Y-%m-%d %H:%M:%S",localtime(¤tStamp)); + + //url encode, Rules conflict with url special characters,eg:&, del rules, by https://cpp.la, 2023-10-09 + char encodeBuffer[2048] = { 0 }; + sprintf(encodeBuffer, "【告警名称】 %s \n\n【告警时间】 %s \n\n【用户名】 %s \n\n【节点名】 %s \n\n【虚拟化】 %s \n\n【主机名】 %s \n\n【位 置】 %s", + pWatchDogs[ID].m_aName, + standardTime, + pClients->m_aUsername, + pClients->m_aName, + pClients->m_aType, + pClients->m_aHost, + pClients->m_aLocation); + char *encodeUrl = curl_easy_escape(curl, encodeBuffer, strlen(encodeBuffer)); + + //standard url + char urlBuffer[2048] = { 0 }; + sprintf(urlBuffer, "%s%s",pWatchDogs[ID].m_aCallback, encodeUrl); + + + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_URL, urlBuffer); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS,"signature=ServerStatus"); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3L); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 6L); + res = curl_easy_perform(curl); + if(res != CURLE_OK) + fprintf(stderr, "watchdog failed: %s\n", curl_easy_strerror(res)); + if(encodeUrl) + curl_free(encodeUrl); + curl_easy_cleanup(curl); + } + curl_global_cleanup(); + } + } + ID++; + } + } + else + { + printf("网络波动,No alarm information is sent due to network fluctuations\n"); + } +} + int CMain::ReadConfig() { // read and parse config @@ -701,6 +796,7 @@ int CMain::Run() m_JSONUpdateThreadData.m_ReloadRequired = 2; m_JSONUpdateThreadData.pClients = m_aClients; m_JSONUpdateThreadData.pConfig = &m_Config; + m_JSONUpdateThreadData.pWatchDogs = m_aCWatchDogs; void *LoadThread = thread_create(JSONUpdateThread, &m_JSONUpdateThreadData); //thread_detach(LoadThread); diff --git a/server/src/main.h b/server/src/main.h index 848d246..3649661 100644 --- a/server/src/main.h +++ b/server/src/main.h @@ -101,10 +101,12 @@ class CMain { CClient *pClients; CConfig *pConfig; + CWatchDog *pWatchDogs; volatile short m_ReloadRequired; - } m_JSONUpdateThreadData; + } m_JSONUpdateThreadData, m_OfflineAlarmThreadData; static void JSONUpdateThread(void *pUser); + static void offlineAlarmThread(void *pUser); public: CMain(CConfig Config);