Compare commits
4 Commits
44852a0846
...
7725fd2d87
| Author | SHA1 | Date | |
|---|---|---|---|
| 7725fd2d87 | |||
| dd01a31a77 | |||
| 1014aeafbc | |||
| c5ded4c032 |
@@ -49,11 +49,11 @@ fi
|
||||
|
||||
# 判断是否为 debug 版本
|
||||
if [[ "$1" == "debug" ]]; then
|
||||
CXXFLAGS="-std=c++11 -g -O0"
|
||||
CXXFLAGS="-std=c++11 -g -O0 -Wformat -Wformat-security -Werror=format"
|
||||
TARGET="${TARGET}d"
|
||||
echo "🟢 编译调试版本 (-g -O0)"
|
||||
else
|
||||
CXXFLAGS="-std=c++11 -O2 -static-libstdc++ -static-libgcc"
|
||||
CXXFLAGS="-std=c++11 -O2 -static-libstdc++ -static-libgcc -Wformat -Wformat-security -Werror=format"
|
||||
echo "🔵 编译正式版本 (-O2 -static)"
|
||||
fi
|
||||
|
||||
|
||||
@@ -2922,11 +2922,19 @@ bool compare_qvvr_and_file(const std::string& cfg_path, std::vector<qvvr_data>&
|
||||
// 遍历所有暂态事件,查找与 trig_tm 匹配的
|
||||
for (auto& data : data_list) {
|
||||
long long diff = static_cast<long long>(data.QVVR_time) - trig_tm;
|
||||
|
||||
std::cout << "[调试] QVVR_time=" << data.QVVR_time
|
||||
<< ", trig_tm=" << trig_tm
|
||||
<< ", diff=" << diff << "\n";
|
||||
|
||||
if (std::abs(diff) <= 1) {
|
||||
|
||||
data.is_pair = true; // 标记为已匹配
|
||||
|
||||
matched_data = data; // 返回匹配到的事件
|
||||
|
||||
std::cout << "[调试] 匹配成功,diff=" << diff << "\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -3312,93 +3320,102 @@ bool update_qvvr_file_download(const std::string& filename_with_mac_in, const st
|
||||
// 找到其中的 .cfg 文件进行匹配
|
||||
for (const auto& fpath : qfile.file_download) {
|
||||
std::string fname = extract_filename1(fpath);
|
||||
if (fname.size() >= 4 && fname.substr(fname.size() - 4) == ".cfg") {
|
||||
// 提取文件时标和监测点事件的时标匹配
|
||||
qvvr_data matched;
|
||||
if (compare_qvvr_and_file(fpath, monitor.qvvrevent.qvvrdata,matched)) {
|
||||
qfile.is_pair = true; // 文件与事件匹配成功
|
||||
if (fname.size() >= 4) {
|
||||
std::string ext = fname.substr(fname.size() - 4);
|
||||
std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
|
||||
if (ext == ".cfg") {
|
||||
//if (fname.size() >= 4 && fname.substr(fname.size() - 4) == ".cfg") {
|
||||
// 提取文件时标和监测点事件的时标匹配
|
||||
qvvr_data matched;
|
||||
if (compare_qvvr_and_file(fpath, monitor.qvvrevent.qvvrdata,matched)) {
|
||||
qfile.is_pair = true; // 文件与事件匹配成功
|
||||
|
||||
// ★新增:上传前拷贝“将要上传的文件列表”,避免锁外用容器引用
|
||||
std::vector<std::string> files_to_send(qfile.file_download.begin(),
|
||||
qfile.file_download.end());
|
||||
// ★新增:上传前拷贝“将要上传的文件列表”,避免锁外用容器引用
|
||||
std::vector<std::string> files_to_send(qfile.file_download.begin(),
|
||||
qfile.file_download.end());
|
||||
|
||||
// ★新增:构造一个临时 qvvr_file,仅用于上传(不改动原结构)
|
||||
qvvr_file tmp_send;
|
||||
tmp_send.file_download.assign(files_to_send.begin(), files_to_send.end());
|
||||
// ★新增:构造一个临时 qvvr_file,仅用于上传(不改动原结构)
|
||||
qvvr_file tmp_send;
|
||||
tmp_send.file_download.assign(files_to_send.begin(), files_to_send.end());
|
||||
|
||||
|
||||
// 发送所有文件(已下载完成)
|
||||
std::string wavepath;
|
||||
// 发送所有文件(已下载完成)
|
||||
std::string wavepath;
|
||||
|
||||
// ★在解锁前,备份“签名”,用于回锁后定位同一个 qfile
|
||||
std::set<std::string> sig_names(qfile.file_name.begin(), qfile.file_name.end());
|
||||
std::set<std::string> sig_downs(qfile.file_download.begin(), qfile.file_download.end());
|
||||
// ★在解锁前,备份“签名”,用于回锁后定位同一个 qfile
|
||||
std::set<std::string> sig_names(qfile.file_name.begin(), qfile.file_name.end());
|
||||
std::set<std::string> sig_downs(qfile.file_download.begin(), qfile.file_download.end());
|
||||
|
||||
// ★修改:把上传与上送 JSON 放到“解锁区间”
|
||||
lock.unlock(); // ★新增:提前解锁
|
||||
// ★修改:把上传与上送 JSON 放到“解锁区间”
|
||||
lock.unlock(); // ★新增:提前解锁
|
||||
|
||||
if (SendAllQvvrFiles(qfile, wavepath)) {
|
||||
//文件发送成功后更新事件
|
||||
|
||||
transfer_json_qvvr_data(terminal_id,
|
||||
logical_seq,
|
||||
matched.QVVR_Amg,
|
||||
matched.QVVR_PerTime,
|
||||
matched.QVVR_time,
|
||||
matched.QVVR_type,
|
||||
matched.phase,
|
||||
wavepath);
|
||||
if (SendAllQvvrFiles(qfile, wavepath)) {
|
||||
//文件发送成功后更新事件
|
||||
|
||||
// ★新增:上传成功后再加锁,准备修改台账
|
||||
lock.lock();
|
||||
transfer_json_qvvr_data(terminal_id,
|
||||
logical_seq,
|
||||
matched.QVVR_Amg,
|
||||
matched.QVVR_PerTime,
|
||||
matched.QVVR_time,
|
||||
matched.QVVR_type,
|
||||
matched.phase,
|
||||
wavepath);
|
||||
|
||||
// 删除上传成功的文件
|
||||
for (const auto& uploaded_file : qfile.file_download) {
|
||||
if (std::remove(uploaded_file.c_str()) != 0) {
|
||||
std::cerr << "[Cleanup] Failed to delete file: " << uploaded_file << "\n";
|
||||
} else {
|
||||
std::cout << "[Cleanup] Deleted uploaded file: " << uploaded_file << "\n";
|
||||
// ★新增:上传成功后再加锁,准备修改台账
|
||||
lock.lock();
|
||||
|
||||
// 删除上传成功的文件
|
||||
for (const auto& uploaded_file : qfile.file_download) {
|
||||
if (std::remove(uploaded_file.c_str()) != 0) {
|
||||
std::cerr << "[Cleanup] Failed to delete file: " << uploaded_file << "\n";
|
||||
} else {
|
||||
std::cout << "[Cleanup] Deleted uploaded file: " << uploaded_file << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ★替换原来的 i<size 判断为:按签名查找当前容器里的那一条
|
||||
auto it_qf = std::find_if(monitor.qvvrevent.qvvrfile.begin(),
|
||||
monitor.qvvrevent.qvvrfile.end(),
|
||||
[&](const qvvr_file& x){
|
||||
std::set<std::string> n(x.file_name.begin(), x.file_name.end());
|
||||
std::set<std::string> d(x.file_download.begin(), x.file_download.end());
|
||||
return n==sig_names && d==sig_downs;
|
||||
});
|
||||
|
||||
if (it_qf != monitor.qvvrevent.qvvrfile.end()) {
|
||||
monitor.qvvrevent.qvvrfile.erase(it_qf); // ✔ 删到同一条
|
||||
} else {
|
||||
std::cerr << "[Cleanup] qvvrfile changed; target group not found, skip erase\n";
|
||||
}
|
||||
// ★替换原来的 i<size 判断为:按签名查找当前容器里的那一条
|
||||
auto it_qf = std::find_if(monitor.qvvrevent.qvvrfile.begin(),
|
||||
monitor.qvvrevent.qvvrfile.end(),
|
||||
[&](const qvvr_file& x){
|
||||
std::set<std::string> n(x.file_name.begin(), x.file_name.end());
|
||||
std::set<std::string> d(x.file_download.begin(), x.file_download.end());
|
||||
return n==sig_names && d==sig_downs;
|
||||
});
|
||||
|
||||
if (it_qf != monitor.qvvrevent.qvvrfile.end()) {
|
||||
monitor.qvvrevent.qvvrfile.erase(it_qf); // ✔ 删到同一条
|
||||
} else {
|
||||
std::cerr << "[Cleanup] qvvrfile changed; target group not found, skip erase\n";
|
||||
}
|
||||
|
||||
//清除暂态事件
|
||||
auto it = std::find_if(
|
||||
monitor.qvvrevent.qvvrdata.begin(),
|
||||
monitor.qvvrevent.qvvrdata.end(),
|
||||
[&](const qvvr_data& d) {
|
||||
return d.QVVR_time == matched.QVVR_time;
|
||||
});
|
||||
|
||||
if (it != monitor.qvvrevent.qvvrdata.end()) {
|
||||
monitor.qvvrevent.qvvrdata.erase(it);
|
||||
}
|
||||
}
|
||||
//清除暂态事件
|
||||
auto it = std::find_if(
|
||||
monitor.qvvrevent.qvvrdata.begin(),
|
||||
monitor.qvvrevent.qvvrdata.end(),
|
||||
[&](const qvvr_data& d) {
|
||||
return d.QVVR_time == matched.QVVR_time;
|
||||
});
|
||||
|
||||
if (it != monitor.qvvrevent.qvvrdata.end()) {
|
||||
monitor.qvvrevent.qvvrdata.erase(it);
|
||||
}
|
||||
}
|
||||
else {
|
||||
lock.lock(); // ★新增:失败时补回锁
|
||||
std::cerr << "[update_qvvr_file_download] Failed to send qvvr files for logical_seq=" << logical_seq << std::endl;
|
||||
}
|
||||
}
|
||||
else {
|
||||
lock.lock(); // ★新增:失败时补回锁
|
||||
std::cerr << "[update_qvvr_file_download] Failed to send qvvr files for logical_seq=" << logical_seq << std::endl;
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cout << "[update_qvvr_file_download] No matching qvvr_data found for cfg file: " << fpath << std::endl;
|
||||
}
|
||||
break; // 只处理第一个 cfg 文件
|
||||
std::cout << "[update_qvvr_file_download] No matching qvvr_data found for cfg file: " << fpath << std::endl;
|
||||
}
|
||||
|
||||
break; // 只处理第一个 cfg 文件
|
||||
}//end if ext==.cfg
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cout << "[update_qvvr_file_download] Filename too short to check extension: " << fname << std::endl;
|
||||
}
|
||||
}//end for file_download
|
||||
}
|
||||
else{
|
||||
std::cout << "qvvr file still imcomplete!!!" << std::endl;
|
||||
@@ -3406,12 +3423,12 @@ bool update_qvvr_file_download(const std::string& filename_with_mac_in, const st
|
||||
lock.unlock();
|
||||
return true; // 当前文件处理成功
|
||||
}
|
||||
}
|
||||
}//end for qvvrfile
|
||||
|
||||
std::cout << "file name doesnt match any file in this monitor!!!" << std::endl;
|
||||
|
||||
}
|
||||
}
|
||||
}//end for monitor
|
||||
}//end for dev
|
||||
lock.unlock();
|
||||
return false; // 未匹配到终端ID或逻辑序号对应的监测点
|
||||
}
|
||||
@@ -4869,6 +4886,20 @@ void check_recall_file() {
|
||||
std::cout << "[check_recall_stat] FAILED dev=" << dev.terminal_id
|
||||
<< " monitor=" << lm.monitor_id
|
||||
<< " " << front.StartTime << " ~ " << front.EndTime << std::endl;
|
||||
|
||||
//20251218添加记录
|
||||
std::string msg_fail;
|
||||
if (front.direct_mode) {
|
||||
msg_fail = std::string("监测点:") + lm.monitor_name
|
||||
+ " 补招波形文件失败,目标时标:"
|
||||
+ front.target_filetimes;
|
||||
} else {
|
||||
msg_fail = std::string("监测点:") + lm.monitor_name
|
||||
+ " 补招波形文件失败,时间范围:"
|
||||
+ front.StartTime + " ~ " + front.EndTime;
|
||||
}
|
||||
append_recall_record_line(dev.guid, lm.monitor_id, msg_fail);
|
||||
//20251218添加记录
|
||||
|
||||
lm.recall_list_static.pop_front();
|
||||
|
||||
@@ -5374,6 +5405,21 @@ void check_recall_file() {
|
||||
<< std::endl;
|
||||
} else {
|
||||
front.recall_status = static_cast<int>(RecallStatus::FAILED);
|
||||
|
||||
//20251218添加记录
|
||||
std::string msg_fail;
|
||||
if (front.direct_mode) {
|
||||
msg_fail = std::string("监测点:") + lm.monitor_name
|
||||
+ " 补招波形文件下载失败,目标时标:"
|
||||
+ front.target_filetimes;
|
||||
} else {
|
||||
msg_fail = std::string("监测点:") + lm.monitor_name
|
||||
+ " 补招波形文件下载失败,时间范围:"
|
||||
+ front.StartTime + " ~ " + front.EndTime;
|
||||
}
|
||||
append_recall_record_line(dev.guid, lm.monitor_id, msg_fail);
|
||||
//20251218添加记录
|
||||
|
||||
std::cout << "[check_recall_stat] some files failed, FAIL dev=" << dev.terminal_id
|
||||
<< " monitor=" << lm.monitor_id
|
||||
<< " ok=" << front.file_success.size()
|
||||
@@ -5769,7 +5815,7 @@ void on_device_response_minimal(int response_code,
|
||||
<< " rc=" << response_code << " recall_status=" << front.recall_status << std::endl; //错误响应码
|
||||
|
||||
//记录日志
|
||||
DIY_ERRORLOG_CODE(matched_monitor->monitor_id.c_str(),2,static_cast<int>(LogCode::LOG_CODE_RECALL),"【ERROR】监测点:%s 补招数据失败 - 失败时间点:%lld 至 %lld",matched_monitor->monitor_id.c_str(),front.StartTime,front.EndTime);
|
||||
DIY_ERRORLOG_CODE(matched_monitor->monitor_id.c_str(),2,static_cast<int>(LogCode::LOG_CODE_RECALL),"【ERROR】监测点:%s 补招数据失败 - 失败时间点:%s 至 %s",matched_monitor->monitor_id.c_str(),front.StartTime.c_str(),front.EndTime.c_str());
|
||||
}
|
||||
else { //补招失败
|
||||
front.recall_status = static_cast<int>(RecallStatus::FAILED);
|
||||
@@ -5779,7 +5825,7 @@ void on_device_response_minimal(int response_code,
|
||||
<< " rc=" << response_code << " recall_status=" << front.recall_status<< std::endl; //错误响应码
|
||||
|
||||
//记录日志
|
||||
DIY_ERRORLOG_CODE(matched_monitor->monitor_id.c_str(),2,static_cast<int>(LogCode::LOG_CODE_RECALL),"【ERROR】监测点:%s 补招数据失败 - 失败时间点:%lld 至 %lld",matched_monitor->monitor_id.c_str(),front.StartTime,front.EndTime);
|
||||
DIY_ERRORLOG_CODE(matched_monitor->monitor_id.c_str(),2,static_cast<int>(LogCode::LOG_CODE_RECALL),"【ERROR】监测点:%s 补招数据失败 - 失败时间点:%s 至 %s",matched_monitor->monitor_id.c_str(),front.StartTime.c_str(),front.EndTime.c_str());
|
||||
}
|
||||
updated = true;
|
||||
} else { //首条不是 RUNNING 状态,不应该收到这条响应
|
||||
|
||||
@@ -271,7 +271,7 @@ void SendFileWeb(const std::string& strUrl, const std::string& localpath, const
|
||||
if (res != CURLE_OK) {
|
||||
const char* em = errbuf[0] ? errbuf : curl_easy_strerror(res);
|
||||
std::cerr << "http web failed: " << em << std::endl;
|
||||
DIY_ERRORLOG("process","【ERROR】前置上传暂态录波文件 %s 失败,请检查文件上传接口配置",localpath);
|
||||
DIY_ERRORLOG("process","【ERROR】前置上传暂态录波文件 %s 失败,请检查文件上传接口配置",localpath.c_str());
|
||||
} else {
|
||||
std::cout << "http web success, response: " << resPost0 << std::endl;
|
||||
handleUploadResponse(resPost0, wavepath); // 处理响应
|
||||
@@ -389,7 +389,7 @@ void download_xml_for_icd(const std::string& MODEL_ID,
|
||||
std::cout << "remote file name:" << remote_file_name << "local save name:" << save_name << std::endl;
|
||||
|
||||
// mq日志
|
||||
DIY_WARNLOG("process","【WARN】前置获取到终端类型%s,该终端类型对应的映射文件为%s,映射文件将下载并保存在本地为%s",TMNL_TYPE,FILE_PATH,save_name);
|
||||
DIY_WARNLOG("process","【WARN】前置获取到终端类型%s,该终端类型对应的映射文件为%s,映射文件将下载并保存在本地为%s",TMNL_TYPE.c_str(),FILE_PATH.c_str(),save_name.c_str());
|
||||
|
||||
std::string fileContent;
|
||||
std::string fullPath = std::string("filePath=") + filepath; //填写远端路径作为入参
|
||||
@@ -409,14 +409,14 @@ void download_xml_for_icd(const std::string& MODEL_ID,
|
||||
outFile.close();
|
||||
|
||||
std::cout << "File saved successfully!" << std::endl;
|
||||
DIY_WARNLOG("process","【WARN】前置下载映射文件%s成功",save_name);
|
||||
DIY_WARNLOG("process","【WARN】前置下载映射文件%s成功",save_name.c_str());
|
||||
} else {
|
||||
std::cerr << "Error: Unable to open file for writing." << std::endl;
|
||||
DIY_ERRORLOG("process","【ERROR】前置写入本地映射文件%s失败",save_name);
|
||||
DIY_ERRORLOG("process","【ERROR】前置写入本地映射文件%s失败",save_name.c_str());
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Error: Unable to download file." << std::endl;
|
||||
DIY_ERRORLOG("process","【ERROR】前置调用文件下载接口下载远端文件文件%s失败",FILE_PATH);
|
||||
DIY_ERRORLOG("process","【ERROR】前置调用文件下载接口下载远端文件文件%s失败",FILE_PATH.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1244,10 +1244,18 @@ int transfer_json_qvvr_data(const std::string& dev_id, ushort monitor_id,
|
||||
root["eventType"] = dis_kind;
|
||||
|
||||
// 时间处理
|
||||
time_t start_sec = start_tm / 1000; //毫秒级取秒
|
||||
/*time_t start_sec = start_tm / 1000; //毫秒级取秒
|
||||
struct tm* time_info = localtime(&start_sec);
|
||||
char time_buf[32];
|
||||
strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", time_info);
|
||||
strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", time_info);*/
|
||||
time_t start_sec = start_tm / 1000;
|
||||
struct tm tm_info;
|
||||
localtime_r(&start_sec, &tm_info);
|
||||
char time_buf[32];
|
||||
strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", &tm_info);
|
||||
|
||||
|
||||
|
||||
std::ostringstream start_time_stream;
|
||||
start_time_stream << time_buf << "." << std::setfill('0') << std::setw(3) << (start_tm % 1000);//构造成年月日时分秒.毫秒
|
||||
std::string start_time_str = start_time_stream.str();
|
||||
@@ -1271,7 +1279,7 @@ int transfer_json_qvvr_data(const std::string& dev_id, ushort monitor_id,
|
||||
// 有效响应,略过
|
||||
} catch (...) {
|
||||
// 响应异常,保存 json
|
||||
DIY_ERRORLOG(mpid.c_str(), "【ERROR】暂态接口响应异常,无法上送装置%s监测点%s的暂态事件",dev_id, monitor_id);
|
||||
DIY_ERRORLOG(mpid.c_str(), "【ERROR】暂态接口响应异常,无法上送装置%s监测点%u的暂态事件",dev_id.c_str(), (unsigned)monitor_id);
|
||||
|
||||
std::cout << "qvvr send fail ,store in local" << std::endl;
|
||||
std::string qvvrDir = FRONT_PATH + "/dat/qvvr/";
|
||||
@@ -1281,7 +1289,7 @@ int transfer_json_qvvr_data(const std::string& dev_id, ushort monitor_id,
|
||||
}
|
||||
} else {
|
||||
// 无响应,保存 json
|
||||
DIY_ERRORLOG(mpid.c_str(), "【ERROR】暂态接口无响应,无法上送装置%s监测点%s的暂态事件",dev_id, monitor_id);
|
||||
DIY_ERRORLOG(mpid.c_str(), "【ERROR】暂态接口无响应,无法上送装置%s监测点%u的暂态事件",dev_id.c_str(), (unsigned)monitor_id);
|
||||
|
||||
std::cout << "qvvr send fail ,store in local" << std::endl;
|
||||
std::string qvvrDir = FRONT_PATH + "/dat/qvvr/";
|
||||
|
||||
@@ -484,6 +484,7 @@ extern "C" {
|
||||
//标准化日志接口
|
||||
// #define LOGMSG_WITH_TS // 需要时间时再打开
|
||||
|
||||
//已在头文件添加编译校验
|
||||
void format_log_msg(char* buf, size_t buf_size, const char* fmt, ...) {
|
||||
if (!buf || buf_size == 0) return;
|
||||
buf[0] = '\0';
|
||||
|
||||
@@ -34,7 +34,13 @@ extern LOG_TLS_SPEC int g_log_code_tls;
|
||||
|
||||
#define LOGTYPE_COM 1
|
||||
#define LOGTYPE_DATA 2
|
||||
|
||||
/////////////////////////////////////////////入参验证
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
# define PRINTF_LIKE(fmt_index, first_arg) __attribute__((format(printf, fmt_index, first_arg)))
|
||||
#else
|
||||
# define PRINTF_LIKE(fmt_index, first_arg)
|
||||
#endif
|
||||
/////////////////////////////////////////
|
||||
struct TypedLogger {
|
||||
log4cplus::Logger logger;
|
||||
int logtype;
|
||||
@@ -94,7 +100,9 @@ void log_debug(const char* key, const char* msg);
|
||||
void log_info(const char* key, const char* msg);
|
||||
void log_warn(const char* key, const char* msg);
|
||||
void log_error(const char* key, const char* msg);
|
||||
void format_log_msg(char* buf, size_t buf_size, const char* fmt, ...);
|
||||
//void format_log_msg(char* buf, size_t buf_size, const char* fmt, ...);
|
||||
//带验证
|
||||
void format_log_msg(char* buf, size_t buf_size, const char* fmt, ...) PRINTF_LIKE(3,4);
|
||||
|
||||
// ====================== ★新增:线程局部变量透传 code ======================
|
||||
// 说明:使用编译器的 TLS(__thread)保存当前日志的 code 值。
|
||||
|
||||
@@ -300,6 +300,7 @@ extern bool normalOutputEnabled;
|
||||
"G_TEST_NUM=<num> - Set the G_TEST_NUM\r\n"
|
||||
"G_TEST_TYPE=<num> - Set the G_TEST_TYPE 0:use ledger,1:use number\r\n"
|
||||
"LOG=<bool> - Set the LOG\r\n"
|
||||
"MAX=<int> - Set the MAX_ITEMS\r\n"
|
||||
"dir - Execute rocketmq_test_getdir\r\n"
|
||||
"rc - Execute rocketmq_test_rc\r\n"
|
||||
"rt - Execute rocketmq_test_rt\r\n"
|
||||
|
||||
Reference in New Issue
Block a user