#include "skyeyeLog.h" #include "RestfulFunc.h" #include "json/json.h" #include #include #include #include "uuid4.h" #include "SpDefine.h" #include #include #define MAX_LOG_LEN 1900 void skyeye_GetToken(char* channelId, char* token, char* terminalno, char* reserve1); void GetUnitedTimeStr(time_t time, char* szTime) { struct tm* tm = localtime(&time); sprintf(szTime, "%04d-%02d-%02dT%02d:%02d:%02d.000000000Z", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec ); } std::string get_format_uuid() { char strbuffer[64] = ""; int uuidlen = 0; uuid4_init(); uuid4_generate(strbuffer); return strbuffer; } class TokenManager { private: std::string endpoint; std::string channelId; std::string tokenSecret; std::string terminalno; std::string installVersion; //need return channelId and token std::string token; //every 20 minites execute getToken task std::chrono::system_clock::time_point lastExecutionTime; std::chrono::minutes interval; public: static TokenManager& getInstance() { static TokenManager cur; return cur; } void InitTokenManager(int t_expired_min, std::string t_endpoint, std::string t_channelId, std::string t_tokenSecret, std::string t_terminalno, std::string t_installVersion) { interval = std::chrono::minutes(t_expired_min); endpoint = t_endpoint; channelId = t_channelId; tokenSecret = t_tokenSecret; terminalno = t_terminalno; installVersion = t_installVersion; getToken(); } std::string getTerminalNo() { return terminalno; } std::pair getToken() { auto execute_refreshToken = [this] { HttpClientRequestConfig config(endpoint, NULL); HttpClientResponseResult result; Json::Value root; root["installVersion"] = installVersion; root["terminalNo"] = terminalno; Json::FastWriter writer; std::string businessId_str = writer.write(root); config.AppendQuery("channelId", channelId); config.AppendQuery("clientSecret", tokenSecret); config.AppendQuery("businessId", businessId_str); RestfulClient client = RestfulClient::getInstance(); client.Do(&config, &result); if (result.ResponseOK()) { //解析返回字符串 Json::Reader reader; Json::Value rootRet; if (!reader.parse(result.content, rootRet, false)) return; token = rootRet["data"].asString(); if (token.length() > 0) lastExecutionTime = std::chrono::system_clock::now(); } }; if (endpoint.length() == 0 && channelId.length() == 0 && endpoint.length() == 0 && tokenSecret.length() == 0 && terminalno.length() == 0 && installVersion.length() == 0) return std::make_pair("", ""); auto duration = std::chrono::duration_cast(std::chrono::system_clock::now() - lastExecutionTime); if (duration >= interval)//already expired { execute_refreshToken(); return std::make_pair(token.length() > 0 ? channelId : "", token.length() > 0 ? token : ""); } else if (duration >= interval / 2)// pre update token { std::string oldToken = token; std::thread (execute_refreshToken).detach(); return std::make_pair(oldToken.length() > 0 ? channelId : "", oldToken.length() > 0 ? oldToken : ""); } else return std::make_pair(token.length() > 0 ? channelId : "", token.length() > 0 ? token : ""); } }; /*reference example * { "_CMB_LOG_SPEC_VERSION": "2.0", "level": "DEBUG", "ts": "2024-09-03T15:09:50.000000000Z", "type": "BASETYPE", "serviceUnitId": "LR04.02@FrameworkLib_PRD_PRD", "log": { "content": { "CmptId": "LR04", "CmptName": "FrameworkLib", "LogFile": "SD", "EvenTime": "2024-09-03 15:09:50.414", "CostTime": 0, "VtmUuid": "1f595ef586bc427fa49ee5bf9842e110", "Version": "1.0", "DateTime": "2024-09-03 15:09:50.414", "ResultCode": "SUC0000", "LogCode": "", "API": "", "TipMsg": "", "BussID": "", "SourceType": "", "ResultMsg": "ReadConfigValue can not find value:site", "TraceID": "", "Item": "1", "EntityName": "mod_chromium", "LifeID": 4, "TimeSn": 125, "ServName": "7555980277", "TerminalNo": "7555980277", "SN": "7.5.1.1", "ClientIP": "192.168.56.1" } } } */ class skyeye_sender { private: std::mutex m_mtx; std::list m_msgArr; int m_TimeSn; std::chrono::system_clock::time_point m_beginTime; std::string convertLinkPrivateToStr(const Link_private& cur) { Json::Value root; root["_CMB_LOG_SPEC_VERSION"] = "2.0"; root["level"] = cur.get_baseLogType(); root["ts"] = cur.recordTime; root["type"] = "BASETYPE"; root["serviceUnitId"] = skyeye_logger::getDefaultLogger().m_constParam.m_serviceUnitId; Json::Value root_log; root_log["CmptId"] = skyeye_logger::getDefaultLogger().m_constParam.m_cmptId; root_log["CmptName"] = skyeye_logger::getDefaultLogger().m_constParam.m_cmptName; root_log["LogFile"] = cur.get_LogFile(); root_log["EvenTime"] = cur.recordTime; root_log["CostTime"] = cur.CostTime; root_log["VtmUuid"] = get_format_uuid(); root_log["Version"] = "1.0"; root_log["DateTime"] = cur.recordTime; root_log["ResultCode"] = cur.ResultCode.length() > 0 ? cur.ResultCode : ""; root_log["LogCode"] = cur.LogCode; root_log["API"] = cur.API; root_log["TipMsg"] = cur.TipMsg; root_log["BussID"] = cur.BussID; root_log["SourceType"] = cur.SourceType; root_log["ResultMsg"] = cur.ResultMsg; root_log["TraceID"] = cur.TraceID; root_log["Item"] = skyeye_logger::getDefaultLogger().m_constParam.m_item; root_log["EntityName"] = skyeye_logger::getDefaultLogger().m_constParam.m_entityName; auto currentTime = std::chrono::system_clock::now(); auto elapsedTime = std::chrono::duration_cast(currentTime - m_beginTime); root_log["LifeID"] = elapsedTime.count(); root_log["TimeSn"] = ++m_TimeSn; root_log["ServName"] = skyeye_logger::getDefaultLogger().m_constParam.m_terminalNo; root_log["TerminalNo"] = skyeye_logger::getDefaultLogger().m_constParam.m_terminalNo; root_log["SN"] = skyeye_logger::getDefaultLogger().m_constParam.m_version; root_log["ClientIP"] = "0.0.0.0"; Json::Value content_log; content_log["content"] = root_log; root["log"] = content_log; Json::FastWriter writer; std::string dst = writer.write(root); return dst; } public: static skyeye_sender& getInstance() { static skyeye_sender cur; return cur; } void LogToSender(Link_private* msg) { m_mtx.lock(); m_msgArr.push_back(*msg); m_mtx.unlock(); } bool InitSender(std::string t_endpoint, std::string t_topic) { auto skyeye_sender = [this, t_endpoint, t_topic] { if (m_msgArr.empty()) return; std::vector sendArr; m_mtx.lock(); //max send 12 logs for (int i = 0; i < 12; i++) { if (m_msgArr.size() == 0) break; sendArr.emplace_back(m_msgArr.front()); m_msgArr.pop_front(); } m_mtx.unlock(); if (sendArr.size() == 0) return; //no need to send //generate send str Json::Value root; Json::Value arraylist;//消息列表 Json::FastWriter fw;//写入对象 for (int i = 0; i < sendArr.size(); i++) { arraylist[i] = convertLinkPrivateToStr(sendArr[i]); } root["message_list"] = arraylist; root["topic"] = t_topic; auto sendStr = fw.write(root); //send HttpClientResponseResult result; HttpClientRequestConfig config(HttpRequestMethod::POST, t_endpoint,skyeye_GetToken); config.SetTimeout(60); config.SetJsonBody(sendStr.c_str()); RestfulClient client = RestfulClient::getInstance(); config.PreDo(); client.Do(&config, &result); }; std::thread(skyeye_sender).detach(); } skyeye_sender() : m_TimeSn(0) { }; }; #define MAX_TOKEN_LEN 256 void skyeye_GetToken(char* channelId, char* token, char* terminalno, char* reserve1) { auto tokenInfo = TokenManager::getInstance().getToken(); auto terminalnoInfo = TokenManager::getInstance().getTerminalNo(); snprintf(channelId, MAX_TOKEN_LEN, "%s", tokenInfo.first.c_str()); snprintf(token, MAX_TOKEN_LEN, "%s", tokenInfo.second.c_str()); snprintf(terminalno, MAX_TOKEN_LEN, "%s", terminalnoInfo.c_str()); } skyeye_logger& skyeye_logger::getDefaultLogger() { // TODO: 在此处插入 return 语句 static skyeye_logger cur; if (cur.m_msg == nullptr) cur.m_msg = new Link_private(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM); else { delete cur.m_msg; cur.m_msg = new Link_private(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM); } return cur; } skyeye_logger& skyeye_logger::setLogLevel(LOG_LEVEL_E t_level) { // TODO: 在此处插入 return 语句 if (m_msg != nullptr) m_msg->Level = t_level; return *this; } skyeye_logger& skyeye_logger::setLogType(LOG_TYPE_E t_type) { // TODO: 在此处插入 return 语句 if (m_msg != nullptr) m_msg->Type = t_type; return *this; } skyeye_logger& skyeye_logger::setResultCode(std::string t_ResultCode) { // TODO: 在此处插入 return 语句 if (m_msg != nullptr) m_msg->ResultCode = t_ResultCode; return *this; } skyeye_logger& skyeye_logger::setTraceID(std::string t_TraceID) { // TODO: 在此处插入 return 语句 if (m_msg != nullptr) m_msg->TraceID = t_TraceID; return *this; } skyeye_logger& skyeye_logger::setResultMsg(std::string t_ResultMsg) { // TODO: 在此处插入 return 语句 if (m_msg != nullptr) m_msg->ResultMsg = t_ResultMsg; return *this; } skyeye_logger& skyeye_logger::setLogCode(std::string t_LogCode) { // TODO: 在此处插入 return 语句 if (m_msg != nullptr) m_msg->LogCode = t_LogCode; return *this; } skyeye_logger& skyeye_logger::setAPI(std::string t_API) { // TODO: 在此处插入 return 语句 if (m_msg != nullptr) m_msg->API = t_API; return *this; } skyeye_logger& skyeye_logger::setBussID(std::string t_BussID) { // TODO: 在此处插入 return 语句 if (m_msg != nullptr) m_msg->BussID = t_BussID; return *this; } skyeye_logger& skyeye_logger::setTipMsg(std::string t_TipMsg) { // TODO: 在此处插入 return 语句 if (m_msg != nullptr) m_msg->TipMsg = t_TipMsg; return *this; } skyeye_logger& skyeye_logger::setSourceType(std::string t_SourceType) { // TODO: 在此处插入 return 语句 if (m_msg != nullptr) m_msg->SourceType = t_SourceType; return *this; } skyeye_logger& skyeye_logger::setBeginTime(long t_BeginTime) { // TODO: 在此处插入 return 语句 if (m_msg != nullptr) m_msg->BeginTime = t_BeginTime; return *this; } skyeye_logger& skyeye_logger::setEndTime(long t_EndTime) { // TODO: 在此处插入 return 语句 if (m_msg != nullptr) m_msg->EndTime = t_EndTime; return *this; } skyeye_logger& skyeye_logger::setCostTime(long t_costTime) { // TODO: 在此处插入 return 语句 if (m_msg != nullptr) m_msg->CostTime = t_costTime; return *this; } skyeye_logger& skyeye_logger::setVtmCode(std::string t_VtmCode) { // TODO: 在此处插入 return 语句 if (m_msg != nullptr) m_msg->VtmCode = t_VtmCode; return *this; } void skyeye_logger::operator()(LOG_LEVEL_E t_level, const char* str, ...) { if (m_msg != nullptr) { if (str == nullptr) return; va_list arg; va_start(arg, str); int n = _vscprintf(str, arg) + 1; if (n > MAX_LOG_LEN) { n = MAX_LOG_LEN; } std::vector buf(n + 1, '\0'); vsnprintf(&buf[0], n, str, arg); va_end(arg); m_msg->Level = t_level; m_msg->ResultMsg = &buf[0]; skyeye_sender::getInstance().LogToSender(m_msg); delete m_msg; m_msg = nullptr; } } void CreateDefaultLogger(std::string logEndpoint, std::string logTopic,std::string tokenEndpoint, std::string channelId, std::string tokenSecret, Link_const constParam) { skyeye_logger::getDefaultLogger().m_constParam = constParam; TokenManager::getInstance().InitTokenManager(30, tokenEndpoint, channelId, tokenSecret, constParam.m_terminalNo, constParam.m_version); skyeye_sender::getInstance().InitSender(logEndpoint, logTopic); } void CreateDefaultLogger(std::string terminalno, std::string version, std::string entityName, std::string itemId) { Link_const constParam; constParam.m_entityName = entityName; constParam.m_item = itemId; constParam.m_terminalNo = terminalno; constParam.m_version = version; constParam.m_cmptId = SpDefine::cmptId; constParam.m_cmptName = SpDefine::CmptName; constParam.m_serviceUnitId = SpDefine::serviceUnitId; constParam.m_deployUnitId = SpDefine::deployUnitId; skyeye_logger::getDefaultLogger().m_constParam = constParam; TokenManager::getInstance().InitTokenManager(30, SpDefine::CenterConfigTotal, SpDefine::channelId, SpDefine::tokenSecret, constParam.m_terminalNo, constParam.m_version); skyeye_sender::getInstance().InitSender(SpDefine::endpoint_env, SpDefine::topicSys); } skyeye_logger& GetDefaultLogger() { return skyeye_logger::getDefaultLogger(); }