diff --git a/cfg_parse/SimpleProducer.cpp b/cfg_parse/SimpleProducer.cpp index d21e73a..9bfb7cc 100644 --- a/cfg_parse/SimpleProducer.cpp +++ b/cfg_parse/SimpleProducer.cpp @@ -555,7 +555,7 @@ void rocketmq_producer_send(const char* strbody, const char* topic) catch (const std::exception& e) { std::cerr << "Failed to send message: " << e.what() << std::endl; // 处理发送失败的情况,例如记录日志或重试 - DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程 mq发送失败,请检查mq配置", get_front_msg_from_subdir(), g_front_seg_index); + DIY_ERRORLOG_CODE("process",LOG_CODE_MQ,"【ERROR】前置的%s%d号进程 mq发送失败,请检查mq配置", get_front_msg_from_subdir(), g_front_seg_index); } } #endif diff --git a/cfg_parse/cfg_parser.cpp b/cfg_parse/cfg_parser.cpp index 0e3afa0..5687bc4 100644 --- a/cfg_parse/cfg_parser.cpp +++ b/cfg_parse/cfg_parser.cpp @@ -1462,7 +1462,7 @@ int parse_rpt_log_ini() //添加判断,有的监测点没有cpuno为2,直接申请了LD_info[1],没申请LD_info[0] if(ied_usr->LD_info[cpuno].LD_name == NULL){ printf("this ld_info didn't palloc space ,maybe this ledger has problem!"); - DIY_ERRORLOG("process","【ERROR】终端%s的监测点序号为%d的监测点没有在写入台账时申请空间,所以无法初始化报告,台账可能存在缺失,跳过这个监测点的报告初始化操作",ied_usr->terminal_id,cpuno + 1); + DIY_ERRORLOG_CODE("process",LOG_CODE_RPTINIT,"【ERROR】终端%s的监测点序号为%d的监测点没有在写入台账时申请空间,所以无法初始化报告,跳过这个监测点的报告初始化。操作台账可能存在缺失,请检查台账的监测点序号是否从1开始",ied_usr->terminal_id,cpuno + 1); continue;//跳过防止崩溃 } @@ -1804,13 +1804,13 @@ int parse_ledger_update_xml(trigger_update_xml_t* trigger_update_xml) //加载一个文件的内容到数据结构 if (!load_ledger_update_from_xml(trigger_update_xml, filename)) { std::cout << "read /etc/ledgerupdate/" << filename << " success..." << std::endl; - DIY_WARNLOG("process","【WARN】前置的%s%d号进程 读取台账更新文件成功,开始更新台账", get_front_msg_from_subdir(), g_front_seg_index); + DIY_WARNLOG_CODE("process",LOG_CODE_LEDGER_UPDATE,"【WARN】前置的%s%d号进程 读取台账更新文件成功,开始更新台账", get_front_msg_from_subdir(), g_front_seg_index); } //处理过的文件删除掉 if (std::remove(filename.c_str()) != 0) { std::cerr << "Failed to remove file: " << filename << " Error: " << strerror(errno) << std::endl; - DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程 删除已读取的台账更新文件失败!请检查台账更新文件是否残留在/FeProject/etc/ledgerupdate", get_front_msg_from_subdir(), g_front_seg_index); + DIY_ERRORLOG_CODE("process",LOG_CODE_LEDGER_UPDATE,"【ERROR】前置的%s%d号进程 删除已读取的台账更新文件失败!请检查台账更新文件是否残留在/FeProject/etc/ledgerupdate", get_front_msg_from_subdir(), g_front_seg_index); return APR_EGENERAL; } else{ @@ -1995,7 +1995,7 @@ int parse_3s_xml(trigger_3s_xml_t* trigger_3s_xml) printf("/etc/trigger3s/*.xml success...\n"); - DIY_WARNLOG("process","【WARN】前置读取实时数据触发文件成功,即将注册实时数据报告"); + DIY_INFOLOG("process","【WARN】前置读取实时数据触发文件成功,即将注册实时数据报告"); return APR_SUCCESS; } @@ -2150,6 +2150,7 @@ int parse_file_names_by_fltnum(int fltnum, char* domname, char** filenames, int p = strtok(NULL, "_"); //PQM1 p = strtok(NULL, "_"); //000001 int nFltNum = atoi(p); //将字符转换成整型 + printf(">>>>>>>>>>>>>>>>>>get nFltNum from file list is %d", nFltNum); if (nFltNum == fltnum) { @@ -2307,7 +2308,7 @@ int parse_recall_xml(recall_xml_t* recall_xml, char* id) QDir dir(cfg_dir); if (!dir.exists()) { qDebug() << "folder does not exist!"; - DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程 无法解析补招文件,补招文件路径/FeProject/etc/recall/不存在", get_front_msg_from_subdir(), g_front_seg_index); + DIY_ERRORLOG_CODE("process",LOG_CODE_RECALL,"【ERROR】前置的%s%d号进程 无法解析补招文件,补招文件路径/FeProject/etc/recall/不存在", get_front_msg_from_subdir(), g_front_seg_index); return false; } //指定文件后缀名,可指定多种类型 @@ -2323,7 +2324,7 @@ int parse_recall_xml(recall_xml_t* recall_xml, char* id) if (!file.open(QIODevice::ReadOnly)) { qDebug() << "file.open error"; - DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程 无法打开补招文件%s", get_front_msg_from_subdir(), g_front_seg_index,qstrRecallPath.toStdString().c_str()); + DIY_ERRORLOG_CODE("process",LOG_CODE_RECALL,"【ERROR】前置的%s%d号进程 无法打开补招文件%s", get_front_msg_from_subdir(), g_front_seg_index,qstrRecallPath.toStdString().c_str()); continue; //以只读方式打开 } bool ret = doc.setContent(&file); @@ -2331,7 +2332,7 @@ int parse_recall_xml(recall_xml_t* recall_xml, char* id) if (!ret) { qDebug() << "doc.setContent error"; - DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程 无法解析补招文件%s,补招内容无效", get_front_msg_from_subdir(), g_front_seg_index,qstrRecallPath.toStdString().c_str()); + DIY_ERRORLOG_CODE("process",LOG_CODE_RECALL,"【ERROR】前置的%s%d号进程 无法解析补招文件%s,补招内容无效", get_front_msg_from_subdir(), g_front_seg_index,qstrRecallPath.toStdString().c_str()); continue; } //将文件内容读到doc中 @@ -2909,7 +2910,7 @@ void DeletcRecallXml() { QDir dir(cfg_dir); if (!dir.exists()) { qDebug() << "folder does not exist!"; - DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程 删除旧的补招文件失败,补招文件路径/FeProject/etc/recall/不存在", get_front_msg_from_subdir(), g_front_seg_index); + DIY_ERRORLOG_CODE("process",LOG_CODE_RECALL,"【ERROR】前置的%s%d号进程 删除旧的补招文件失败,补招文件路径/FeProject/etc/recall/不存在", get_front_msg_from_subdir(), g_front_seg_index); return; } QStringList filter(file_name); @@ -2974,7 +2975,7 @@ void CreateRecallXml() if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { printf("补招查询完成,打开%s失败,无法写入线路补招配置!\n", qstrRecallPath.toAscii().data()); - DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程 无法将补招文件写入补招文件路径/FeProject/etc/recall/", get_front_msg_from_subdir(), g_front_seg_index); + DIY_ERRORLOG_CODE("process",LOG_CODE_RECALL,"【ERROR】前置的%s%d号进程 无法将补招文件写入补招文件路径/FeProject/etc/recall/", get_front_msg_from_subdir(), g_front_seg_index); QMap >().swap(ID_CJournalRecall_Map); return; @@ -3702,14 +3703,14 @@ int terminal_ledger_web(QMap* terminal_dev_map, // 参数验证 if (num <= 0) { std::cerr << "Error: 'num' must be greater than 0." << std::endl; - DIY_ERRORLOG("process","【ERROR】前置的多进程最大进程号为:%d,应该为大于0的整数",num); + DIY_ERRORLOG_CODE("process",LOG_CODE_LEDGER,"【ERROR】前置的多进程最大进程号为:%d,应该为大于0的整数",num); return 1; // 返回适当的错误码 } index = index - 1; if (index < 0 || index >= num) { std::cerr << "Error: 'index' must be in the range [0, num]." << std::endl; - DIY_ERRORLOG("process","【ERROR】前置当前进程的进程号为:%d,应该为0到最大进程号范围内的整数",index); + DIY_ERRORLOG_CODE("process",LOG_CODE_LEDGER,"【ERROR】前置当前进程的进程号为:%d,应该为0到最大进程号范围内的整数",index); return 1; // 返回适当的错误码 } } @@ -3717,7 +3718,7 @@ int terminal_ledger_web(QMap* terminal_dev_map, // 获取参数 if (codes.empty()) { std::cerr << "Error: 'codes' vector is empty." << std::endl; - DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程调用web台账接口的入参为空",get_front_msg_from_subdir(), g_front_seg_index); + DIY_ERRORLOG_CODE("process",LOG_CODE_LEDGER,"【ERROR】前置的%s%d号进程调用web台账接口的入参为空",get_front_msg_from_subdir(), g_front_seg_index); return 1; } @@ -3837,7 +3838,7 @@ int terminal_ledger_web(QMap* terminal_dev_map, } } std::cerr << "data 无效或为空数组,重试" << std::endl; - DIY_ERRORLOG("process","【ERROR】前置从web接口中获取的台账信息为空或者无效信息无法解析,请核对前置使用的入参信息:%s",parm.c_str()); + DIY_ERRORLOG_CODE("process",LOG_CODE_LEDGER,"【ERROR】前置从web接口中获取的台账信息为空或者无效信息无法解析,请核对前置使用的入参信息:%s",parm.c_str()); } } @@ -3879,7 +3880,7 @@ int terminal_ledger_web(QMap* terminal_dev_map, break; // 本地台账解析成功且数组非空 } } - DIY_ERRORLOG("process","【ERROR】前置从本地台账中获取的台账信息为空或者无效信息无法解析,请核对前置使用的入参信息:%s",parm.c_str()); + DIY_ERRORLOG_CODE("process",LOG_CODE_LEDGER,"【ERROR】前置从本地台账中获取的台账信息为空或者无效信息无法解析,请核对前置使用的入参信息:%s",parm.c_str()); } free(ledger); // root==null释放内容 @@ -4147,13 +4148,13 @@ int parse_device_cfg_web() //判断是否相等 if(max_process_num != max_index){ if(max_process_num > 0 && max_process_num < 10){ - DIY_WARNLOG("process","【WARN】前置比对台账获取的进程数:%d和本地配置的进程数:%d,不匹配,按照台账进程数重置前置的进程数量",max_process_num,max_index); + DIY_WARNLOG_CODE("process",LOG_CODE_LEDGER,"【WARN】前置比对台账获取的进程数:%d和本地配置的进程数:%d,不匹配,按照台账进程数重置前置的进程数量",max_process_num,max_index); // 调用执行脚本函数 close_listening_socket(); execute_bash("reset", max_process_num, "all"); } else{ - DIY_ERRORLOG("process","【ERROR】前置从台账获取的进程数:%d不符合范围1~9,按照本地配置进程数启动进程",max_process_num); + DIY_ERRORLOG_CODE("process",LOG_CODE_LEDGER,"【ERROR】前置从台账获取的进程数:%d不符合范围1~9,按照本地配置进程数启动进程",max_process_num); } } } @@ -4177,7 +4178,7 @@ int parse_device_cfg_web() //添加提示 std::cout << "!!!!!!!!!!single process can not add any ledger unless reboot!!!!!!!"<< std::endl; - DIY_WARNLOG("process","【WARN】前置的%s%d号进程获取到的台账的数量大于配置文件中给单个进程配置的台账数量:%d,这个进程将按照获取到的台账的数量来创建台账空间,这个进程不能直接通过台账添加来新增台账,只能通过重启进程或者先删除已有台账再添加台账的方式来添加新台账",get_front_msg_from_subdir(), g_front_seg_index,IED_COUNT); + DIY_WARNLOG_CODE("process",LOG_CODE_LEDGER,"【WARN】前置的%s%d号进程获取到的台账的数量大于配置文件中给单个进程配置的台账数量:%d,这个进程将按照获取到的台账的数量来创建台账空间,这个进程不能直接通过台账添加来新增台账,只能通过重启进程或者先删除已有台账再添加台账的方式来添加新台账",get_front_msg_from_subdir(), g_front_seg_index,IED_COUNT); } else{ g_node->clients = (ied_t**)apr_pcalloc(g_cfg_pool, IED_COUNT * sizeof(ied_t*));//g_node->clients 这块大内存空间存储了 count_cfg 个 ied_t* 类型的指针(即一个指针数组)这是(指向内存块的指针)的指针数组 @@ -4458,7 +4459,7 @@ int parse_device_cfg_web() isdelta_flag = 1; //存在一个监测点为角型接线则这个前置就要启动第二个配置列表 cout << "monitor_id" << monitor_id << "v_wiring_type:" << line_info.v_wiring_type << "is delta wiring:" << isdelta_flag << endl; - DIY_WARNLOG("process","【WARN】前置连接的监测点 %s 是角形接线,对应终端为%s 终端类型是%s",line_info.mp_id,ied_usr->terminal_id,ied_usr->dev_type); + DIY_WARNLOG_CODE("process",LOG_CODE_LEDGER,"【WARN】前置连接的监测点 %s 是角形接线,对应终端为%s 终端类型是%s",line_info.mp_id,ied_usr->terminal_id,ied_usr->dev_type); } strcpy(line_info.monitor_status, monitor_status); @@ -4689,7 +4690,7 @@ int parse_model_cfg_web() ///////////////////////////////////////////////////////////////////////// if(parse_model_web(&icd_model_map,codes)){ - DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程 icd模型接口异常,将使用默认的icd模型,请检查接口配置", get_front_msg_from_subdir(), g_front_seg_index); + DIY_ERRORLOG_CODE("process",LOG_CODE_ICD_AND_DOWNLOAD,"【ERROR】前置的%s%d号进程 icd模型接口异常,将使用默认的icd模型,请检查接口配置", get_front_msg_from_subdir(), g_front_seg_index); return APR_SUCCESS; //可以使用默认的映射文件所以返回正常 } @@ -5173,7 +5174,7 @@ void handleUploadResponse(const std::string& response, char* wavepath) { cJSON* json_data = cJSON_Parse(response.c_str()); if (json_data == nullptr) { std::cerr << "Error parsing response: " << cJSON_GetErrorPtr() << std::endl; - DIY_ERRORLOG("process","【ERROR】前置上传暂态录波文件失败,web返回的消息不是json格式"); + DIY_ERRORLOG_CODE("process",LOG_CODE_TRANSIENT_COMM,"【ERROR】前置上传暂态录波文件失败,web返回的消息错误,无法解析"); return; } @@ -5223,7 +5224,7 @@ void handleUploadResponse(const std::string& response, char* wavepath) { } } else { std::cerr << "Error: Missing expected fields in JSON response." << std::endl; - DIY_ERRORLOG("process","【ERROR】前置上传暂态录波文件失败,web返回的消息没有远端文件名"); + DIY_ERRORLOG_CODE("process",LOG_CODE_TRANSIENT_COMM,"【ERROR】前置上传暂态录波文件失败,web返回的消息没有远端文件名"); } // 释放 JSON 对象 @@ -5340,7 +5341,7 @@ void SendFileWeb(const std::string& strUrl, const char* localpath, const char* c CURLcode res = curl_easy_perform(curl); if (res != CURLE_OK) { std::cerr << "http web failed: " << curl_easy_strerror(res) << std::endl; - DIY_ERRORLOG("process","【ERROR】前置上传暂态录波文件 %s 失败,请检查文件上传接口配置",localpath); + DIY_ERRORLOG_CODE("process",LOG_CODE_TRANSIENT_COMM,"【ERROR】前置上传暂态录波文件 %s 失败,请检查文件上传接口配置",localpath); } else { std::cout << "http web success, response: " << resPost0 << std::endl; handleUploadResponse(resPost0, wavepath); // 处理响应 @@ -5857,7 +5858,7 @@ int parse_rpt_log_ini_one(ied_t* ied) //添加判断,有的监测点没有cpuno为2,直接申请了LD_info[2-1],没申请LD_info[0] if(ied_usr->LD_info[cpuno].LD_name == NULL){ printf("this ld_info didn't palloc space ,maybe this ledger has problem!"); - DIY_ERRORLOG("process","【ERROR】终端%s的监测点序号为%d的监测点没有在写入台账时申请空间,所以无法初始化报告,台账可能存在缺失,跳过这个监测点的报告初始化操作",ied_usr->terminal_id,cpuno + 1); + DIY_ERRORLOG_CODE("process",LOG_CODE_RPTINIT,"【ERROR】终端%s的监测点序号为%d的监测点没有在写入台账时申请空间,所以无法初始化报告,跳过这个监测点的报告初始化。操作台账可能存在缺失,请检查台账的监测点序号是否从1开始",ied_usr->terminal_id,cpuno + 1); continue;//跳过防止崩溃 } diff --git a/cfg_parse/log4.cpp b/cfg_parse/log4.cpp index f0ddd7d..1743c38 100644 --- a/cfg_parse/log4.cpp +++ b/cfg_parse/log4.cpp @@ -127,6 +127,9 @@ bool DebugSwitch::match(const std::string& logger_name, int level, int logtype) std::map logger_map; DebugSwitch g_debug_switch; +// ★新增:定义 TLS 变量,默认 0 +LOG_TLS int g_log_code_tls = 0; + class SendAppender : public Appender { protected: void append(const spi::InternalLoggingEvent& event) { @@ -143,6 +146,9 @@ protected: else level_str = "terminal"; + // ★读取 TLS 中的 code(在打日志的线程里由宏设定) + int code = g_log_code_tls; // 若未显式传入,则为 0 + if (level == ERROR_LOG_LEVEL || level == WARN_LOG_LEVEL || g_debug_switch.match(logger_name, level, logtype)) { std::ostringstream oss; oss << "{\"processNo\":\"" << intToString(g_front_seg_index) @@ -152,6 +158,8 @@ protected: << "\",\"grade\":\"" << get_level_str(level) << "\",\"logtype\":\"" << (logtype == LOGTYPE_COM ? "com" : "data") << "\",\"frontType\":\"" << get_front_type_from_subdir() + // ★新增:输出 code 字段(整型) + << "\",\"code\":" << code << "\",\"log\":\"" << escape_json(msg) << "\"}"; std::string jsonString = oss.str(); @@ -332,7 +340,7 @@ void init_loggers_bydevid(const char* dev_id) logger_map[device_key_c] = TypedLogger(device_logger_c, LOGTYPE_COM); logger_map[device_key_d] = TypedLogger(device_logger_d, LOGTYPE_DATA); - DIY_WARNLOG(device_key_d.c_str(),"【WARN】终端id:%s终端级日志初始化完毕", ied_usr->terminal_id); + DIY_INFOLOG(device_key_d.c_str(),"【WARN】终端id:%s终端级日志初始化完毕", ied_usr->terminal_id); } // 初始化监测点 @@ -361,7 +369,7 @@ void init_loggers_bydevid(const char* dev_id) logger_map[mon_key_c.str()] = TypedLogger(mon_logger_c, LOGTYPE_COM); logger_map[mon_key_d.str()] = TypedLogger(mon_logger_d, LOGTYPE_DATA); - DIY_WARNLOG(mon_key_d.str().c_str(),"【WARN】监测点:%s - id:%s监测点级日志初始化完毕", ied_usr->LD_info[i].name,ied_usr->LD_info[i].mp_id); + DIY_INFOLOG(mon_key_d.str().c_str(),"【WARN】监测点:%s - id:%s监测点级日志初始化完毕", ied_usr->LD_info[i].name,ied_usr->LD_info[i].mp_id); } } @@ -410,7 +418,7 @@ void init_loggers() { logger_map[device_key_c] = TypedLogger(device_logger_c, LOGTYPE_COM); logger_map[device_key_d] = TypedLogger(device_logger_d, LOGTYPE_DATA); - DIY_WARNLOG(device_key_d.c_str(),"【WARN】终端id:%s终端级日志初始化完毕", ied_usr->terminal_id); + DIY_INFOLOG(device_key_d.c_str(),"【WARN】终端id:%s终端级日志初始化完毕", ied_usr->terminal_id); // 初始化监测点 // 监测点 logger 名称格式:monitor..COM / .DATA @@ -435,7 +443,7 @@ void init_loggers() { logger_map[mon_key_c.str()] = TypedLogger(mon_logger_c, LOGTYPE_COM); logger_map[mon_key_d.str()] = TypedLogger(mon_logger_d, LOGTYPE_DATA); - DIY_WARNLOG(mon_key_d.str().c_str(),"【WARN】监测点:%s - id:%s监测点级日志初始化完毕", ied_usr->LD_info[i].name,ied_usr->LD_info[i].mp_id); + DIY_INFOLOG(mon_key_d.str().c_str(),"【WARN】监测点:%s - id:%s监测点级日志初始化完毕", ied_usr->LD_info[i].name,ied_usr->LD_info[i].mp_id); } diff --git a/json/create_json.cpp b/json/create_json.cpp index 2a0ce11..af8c4e1 100644 --- a/json/create_json.cpp +++ b/json/create_json.cpp @@ -2681,7 +2681,7 @@ void Set_xml_databaseinfo(char* MODEL_ID, char* TMNL_TYPE, char* FILE_PATH, char cout << file_name << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << save_name << endl; //mq日志 - DIY_WARNLOG("process","【WARN】前置获取到终端类型%s,该终端类型对应的映射文件为%s,映射文件将下载并保存在本地为%s",TMNL_TYPE,FILE_PATH,save_name); + DIY_WARNLOG_CODE("process",LOG_CODE_ICD_AND_DOWNLOAD,"【WARN】前置获取到终端类型%s,该终端类型对应的映射文件为%s,映射文件将下载并保存在本地为%s",TMNL_TYPE,FILE_PATH,save_name); //20241028 lnk 替换为文件下载web接口 //构造文件下载接口参数 @@ -2713,17 +2713,17 @@ void Set_xml_databaseinfo(char* MODEL_ID, char* TMNL_TYPE, char* FILE_PATH, char outFile.close(); std::cout << "File saved successfully!" << std::endl; //mq日志 - DIY_WARNLOG("process","【WARN】前置下载映射文件%s成功",save_name); + DIY_INFOLOG("process","【NORMAL】前置下载映射文件%s成功",save_name); } else { std::cerr << "Error: Unable to open file for writing." << std::endl; - DIY_ERRORLOG("process","【ERROR】前置写入本地映射文件%s失败",save_name); + DIY_ERRORLOG_CODE("process",LOG_CODE_ICD_AND_DOWNLOAD,"【ERROR】前置写入本地映射文件%s失败",save_name); } // 释放分配的内存 free(fileContent); } else { std::cerr << "Error: Unable to download file." << std::endl; - DIY_ERRORLOG("process","【ERROR】前置调用文件下载接口下载远端文件文件%s失败",FILE_PATH); + DIY_ERRORLOG_CODE("process",LOG_CODE_ICD_AND_DOWNLOAD,"【ERROR】前置调用文件下载接口下载远端文件文件%s失败",FILE_PATH); } } @@ -3054,7 +3054,7 @@ static void writeJsonToFile(const char* filePath, const char* jsonString) { FILE* fp = fopen(filePath, "w"); if (!fp) { - DIY_ERRORLOG("process","【ERROR】无法将暂态事件写入本地缓存"); + DIY_ERRORLOG_CODE("process",LOG_CODE_TRANSIENT_COMM,"【ERROR】无法将暂态事件写入本地缓存"); std::cerr << "Failed to write in file : " << filePath << std::endl; return; } @@ -3140,7 +3140,7 @@ static void scanAndResendOfflineFiles(const std::string &dirPath) // 读取文件内容(即之前存的 JSON) FILE* fp = fopen(fileList[i].fileName.c_str(), "r"); if (!fp) { - DIY_ERRORLOG("process","【ERROR】无法打开本地缓存的暂态事件"); + DIY_ERRORLOG_CODE("process",LOG_CODE_TRANSIENT_COMM,"【ERROR】无法打开本地缓存的暂态事件"); std::cerr << " fail to open exsist file " << fileList[i].fileName << std::endl; continue; } @@ -3168,12 +3168,12 @@ static void scanAndResendOfflineFiles(const std::string &dirPath) // 表示有响应,则可视为成功;根据项目需要可加更精细的判断 handleCommentResponse(std::string(ptr)); - DIY_WARNLOG("process","【WARN】前置重发暂态事件失败"); + DIY_WARNLOG_CODE("process",LOG_CODE_TRANSIENT_COMM,"【WARN】前置重发暂态事件失败"); } else{ - DIY_WARNLOG("process","【WARN】前置重发暂态事件成功"); + DIY_WARNLOG_CODE("process",LOG_CODE_TRANSIENT_COMM,"【WARN】前置重发暂态事件成功"); std::cout << "old file send success,remove it" << std::endl; // 删除文件 @@ -3283,7 +3283,7 @@ char* mp_id,char* Qvvr_rptname,char* devtype) if (j_r == NULL) { //mq日志 - DIY_ERRORLOG(full_key_m_d,"【ERROR】暂态接口响应异常,无法上送监测点%s的暂态事件",mp_id); + DIY_ERRORLOG_CODE(full_key_m_d,LOG_CODE_TRANSIENT_COMM,"【ERROR】暂态接口响应异常,无法上送监测点%s的暂态事件",mp_id); std::cout << "qvvr send fail ,store in local" << std::endl; // 1) 先检查/FeProject/dat/qvvr/目录文件大小是否超过 10M,若超过则删除最老的一个文件 @@ -3331,7 +3331,7 @@ char* mp_id,char* Qvvr_rptname,char* devtype) std::cout << "Error: Received NULL response" << std::endl; //mq日志 - DIY_ERRORLOG(full_key_m_d,"【ERROR】暂态接口无响应,无法上送监测点%s的暂态事件",mp_id); + DIY_ERRORLOG_CODE(full_key_m_d,LOG_CODE_TRANSIENT_COMM,"【ERROR】暂态接口无响应,无法上送监测点%s的暂态事件",mp_id); std::cout << "qvvr send fail ,store in local" << std::endl; // 1) 先检查/FeProject/dat/qvvr/目录文件大小是否超过 10M,若超过则删除最老的一个文件 diff --git a/json/save2json.cpp b/json/save2json.cpp index c0784bc..434dc4a 100644 --- a/json/save2json.cpp +++ b/json/save2json.cpp @@ -998,7 +998,7 @@ int parse_set(const std::string& json_str) { } execute_bash(fun, processNum, frontType); - DIY_WARNLOG("process","【WARN】前置的%s%d号进程执行指令:%s,reset表示重启所有进程,add表示添加进程",get_front_msg_from_subdir(), g_front_seg_index,fun.c_str()); + DIY_WARNLOG_CODE("process",LOG_CODE_PROCESS_CONTROL,"【WARN】前置的%s%d号进程执行指令:%s,reset表示重启所有进程,add表示添加进程",get_front_msg_from_subdir(), g_front_seg_index,fun.c_str()); //脚本在3秒后执行 //回复消息 @@ -1020,7 +1020,7 @@ int parse_set(const std::string& json_str) { send_reply_to_kafka(guid,"1","收到删除进程指令,这个进程将会重启 "); //上送日志 - DIY_WARNLOG("process","【WARN】前置的%s%d号进程执行指令:%s,即将重启",get_front_msg_from_subdir(), g_front_seg_index,fun.c_str()); + DIY_WARNLOG_CODE("process",LOG_CODE_PROCESS_CONTROL,"【WARN】前置的%s%d号进程执行指令:%s,即将重启",get_front_msg_from_subdir(), g_front_seg_index,fun.c_str()); apr_sleep(apr_time_from_sec(10)); ::_exit(-1039); //进程退出 @@ -1796,7 +1796,7 @@ int myMessageCallbackrtdata(CPushConsumer* consumer, CMessageExt* msg) if (!parseJsonMessageRT(body, devid, line, realData, soeData, limit)) { std::cerr << "Failed to parse the JSON message." << std::endl; //记录日志 - DIY_ERRORLOG("process","【ERROR】前置消费topic:%s_%s的实时触发消息失败,消息的json格式不正确",FRONT_INST.c_str(),G_MQCONSUMER_TOPIC_RT.c_str()); + DIY_ERRORLOG_CODE("process",LOG_CODE_RT_DATA,"【ERROR】前置消费topic:%s_%s的实时触发消息失败,消息的json格式不正确",FRONT_INST.c_str(),G_MQCONSUMER_TOPIC_RT.c_str()); return E_RECONSUME_LATER; } @@ -1814,7 +1814,7 @@ int myMessageCallbackrtdata(CPushConsumer* consumer, CMessageExt* msg) } // 创建 XML 文件 if (!createXmlFile(dev_index, mp_index, realData, soeData, limit,"new")) { - DIY_ERRORLOG("process","【ERROR】前置无法创建实时数据触发文件"); + DIY_ERRORLOG_CODE("process",LOG_CODE_RT_DATA,"【ERROR】前置无法创建实时数据触发文件"); std::cerr << "Failed to create the XML file." << std::endl; return E_RECONSUME_LATER; } @@ -1855,7 +1855,7 @@ int myMessageCallbackupdate(CPushConsumer* consumer, CMessageExt* msg) //处理台账更新消息 std::string updatefilepath = "/home/pq/FeProject/etc/ledgerupdate"; if(parse_control(body,updatefilepath)){ - DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程处理topic:%s_%s的台账更新消息失败,消息的json结构不正确",get_front_msg_from_subdir(), g_front_seg_index,FRONT_INST.c_str(),G_MQCONSUMER_TOPIC_UD.c_str()); + DIY_ERRORLOG_CODE("process",LOG_CODE_LEDGER_UPDATE,"【ERROR】前置的%s%d号进程处理topic:%s_%s的台账更新消息失败,消息的json结构不正确",get_front_msg_from_subdir(), g_front_seg_index,FRONT_INST.c_str(),G_MQCONSUMER_TOPIC_UD.c_str()); } } @@ -1891,7 +1891,7 @@ int myMessageCallbackset(CPushConsumer* consumer, CMessageExt* msg) //处理进程更新消息 if(parse_set(body)){ - DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程处理topic:%s_%s的进程控制消息失败,消息的json结构不正确",get_front_msg_from_subdir(), g_front_seg_index,FRONT_INST.c_str(),G_MQCONSUMER_TOPIC_SET.c_str()); + DIY_ERRORLOG_CODE("process",LOG_CODE_PROCESS_CONTROL,"【ERROR】前置的%s%d号进程处理topic:%s_%s的进程控制消息失败,消息的json结构不正确",get_front_msg_from_subdir(), g_front_seg_index,FRONT_INST.c_str(),G_MQCONSUMER_TOPIC_SET.c_str()); } } @@ -1927,7 +1927,7 @@ int myMessageCallbacklog(CPushConsumer* consumer, CMessageExt* msg) //处理进程更新消息 if(parse_log(body)){ - DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程处理topic:%s_%s的日志上送消息失败,消息的json结构不正确",get_front_msg_from_subdir(), g_front_seg_index,FRONT_INST.c_str(),G_MQCONSUMER_TOPIC_LOG.c_str()); + DIY_ERRORLOG_CODE("process",LOG_CODE_LOG_REQUEST,"【ERROR】前置的%s%d号进程处理topic:%s_%s的日志上送消息失败,消息的json结构不正确",get_front_msg_from_subdir(), g_front_seg_index,FRONT_INST.c_str(),G_MQCONSUMER_TOPIC_LOG.c_str()); } } @@ -1976,7 +1976,7 @@ int myMessageCallbackrecall(CPushConsumer* consumer, CMessageExt* msg) } else{ std::cerr << "recall data is NULL." << std::endl; - DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程处理topic:%s_%s的补招触发消息失败,消息的json结构不正确",get_front_msg_from_subdir(), g_front_seg_index,FRONT_INST.c_str(),G_MQCONSUMER_TOPIC_RC.c_str()); + DIY_ERRORLOG_CODE("process",LOG_CODE_RECALL,"【ERROR】前置的%s%d号进程处理topic:%s_%s的补招触发消息失败,消息的json结构不正确",get_front_msg_from_subdir(), g_front_seg_index,FRONT_INST.c_str(),G_MQCONSUMER_TOPIC_RC.c_str()); } } diff --git a/log4cplus/log4.h b/log4cplus/log4.h index 9606687..6ab812e 100644 --- a/log4cplus/log4.h +++ b/log4cplus/log4.h @@ -3,6 +3,8 @@ #ifdef __cplusplus +#include // ★新增:需要 MDCGuard + #include #include @@ -88,7 +90,22 @@ void log_error(const char* key, const char* msg); void send_reply_to_kafka_c(const char* guid, const char* step, const char* result); void format_log_msg(char* buf, size_t buf_size, const char* fmt, ...); -//宏定义 +// ====================== ★新增:线程局部变量透传 code ====================== +// 说明:使用编译器的 TLS(__thread)保存当前日志的 code 值。 +// 在每次打日志前写入,打完后恢复,Appender 读取该值写入 JSON。 +#if defined(__GNUC__) + #define LOG_TLS __thread +#else + // 若编译器不支持 __thread,可替换为 C++11 thread_local(但你的工程多为 C++98/C 混编,优先 __thread) + #define LOG_TLS __thread +#endif + +extern LOG_TLS int g_log_code_tls; // 声明为 TLS 变量,定义见 log4.cpp +// ====================== ★新增结束 ====================== + + +// ====================== 日志宏区域 ====================== +// 原始不带 code 的实现(兼容/复用) #define DIY_LOG(LEVEL_FUNC, KEY, ...) \ do { \ char buf[256]; \ @@ -96,11 +113,52 @@ void format_log_msg(char* buf, size_t buf_size, const char* fmt, ...); LEVEL_FUNC(KEY, buf); \ } while (0) -#define DIY_ERRORLOG(KEY, ...) DIY_LOG(log_error, KEY, __VA_ARGS__) -#define DIY_WARNLOG(KEY, ...) DIY_LOG(log_warn, KEY, __VA_ARGS__) -#define DIY_INFOLOG(KEY, ...) DIY_LOG(log_info, KEY, __VA_ARGS__) -#define DIY_DEBUGLOG(KEY, ...) DIY_LOG(log_debug, KEY, __VA_ARGS__) +// ★新增:带 code 的实现(C/C++ 通用,使用 TLS 保存/恢复) +#define DIY_LOG_CODE(LEVEL_FUNC, KEY, CODE_INT, ...) \ + do { \ + int __old_code__ = g_log_code_tls; /* 备份旧值 */ \ + g_log_code_tls = (int)(CODE_INT); /* 设置本次日志 code */ \ + char buf[256]; \ + format_log_msg(buf, sizeof(buf), __VA_ARGS__); \ + LEVEL_FUNC(KEY, buf); /* 输出日志 */ \ + g_log_code_tls = __old_code__; /* 恢复旧值 */ \ + } while (0) +// ★修改:默认宏改为 code=0(兼容原有用法) +#define DIY_ERRORLOG(KEY, ...) DIY_LOG_CODE(log_error, KEY, 0, __VA_ARGS__) // ★修改:默认 code=0 +#define DIY_WARNLOG(KEY, ...) DIY_LOG_CODE(log_warn, KEY, 0, __VA_ARGS__) // ★修改:默认 code=0 +#define DIY_INFOLOG(KEY, ...) DIY_LOG_CODE(log_info, KEY, 0, __VA_ARGS__) // ★修改:默认 code=0 +#define DIY_DEBUGLOG(KEY, ...) DIY_LOG_CODE(log_debug, KEY, 0, __VA_ARGS__) // ★修改:默认 code=0 + +// ★新增:显式传入 code 的便捷宏 +// 用法示例:DIY_WARNLOG_CODE(full_key_m_c, warn_recallstart, "【WARN】监测点:%s ...", ...); +#define DIY_ERRORLOG_CODE(KEY, CODE_INT, ...) DIY_LOG_CODE(log_error, KEY, CODE_INT, __VA_ARGS__) // ★新增 +#define DIY_WARNLOG_CODE(KEY, CODE_INT, ...) DIY_LOG_CODE(log_warn, KEY, CODE_INT, __VA_ARGS__) // ★新增 +#define DIY_INFOLOG_CODE(KEY, CODE_INT, ...) DIY_LOG_CODE(log_info, KEY, CODE_INT, __VA_ARGS__) // ★新增 +#define DIY_DEBUGLOG_CODE(KEY, CODE_INT, ...) DIY_LOG_CODE(log_debug, KEY, CODE_INT, __VA_ARGS__) // ★新增 + + +// ====================== 日志宏区域 ====================== + + +typedef enum LogCode { + LOG_CODE_OTHER = 99, /* 其他类型 */ + LOG_CODE_LEDGER = 100, /* 台账类型 */ + LOG_CODE_RPTINIT = 101, /* 报告初始化 */ + LOG_CODE_ICD_AND_DOWNLOAD = 200, /* ICD 和文件下载类型 */ + LOG_CODE_TRANSIENT = 300, /* 暂态发生 */ + LOG_CODE_TRANSIENT_COMM = 301, /* 暂态接口 */ + LOG_CODE_COMTRADE_FILE = 302, /* 录波文件(Comtrade) */ + LOG_CODE_MQ = 400, /* MQ发送 */ + LOG_CODE_RT_DATA = 401, /* 实时数据 */ + LOG_CODE_LEDGER_UPDATE = 402, /* 台账更新 */ + LOG_CODE_PROCESS_CONTROL = 403, /* 进程控制 */ + LOG_CODE_RECALL = 404, /* 补招相关 */ + LOG_CODE_LOG_REQUEST = 405, /* 日志请求 */ + LOG_CODE_REPORT = 500, /* 报告处理 */ + LOG_CODE_COMM = 600, /* 通讯状态 */ + LOG_CODE_SPACE_ALARM = 700 /* 空间告警 */ +} LogCode; #ifdef __cplusplus } diff --git a/mms/main.c b/mms/main.c index 1211202..cd81896 100644 --- a/mms/main.c +++ b/mms/main.c @@ -232,7 +232,7 @@ int main(int argc, const char **argv) //char buf[256]; //format_log_msg(buf,sizeof(buf),"前置的%s%d号进程 进程级日志初始化完毕", get_front_msg_from_subdir(), g_front_seg_index); //log_debug("process", buf); - DIY_WARNLOG("process","【WARN】前置的%s%d号进程 进程级日志初始化完毕", get_front_msg_from_subdir(), g_front_seg_index); + DIY_INFOLOG("process","【WARN】前置的%s%d号进程 进程级日志初始化完毕", get_front_msg_from_subdir(), g_front_seg_index); #ifdef _OS_UNIX_ #ifdef QT_NO_DEBUG @@ -268,7 +268,7 @@ int main(int argc, const char **argv) //char buf[256]; //format_log_msg(buf,sizeof(buf),"前置的%s%d号进程 台账初始化失败", get_front_msg_from_subdir(), g_front_seg_index); //log_error("process", buf); - DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程 台账初始化失败", get_front_msg_from_subdir(), g_front_seg_index); + DIY_ERRORLOG_CODE("process",LOG_CODE_LEDGER,"【ERROR】前置的%s%d号进程 台账初始化失败", get_front_msg_from_subdir(), g_front_seg_index); return rv; } @@ -277,7 +277,7 @@ int main(int argc, const char **argv) //char buf[256]; //format_log_msg(buf,sizeof(buf),"前置的%s%d号进程 线程初始化失败", get_front_msg_from_subdir(), g_front_seg_index); //log_error("process", buf); - DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程 线程初始化失败", get_front_msg_from_subdir(), g_front_seg_index); + DIY_ERRORLOG_CODE("process",LOG_CODE_OTHER,"【ERROR】前置的%s%d号进程 线程初始化失败", get_front_msg_from_subdir(), g_front_seg_index); return rv; } @@ -324,7 +324,7 @@ int main(int argc, const char **argv) //char buf[256]; //format_log_msg(buf,sizeof(buf),"前置的业务线程死锁,退出进程"); //log_error("process", buf); - DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程 业务线程死锁,退出进程", get_front_msg_from_subdir(), g_front_seg_index); + DIY_ERRORLOG_CODE("process",LOG_CODE_OTHER,"【ERROR】前置的%s%d号进程 业务线程死锁,退出进程", get_front_msg_from_subdir(), g_front_seg_index); apr_sleep(apr_time_from_sec(10)); exit(-1039); diff --git a/mms/mms_process.c b/mms/mms_process.c index 7edc65c..cc764cb 100644 --- a/mms/mms_process.c +++ b/mms/mms_process.c @@ -184,7 +184,7 @@ void closeChannel(chnl_usr_t *chnl_usr) ret = mms_disconnectFromServer(chnl_usr->net_info,&chnl_usr->m_reqCtrl); echo_warn("---------end disconnectFromServer!\n"); - DIY_WARNLOG(full_key_t_c,"【WARN】前置与终端%s - ip端口%s:%d 断开连接", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port); + DIY_WARNLOG_CODE(full_key_t_c,LOG_CODE_COMM,"【WARN】前置与终端%s - ip端口%s:%d 断开连接", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port); if (ret != SD_SUCCESS){ echo_warn("---------disconnectFromServer success!\n"); @@ -368,14 +368,14 @@ void ChannelCheckIECReports(chnl_usr_t *chnl_usr) LD_info->registcount++; if (LD_info->registcount <= 5) { - DIY_WARNLOG(full_key_m_c, "【WARN】监测点:%s - id:%s注册报告失败,报告名:%s", + DIY_WARNLOG_CODE(full_key_m_c,LOG_CODE_REPORT, "【WARN】监测点:%s - id:%s注册报告失败,报告名:%s", LD_info->name, LD_info->mp_id, rpt_inst_name); } // 到5次就不再打印,并标记 if (LD_info->registcount > 5) { LD_info->has_logged_regist = true; - DIY_WARNLOG(full_key_m_c, "【WARN】监测点:%s - id:%s注册报告失败日志已达本次注册上限,不再输出,请检查装置icd和映射文件是否匹配或者装置存在过多连接", + DIY_WARNLOG_CODE(full_key_m_c,LOG_CODE_REPORT,"【WARN】监测点:%s - id:%s注册报告失败日志已达本次注册上限,不再输出,请检查装置icd和映射文件是否匹配或者装置存在过多连接", LD_info->name, LD_info->mp_id); } } @@ -398,7 +398,7 @@ void ChannelCheckIECReports(chnl_usr_t *chnl_usr) //mq日志 LD_info->has_logged_regist = FALSE; LD_info->registcount = 0; - DIY_WARNLOG(full_key_m_c,"【WARN】监测点:%s - id:%s注册报告成功,报告名:%s", LD_info->name,LD_info->mp_id,rpt_inst_name); + DIY_WARNLOG_CODE(full_key_m_c,LOG_CODE_REPORT,"【WARN】监测点:%s - id:%s注册报告成功,报告名:%s", LD_info->name,LD_info->mp_id,rpt_inst_name); // add here to GI not the same time GIoffset = 0.5 * g_pt61850app->giTime; @@ -426,7 +426,7 @@ void ChannelCheckIECReports(chnl_usr_t *chnl_usr) APR_EGENERAL, LD_info->ied->id,LD_info->cpuno,LD_info->LD_name,rpt_inst_name,chnl_usr->ip_str,chnl_usr->chnl_id); //mq日志 - DIY_WARNLOG(full_key_m_c,"【WARN】监测点:%s - id:%s注销报告失败,报告名:%s", LD_info->name,LD_info->mp_id,rpt_inst_name); + DIY_WARNLOG_CODE(full_key_m_c,LOG_CODE_REPORT,"【WARN】监测点:%s - id:%s注销报告失败,报告名:%s", LD_info->name,LD_info->mp_id,rpt_inst_name); } else { @@ -515,11 +515,11 @@ void ChannelCheckIECLogs(chnl_usr_t *chnl_usr) if(strcmp(cfg1.ValueOfTimeUnit, "utc") == 0){//装置时间是utc还是北京 utc_or_beijing = 28800;//秒 - DIY_WARNLOG(full_key_m_c,"【WARN】监测点:%s - id:%s开始补招数据,下发补招时间为utc时间,监测点对应装置型号:%s", LD_info->name,LD_info->mp_id,ied_usr->dev_type); + DIY_WARNLOG_CODE(full_key_m_c,LOG_CODE_RECALL,"【WARN】监测点:%s - id:%s开始补招数据,下发补招时间为utc时间,监测点对应装置型号:%s", LD_info->name,LD_info->mp_id,ied_usr->dev_type); } else{ utc_or_beijing = 0; - DIY_WARNLOG(full_key_m_c,"【WARN】监测点:%s - id:%s开始补招数据,下发补招时间为beijing时间,监测点对应装置型号:%s", LD_info->name,LD_info->mp_id,ied_usr->dev_type); + DIY_WARNLOG_CODE(full_key_m_c,LOG_CODE_RECALL,"【WARN】监测点:%s - id:%s开始补招数据,下发补招时间为beijing时间,监测点对应装置型号:%s", LD_info->name,LD_info->mp_id,ied_usr->dev_type); } ////////////////////////////////////////////////////////////// @@ -559,7 +559,7 @@ void ChannelCheckIECLogs(chnl_usr_t *chnl_usr) LD_info->ied->id, LD_info->cpuno, LD_info->LD_name, loginfo->logName, chnl_usr->ip_str, chnl_usr->chnl_id); //mq日志 - DIY_ERRORLOG(full_key_m_c,"【ERROR】监测点:%s - id:%s补招数据失败 - 失败时间点:%lld 至 %lld", LD_info->name,LD_info->mp_id,loginfo->start_time,loginfo->end_time); + DIY_ERRORLOG_CODE(full_key_m_c,LOG_CODE_RECALL,"【ERROR】监测点:%s - id:%s补招数据失败 - 失败时间点:%lld 至 %lld", LD_info->name,LD_info->mp_id,loginfo->start_time,loginfo->end_time); failed_count++; } @@ -582,7 +582,7 @@ void ChannelCheckIECLogs(chnl_usr_t *chnl_usr) //不管是否成功,这个补招文件必须删除,可能出现一直失败,循环读取文件和循环补招导致程序崩溃202050724lnk //if (failed_count==0) {//成功 Delete_recall_Xml(LD_info->mp_id); - DIY_WARNLOG(full_key_m_c,"【WARN】监测点:%s - id:%s结束补招数据", LD_info->name,LD_info->mp_id); + DIY_WARNLOG_CODE(full_key_m_c,LOG_CODE_RECALL,"【WARN】监测点:%s - id:%s结束补招数据", LD_info->name,LD_info->mp_id); //} } @@ -1387,13 +1387,13 @@ void check_disk_quota() //printf("Current user disk free size: %dMB ,total size: %dMB \n",freeSizeMB,totalSizeMB); if (freeSizeMBchnl->ied->usr_ext))->lastconnectstat = true; ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect = false; - DIY_WARNLOG(full_key_t_c,"【WARN】终端%s - ip端口:%s:%d连接成功", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port); + DIY_WARNLOG_CODE(full_key_t_c,LOG_CODE_COMM,"【WARN】终端%s - ip端口:%s:%d连接成功", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port); mvl_free_req_ctrl(chnl_usr->m_reqCtrl); chnl_usr->m_reqCtrl = NULL; @@ -1591,11 +1591,11 @@ void CheckNextNotConnectedChannel() if(true == ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->lastconnectstat){ ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->lastconnectstat = false; ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect = true; - DIY_WARNLOG(full_key_t_c,"【WARN】终端%s - ip/端口:%s:%d - 识别码/秘钥:%s/%s,从开始连接到目前已经%i秒,连接失败,断开连接!", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port,((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->dev_series,((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->dev_key,secsSince); + DIY_WARNLOG_CODE(full_key_t_c,LOG_CODE_COMM,"【WARN】终端%s - ip/端口:%s:%d - 识别码/秘钥:%s/%s,从开始连接到目前已经%i秒,连接失败,断开连接!", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port,((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->dev_series,((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->dev_key,secsSince); } else if(false == ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->lastconnectstat && false == ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect){ ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect = true; - DIY_WARNLOG(full_key_t_c,"【WARN】终端%s - ip/端口:%s:%d - 识别码/秘钥:%s/%s,从开始连接到目前已经%i秒,连接失败,断开连接!", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port,((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->dev_series,((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->dev_key,secsSince); + DIY_WARNLOG_CODE(full_key_t_c,LOG_CODE_COMM,"【WARN】终端%s - ip/端口:%s:%d - 识别码/秘钥:%s/%s,从开始连接到目前已经%i秒,连接失败,断开连接!", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port,((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->dev_series,((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->dev_key,secsSince); } mvl_free_req_ctrl(chnl_usr->m_reqCtrl); @@ -1618,11 +1618,11 @@ void CheckNextNotConnectedChannel() if(true == ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->lastconnectstat){ ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->lastconnectstat = false; ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect = true; - DIY_WARNLOG(full_key_t_c,"【WARN】终端%s - ip端口:%s:%d,从开始连接到目前已经300秒,未能获取连接响应,断开连接!", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port); + DIY_WARNLOG_CODE(full_key_t_c,LOG_CODE_COMM,"【WARN】终端%s - ip端口:%s:%d,从开始连接到目前已经300秒,未能获取连接响应,断开连接!", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port); } else if(false == ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->lastconnectstat && false == ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect){ ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->has_logged_disconnect = true; - DIY_WARNLOG(full_key_t_c,"【WARN】终端%s - ip端口:%s:%d,从开始连接到目前已经300秒,未能获取连接响应,断开连接!", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port); + DIY_WARNLOG_CODE(full_key_t_c,LOG_CODE_COMM,"【WARN】终端%s - ip端口:%s:%d,从开始连接到目前已经300秒,未能获取连接响应,断开连接!", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port); } @@ -1706,7 +1706,7 @@ void CheckNextNotConnectedChannel() connectlog_pgsql(ied_usr->terminal_id,convertMsToDateTimeString(t_now),0); //mq日志 - DIY_WARNLOG(full_key_t_c,"【WARN】终端%s - ip端口:%s:%d 断连完成,关闭连接通道", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port); + DIY_WARNLOG_CODE(full_key_t_c,LOG_CODE_COMM,"【WARN】终端%s - ip端口:%s:%d 断连完成,关闭连接通道", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port); } else @@ -1733,7 +1733,7 @@ void CheckNextNotConnectedChannel() connectlog_pgsql(ied_usr->terminal_id,convertMsToDateTimeString(t_now),0); //mq日志 - DIY_WARNLOG(full_key_t_c,"【WARN】终端%s - ip端口:%s:%d 断连未完成,但是已经超时180秒,关闭连接通道", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port); + DIY_WARNLOG_CODE(full_key_t_c,LOG_CODE_COMM,"【WARN】终端%s - ip端口:%s:%d 断连未完成,但是已经超时180秒,关闭连接通道", ((ied_usr_t*)(chnl_usr->chnl->ied->usr_ext))->terminal_id,chnl_usr->ip_str,chnl_usr->chnl->port); } } @@ -1848,6 +1848,30 @@ apr_status_t prepare_call_cn_wavelist(LD_info_t *LD_info, int FltNum) return APR_SUCCESS; } +//判断暂态记录非空,lnk20250818 +int ld_has_qvvr_nonempty(const LD_info_t* info) +{ + if (!info) return 0; + + /* 规则1:索引计数 > 0 直接认为非空 */ + if (info->qvvr_idx > 0) return 1; + + /* 规则2:扫描数组,任意一项出现被使用/有时间/有名称/有数值 即认为非空 */ + int i; + for (i = 0; i < QVVR_NUM; ++i) { + const QVVR_t* it = &info->qvvr[i]; + + /* 只要有任一“有效迹象”就视为非空 */ + if (it->used_status != 0 ) + { + return 1; + } + } + + /* 都没有则为空 */ + return 0; +} + apr_status_t call_cn_wavelist(LD_info_t *LD_info ) { int ret ; @@ -1909,7 +1933,9 @@ apr_status_t call_cn_wavelist(LD_info_t *LD_info ) //WW 2023-11-01 end if (ret2 !=APR_SUCCESS){ //mq日志 - DIY_WARNLOG(full_key_m_c,"【WARN】监测点:%s - id:%s匹配录波文件失败", LD_info->name,LD_info->mp_id); + DIY_WARNLOG_CODE(full_key_m_c,LOG_CODE_COMTRADE_FILE,"【WARN】监测点:%s - id:%s前置记录的录波事件上传的录波号段%d与从装置获取的录波文件列表匹配失败,装置没有对应的号段的录波文件,前置清除这个录波号段", LD_info->name,LD_info->mp_id,LD_info->FltNum[i]); + //lnk20250819装置没有对应的文件时清除录波号段 + LD_info->FltNum[i] = -1; return ret2; } @@ -2142,9 +2168,9 @@ apr_status_t call_cn_wavelist(LD_info_t *LD_info ) } - else + else if(ld_has_qvvr_nonempty(LD_info))//防止手动录波日志还一直上送 { - DIY_ERRORLOG(full_key_m_c,"【NORMAL】监测点:%s - id:%s匹配录波文件失败,请检查装置的暂态时间是秒还是毫秒,并修改映射文件", LD_info->name,LD_info->mp_id); + DIY_ERRORLOG_CODE(full_key_m_c,LOG_CODE_COMTRADE_FILE,"【ERROR】监测点:%s - id:%s匹配录波文件失败,请检查装置的暂态时间是秒还是毫秒,并根据实际修改映射文件;也有可能装置触发了手动录波而不是发生暂态事件", LD_info->name,LD_info->mp_id); } } @@ -2155,7 +2181,8 @@ apr_status_t call_cn_wavelist(LD_info_t *LD_info ) if (ied && chnl_usr){ echo_warn2("mms_mvla_fdir Failed: IED [%d] %s \n", ied->id , chnl_usr->ip_str) ; //mq日志 - DIY_WARNLOG(full_key_m_c,"【WARN】监测点:%s - id:%s召唤录波文件失败", LD_info->name,LD_info->mp_id); + DIY_WARNLOG_CODE(full_key_m_c,LOG_CODE_COMTRADE_FILE,"【WARN】监测点:%s - id:%s召唤录波文件失败,放弃这个号段", LD_info->name,LD_info->mp_id); + LD_info->FltNum[i] = -1; } return APR_EAGAIN; diff --git a/mms/mmscli_rpt.c b/mms/mmscli_rpt.c index ebcfdf1..ded83e7 100644 --- a/mms/mmscli_rpt.c +++ b/mms/mmscli_rpt.c @@ -1162,7 +1162,7 @@ ST_VOID u_iec_rpt_ind_data_by_devtype(MVL_VAR_ASSOC** info_va, echo_err3("Ignore this report due to line_id invalid , Report From %s %s %s !!!", APR_EGENERAL, chnl_usr->ip_str, LD_info->LD_name, rcb_info->RptID); //mq日志 - DIY_ERRORLOG(full_key_m_d,"【ERROR】前置不处理这个监测点:%s - id:%s的报告,报告名称:%s,原因是监测点的序号非法", LD_info->name,LD_info->mp_id,rcb_info->RptID); + DIY_ERRORLOG_CODE(full_key_m_d,LOG_CODE_REPORT,"【ERROR】前置不处理这个监测点:%s - id:%s的报告,报告名称:%s,原因是监测点的序号非法", LD_info->name,LD_info->mp_id,rcb_info->RptID); } printf("[END Process] Report From %s:%d %s %s ,va_total = %i ,【count = %i】 \n", diff --git a/mms/rdb_client.c b/mms/rdb_client.c index 9a89cef..8f7aa47 100644 --- a/mms/rdb_client.c +++ b/mms/rdb_client.c @@ -194,7 +194,7 @@ apr_status_t init_rdb() //char buf[256]; //format_log_msg(buf,sizeof(buf),"前置的%s%d号进程调用web台账接口失败", get_front_msg_from_subdir(), g_front_seg_index); //log_error("process", buf); - DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程调用web台账接口失败", get_front_msg_from_subdir(), g_front_seg_index); + DIY_ERRORLOG_CODE("process",LOG_CODE_LEDGER,"【ERROR】前置的%s%d号进程调用web台账接口失败", get_front_msg_from_subdir(), g_front_seg_index); return rv; } @@ -209,7 +209,7 @@ apr_status_t init_rdb() //char buf[256]; //format_log_msg(buf,sizeof(buf),"前置的%s%d号进程调用web模型接口失败", get_front_msg_from_subdir(), g_front_seg_index); //log_error("process", buf); - DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程调用web模型接口失败", get_front_msg_from_subdir(), g_front_seg_index); + DIY_ERRORLOG_CODE("process",LOG_CODE_ICD_AND_DOWNLOAD,"【ERROR】前置的%s%d号进程调用web模型接口失败", get_front_msg_from_subdir(), g_front_seg_index); return rv; } @@ -220,7 +220,7 @@ apr_status_t init_rdb() if (rv != APR_SUCCESS) { echo_errg("Failed to parse report log define ini file! \n"); - DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程报告初始化失败", get_front_msg_from_subdir(), g_front_seg_index); + DIY_ERRORLOG_CODE("process",LOG_CODE_RPTINIT,"【ERROR】前置的%s%d号进程报告初始化失败", get_front_msg_from_subdir(), g_front_seg_index); return rv; } @@ -228,7 +228,7 @@ apr_status_t init_rdb() if (app_get_private_config(g_my_conf_fname) != APR_SUCCESS) { echo_errg("Failed when processing private configuration\n"); - DIY_ERRORLOG("process","【ERROR】前置的%s%d号进程读取mms配置失败", get_front_msg_from_subdir(), g_front_seg_index); + DIY_ERRORLOG_CODE("process",LOG_CODE_OTHER,"【ERROR】前置的%s%d号进程读取mms配置失败", get_front_msg_from_subdir(), g_front_seg_index); return APR_EGENERAL; } diff --git a/mms/rdb_ext_utils.c b/mms/rdb_ext_utils.c index 04d6c9d..1314f0d 100644 --- a/mms/rdb_ext_utils.c +++ b/mms/rdb_ext_utils.c @@ -562,11 +562,11 @@ void processQVVR_end(LD_info_t* LD_info) long long utc_or_beijing; if(strcmp(cfg.UnitOfTimeUnit, "1") == 0){//持续时间上送的是秒1还是毫秒0 s_or_ms = 0.001; - DIY_WARNLOG(full_key_m_c,"【WARN】监测点:%s - id:%s上送的暂态持续时间单位是秒,监测点对应装置型号:%s",LD_info->name,LD_info->mp_id,ied_usr->dev_type); + DIY_WARNLOG_CODE(full_key_m_c,LOG_CODE_TRANSIENT,"【WARN】监测点:%s - id:%s上送的暂态持续时间单位是秒,监测点对应装置型号:%s",LD_info->name,LD_info->mp_id,ied_usr->dev_type); } else{ s_or_ms = 1.0; - DIY_WARNLOG(full_key_m_c,"【WARN】监测点:%s - id:%s上送的暂态持续时间单位是毫秒,监测点对应装置型号:%s",LD_info->name,LD_info->mp_id,ied_usr->dev_type); + DIY_WARNLOG_CODE(full_key_m_c,LOG_CODE_TRANSIENT,"【WARN】监测点:%s - id:%s上送的暂态持续时间单位是毫秒,监测点对应装置型号:%s",LD_info->name,LD_info->mp_id,ied_usr->dev_type); } if(strcmp(cfg.ValueOfTimeUnit, "utc") == 0){//上送的是utc还是北京 @@ -638,7 +638,7 @@ void processQVVR_end(LD_info_t* LD_info) //匹配后再发qvvr,起始时间要填暂态触发的时间,就是第一次事件上送时只有时间没有值的那个时间 //mq日志 - DIY_WARNLOG(full_key_m_d,"【WARN】监测点%s - id:%s 发生暂态事件",LD_info->name,LD_info->mp_id); + DIY_WARNLOG_CODE(full_key_m_d,LOG_CODE_TRANSIENT,"【WARN】监测点%s - id:%s 发生暂态事件",LD_info->name,LD_info->mp_id); ret = transfer_json_qvvr_data(g_node_id, //这个参数没有使用 LD_info->line_id, //监测点序号