fix compile problem in otherplace
This commit is contained in:
2617
LFtid1056/cloudfront/code/cfg_parser.cpp
Normal file
2617
LFtid1056/cloudfront/code/cfg_parser.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1291
LFtid1056/cloudfront/code/interface.cpp
Normal file
1291
LFtid1056/cloudfront/code/interface.cpp
Normal file
File diff suppressed because it is too large
Load Diff
534
LFtid1056/cloudfront/code/log4.cpp
Normal file
534
LFtid1056/cloudfront/code/log4.cpp
Normal file
@@ -0,0 +1,534 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <ctime>
|
||||
#include <sstream>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include <cstdio>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <fnmatch.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "log4cplus/logger.h"
|
||||
#include "log4cplus/configurator.h"
|
||||
#include "log4cplus/fileappender.h"
|
||||
#include "log4cplus/layout.h"
|
||||
#include "log4cplus/ndc.h"
|
||||
#include "log4.h"
|
||||
#include "log4cplus/spi/loggingevent.h"
|
||||
|
||||
#include "rocketmq.h"
|
||||
#include "interface.h"
|
||||
#include "log4.h"
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//log4命名空间
|
||||
using namespace log4cplus;
|
||||
using namespace log4cplus::helpers;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//queue结构定义
|
||||
extern std::mutex queue_data_list_mutex; //queue发送数据锁
|
||||
extern std::list<queue_data_t> queue_data_list; //queue发送数据链表
|
||||
|
||||
extern unsigned int g_node_id;
|
||||
extern int g_front_seg_index;
|
||||
extern std::string FRONT_INST;
|
||||
extern std::string subdir;
|
||||
|
||||
//mq
|
||||
extern std::mutex queue_data_list_mutex; //queue发送数据锁
|
||||
extern std::list<queue_data_t> queue_data_list; //queue发送数据链表
|
||||
|
||||
//日志主题
|
||||
extern std::string G_LOG_TOPIC;
|
||||
|
||||
extern std::vector<terminal_dev> terminal_devlist;
|
||||
|
||||
////////////////////////////////////////////////////////辅助函数
|
||||
std::string get_front_type_from_subdir() {
|
||||
if (subdir == "cfg_3s_data")
|
||||
return "realTime";
|
||||
else if (subdir == "cfg_soe_comtrade")
|
||||
return "comtrade";
|
||||
else if (subdir == "cfg_recallhis_data")
|
||||
return "recall";
|
||||
else if (subdir == "cfg_stat_data")
|
||||
return "stat";
|
||||
else
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
// 递归创建目录
|
||||
bool create_directory_recursive(const std::string& path) {
|
||||
size_t pos = 0;
|
||||
std::string current;
|
||||
while (pos != std::string::npos) {
|
||||
pos = path.find('/', pos + 1);
|
||||
current = path.substr(0, pos);
|
||||
if (!current.empty() && access(current.c_str(), F_OK) != 0) {
|
||||
if (mkdir(current.c_str(), 0755) != 0) {
|
||||
perror(("mkdir failed: " + current).c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
std::string extract_logger_id(const std::string& logger_name) {
|
||||
size_t pos = logger_name.find('.');
|
||||
if (pos != std::string::npos && pos + 1 < logger_name.size()) {
|
||||
return logger_name.substr(pos + 1);
|
||||
}
|
||||
return ""; // 没有找到 '.' 或 '.' 后为空
|
||||
}
|
||||
|
||||
std::string get_level_str(int level) {
|
||||
switch (level) {
|
||||
case 10000: return "DEBUG";
|
||||
case 20000: return "NORMAL"; // 或 "INFO" 根据你业务定义
|
||||
case 30000: return "WARN";
|
||||
case 40000: return "ERROR";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
TypedLogger::TypedLogger() {}
|
||||
TypedLogger::TypedLogger(const Logger& l, int t) : logger(l), logtype(t) {}
|
||||
|
||||
DebugSwitch::DebugSwitch() : debug_open(false), min_level(WARN_LOG_LEVEL) {}
|
||||
void DebugSwitch::open() { debug_open = true; }
|
||||
void DebugSwitch::close() {
|
||||
debug_open = false;
|
||||
targets.clear();
|
||||
type_enable.clear();
|
||||
}
|
||||
void DebugSwitch::set_target(const std::string& name) { targets.insert(name); }
|
||||
void DebugSwitch::set_level(int level) { min_level = level; }
|
||||
void DebugSwitch::enable_type(int type) { type_enable[type] = true; }
|
||||
void DebugSwitch::disable_type(int type) { type_enable[type] = false; }
|
||||
|
||||
bool DebugSwitch::match(const std::string& logger_name, int level, int logtype) {
|
||||
if (!debug_open) return false;
|
||||
if (level < min_level) return false;
|
||||
if (type_enable.count(logtype) && !type_enable[logtype]) return false;
|
||||
std::set<std::string>::iterator it;
|
||||
for (it = targets.begin(); it != targets.end(); ++it) {
|
||||
if (logger_name.find(*it) != std::string::npos)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::map<std::string, TypedLogger> logger_map;
|
||||
DebugSwitch g_debug_switch;
|
||||
|
||||
class SendAppender : public Appender {
|
||||
protected:
|
||||
void append(const spi::InternalLoggingEvent& event) {
|
||||
std::string logger_name = event.getLoggerName();
|
||||
int level = event.getLogLevel();
|
||||
std::string msg = event.getMessage();
|
||||
|
||||
int logtype = (logger_name.find(".COM") != std::string::npos) ? LOGTYPE_COM : LOGTYPE_DATA;
|
||||
std::string level_str;
|
||||
if (logger_name.find("process") == 0)
|
||||
level_str = "process";
|
||||
else if (logger_name.find("monitor") != std::string::npos)
|
||||
level_str = "measurepoint";
|
||||
else
|
||||
level_str = "terminal";
|
||||
|
||||
if (level == ERROR_LOG_LEVEL || level == WARN_LOG_LEVEL || g_debug_switch.match(logger_name, level, logtype)) {
|
||||
std::ostringstream oss;
|
||||
oss << "{\"processNo\":\"" << std::to_string(g_front_seg_index)
|
||||
<< "\",\"nodeId\":\"" << FRONT_INST
|
||||
<< "\",\"businessId\":\"" << extract_logger_id(logger_name)
|
||||
<< "\",\"level\":\"" << level_str
|
||||
<< "\",\"grade\":\"" << get_level_str(level)
|
||||
<< "\",\"logtype\":\"" << (logtype == LOGTYPE_COM ? "com" : "data")
|
||||
<< "\",\"frontType\":\"" << get_front_type_from_subdir()
|
||||
<< "\",\"log\":\"" << escape_json(msg) << "\"}";
|
||||
|
||||
std::string jsonString = oss.str();
|
||||
|
||||
queue_data_t connect_info;
|
||||
connect_info.strTopic = G_LOG_TOPIC;
|
||||
connect_info.strText = jsonString;
|
||||
|
||||
std::lock_guard<std::mutex> lock(queue_data_list_mutex);
|
||||
queue_data_list.push_back(connect_info);
|
||||
}
|
||||
}
|
||||
|
||||
std::string escape_json(const std::string& input) {
|
||||
std::ostringstream ss;
|
||||
for (unsigned int i = 0; i < input.size(); ++i) {
|
||||
switch (input[i]) {
|
||||
case '\\': ss << "\\\\"; break;
|
||||
case '"': ss << "\\\""; break;
|
||||
case '\n': ss << "\\n"; break;
|
||||
case '\r': ss << "\\r"; break;
|
||||
case '\t': ss << "\\t"; break;
|
||||
default: ss << input[i]; break;
|
||||
}
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
virtual void close() {
|
||||
// 可空实现
|
||||
}
|
||||
|
||||
public:
|
||||
SendAppender() {}
|
||||
virtual ~SendAppender() {
|
||||
destructorImpl(); // 重要!释放 log4cplus 基类资源
|
||||
}
|
||||
};
|
||||
|
||||
//用来控制日志上送的结构
|
||||
struct LOGEntry {
|
||||
std::string id;
|
||||
std::string level; // terminal / measurepoint
|
||||
int logtype; // com / data
|
||||
int min_grade;
|
||||
int countdown;
|
||||
};
|
||||
|
||||
//日志上送map管理
|
||||
std::map<std::string, LOGEntry> g_log_entries;
|
||||
pthread_mutex_t g_log_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
// 生成唯一 key
|
||||
std::string build_debug_key(const std::string& id, const std::string& level, int logtype) {
|
||||
return id + "|" + level + "|" + (logtype == 1 ? "COM" : "DATA");
|
||||
}
|
||||
|
||||
// 外部线程中调用:每秒更新所有倒计时,0 则删除
|
||||
void update_log_entries_countdown() {
|
||||
pthread_mutex_lock(&g_log_mutex);
|
||||
std::map<std::string, LOGEntry>::iterator it = g_log_entries.begin();
|
||||
while (it != g_log_entries.end()) {
|
||||
if (it->second.countdown > 0) {
|
||||
it->second.countdown--;
|
||||
if (it->second.countdown == 0) {
|
||||
std::cout << "[LOG] debug日志上送自动关闭: " << it->first << std::endl;
|
||||
it = g_log_entries.erase(it);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
++it;
|
||||
}
|
||||
pthread_mutex_unlock(&g_log_mutex);
|
||||
}
|
||||
|
||||
void process_log_command(const std::string& id, const std::string& level, const std::string& grade, const std::string& logtype_str) {
|
||||
if (level != "terminal" && level != "measurepoint") return;
|
||||
|
||||
int type = (logtype_str == "com") ? LOGTYPE_COM : LOGTYPE_DATA;
|
||||
int grade_level = (grade == "DEBUG") ? DEBUG_LOG_LEVEL : INFO_LOG_LEVEL;
|
||||
|
||||
std::string key = build_debug_key(id, level, type);
|
||||
|
||||
pthread_mutex_lock(&g_log_mutex);
|
||||
|
||||
LOGEntry& entry = g_log_entries[key]; // 会自动 insert 或取已有
|
||||
entry.id = id;
|
||||
entry.level = level;
|
||||
entry.logtype = type;
|
||||
entry.min_grade = grade_level;
|
||||
entry.countdown = 60; // 重置倒计时
|
||||
|
||||
pthread_mutex_unlock(&g_log_mutex);
|
||||
|
||||
}
|
||||
|
||||
Logger init_logger(const std::string& full_name, const std::string& file_dir, const std::string& base_file, SharedAppenderPtr fileAppender) {
|
||||
create_directory_recursive(file_dir);
|
||||
|
||||
Logger logger = Logger::getInstance(full_name);
|
||||
if (!fileAppender) {
|
||||
std::string file_path = file_dir + "/" + base_file + ".log";
|
||||
fileAppender = SharedAppenderPtr(new RollingFileAppender(file_path, 1 * 1024 * 1024, 2));
|
||||
fileAppender->setLayout(std::unique_ptr<Layout>(
|
||||
new PatternLayout("%D{%Y-%m-%d %H:%M:%S} [%p] [%c] %m%n")));
|
||||
}
|
||||
|
||||
SharedAppenderPtr sendAppender(new SendAppender());
|
||||
logger.addAppender(fileAppender);
|
||||
logger.addAppender(sendAppender);
|
||||
logger.setLogLevel(DEBUG_LOG_LEVEL);
|
||||
return logger;
|
||||
}
|
||||
|
||||
// 重载版本:无 Appender 传入时调用上面的实现
|
||||
log4cplus::Logger init_logger(const std::string& full_name,
|
||||
const std::string& file_dir,
|
||||
const std::string& base_file) {
|
||||
return init_logger(full_name, file_dir, base_file,
|
||||
log4cplus::SharedAppenderPtr()); // 空指针
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////应用函数
|
||||
|
||||
//进程的日志
|
||||
void init_logger_process() {
|
||||
std::string base_dir = FRONT_PATH + "/" + subdir + "/processNo" + std::to_string(g_front_seg_index) + "/log";
|
||||
logger_map["process"] = TypedLogger(init_logger(std::string("process"), base_dir, std::string("process")), LOGTYPE_DATA);
|
||||
std::cout << "process log init ok" << std::endl;
|
||||
}
|
||||
|
||||
//单个终端的日志初始化
|
||||
void init_loggers_bydevid(const std::string& dev_id)
|
||||
{
|
||||
if (dev_id.empty()) return;
|
||||
|
||||
std::string terminal_id = dev_id;
|
||||
std::string base_dir = FRONT_PATH + "/" + subdir + "/processNo" + std::to_string(g_front_seg_index) + "/log";
|
||||
|
||||
for (size_t i = 0; i < terminal_devlist.size(); ++i) {
|
||||
terminal_dev& term = terminal_devlist[i];
|
||||
|
||||
// 跳过终端台账信息为空的节点
|
||||
if (term.terminal_id.empty()) {
|
||||
std::cout << "terminal_dev No." << i << " is null" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 跳过不匹配的终端
|
||||
if (term.terminal_id != dev_id) continue;
|
||||
|
||||
std::string ip_str = term.addr_str.empty() ? "unknown" : term.addr_str;
|
||||
std::string device_dir = base_dir + "/" + ip_str;
|
||||
std::string device_key_c = std::string("terminal.") + dev_id + ".COM";
|
||||
std::string device_key_d = std::string("terminal.") + dev_id + ".DATA";
|
||||
|
||||
// 添加判断:终端日志 logger 是否已存在
|
||||
if (logger_map.find(device_key_c) == logger_map.end() &&
|
||||
logger_map.find(device_key_d) == logger_map.end()) {
|
||||
|
||||
// 所有终端日志(com 和 data)写到同一个 device 日志文件中
|
||||
std::string file_path_t = device_dir + "/" + dev_id + ".log";
|
||||
|
||||
// 共用一个 appender 实例
|
||||
SharedAppenderPtr device_appender(new RollingFileAppender(file_path_t, 1 * 1024 * 1024, 2));
|
||||
device_appender->setLayout(std::unique_ptr<Layout>(new PatternLayout("%D{%Y-%m-%d %H:%M:%S} [%p] [%c] %m%n")));
|
||||
|
||||
Logger device_logger_c = init_logger(device_key_c, device_dir, dev_id, device_appender);
|
||||
Logger device_logger_d = init_logger(device_key_d, device_dir, dev_id, device_appender);
|
||||
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终端级日志初始化完毕", term.terminal_id.c_str());
|
||||
}
|
||||
|
||||
// 初始化监测点日志,monitor.<mp_id>.COM / .DATA
|
||||
for (size_t j = 0; j < term.line.size(); ++j) {
|
||||
const ledger_monitor& monitor = term.line[j];
|
||||
if (!monitor.monitor_id.empty()) {
|
||||
std::ostringstream mon_key_c, mon_key_d, mon_path, mon_name;
|
||||
mon_key_c << "monitor." << monitor.monitor_id << ".COM";
|
||||
mon_key_d << "monitor." << monitor.monitor_id << ".DATA";
|
||||
mon_path << device_dir << "/monitor" << j;
|
||||
mon_name << monitor.monitor_id;
|
||||
|
||||
// 判断监测点 logger 是否已存在
|
||||
if (logger_map.find(mon_key_c.str()) == logger_map.end() &&
|
||||
logger_map.find(mon_key_d.str()) == logger_map.end()) {
|
||||
|
||||
// 所有监测点日志(com 和 data)写到同一个 monitor 日志文件中
|
||||
std::string file_path_m = mon_path.str() + "/" + mon_name.str() + ".log";
|
||||
|
||||
// 共用一个 appender 实例
|
||||
SharedAppenderPtr monitor_appender(new RollingFileAppender(file_path_m, 1 * 1024 * 1024, 2));
|
||||
monitor_appender->setLayout(std::unique_ptr<Layout>(new PatternLayout("%D{%Y-%m-%d %H:%M:%S} [%p] [%c] %m%n")));
|
||||
|
||||
Logger mon_logger_c = init_logger(mon_key_c.str(), mon_path.str(), mon_name.str(), monitor_appender);
|
||||
Logger mon_logger_d = init_logger(mon_key_d.str(), mon_path.str(), mon_name.str(), monitor_appender);
|
||||
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监测点级日志初始化完毕", monitor.monitor_name.c_str(), monitor.monitor_id.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break; // 只匹配一个 terminal_id
|
||||
}
|
||||
}
|
||||
|
||||
//初始化台账日志
|
||||
void init_loggers()
|
||||
{
|
||||
std::string base_dir = FRONT_PATH + "/" + subdir + "/processNo" + std::to_string(g_front_seg_index) + "/log";
|
||||
|
||||
// 遍历所有终端
|
||||
for (size_t t = 0; t < terminal_devlist.size(); ++t) {
|
||||
terminal_dev& term = terminal_devlist[t];
|
||||
|
||||
// 跳过无效终端
|
||||
if (term.terminal_id.empty()) {
|
||||
std::cout << "terminal_dev No." << t << " is null" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string ip_str = term.addr_str.empty() ? "unknown" : term.addr_str;
|
||||
std::string device_dir = base_dir + "/" + ip_str;
|
||||
|
||||
std::string device_key_c = std::string("terminal.") + term.terminal_id + ".COM";
|
||||
std::string device_key_d = std::string("terminal.") + term.terminal_id + ".DATA";
|
||||
|
||||
// 所有终端日志(com 和 data)写到同一个 device 日志文件中
|
||||
std::string file_path_t = device_dir + "/" + term.terminal_id + ".log";
|
||||
|
||||
// 共用一个 appender 实例
|
||||
SharedAppenderPtr device_appender(new RollingFileAppender(file_path_t, 1 * 1024 * 1024, 2));
|
||||
device_appender->setLayout(std::unique_ptr<Layout>(new PatternLayout("%D{%Y-%m-%d %H:%M:%S} [%p] [%c] %m%n")));
|
||||
|
||||
Logger device_logger_c = init_logger(device_key_c, device_dir, term.terminal_id, device_appender);
|
||||
Logger device_logger_d = init_logger(device_key_d, device_dir, term.terminal_id, device_appender);
|
||||
|
||||
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终端级日志初始化完毕", term.terminal_id.c_str());
|
||||
|
||||
// 初始化监测点日志
|
||||
for (size_t i = 0; i < term.line.size(); ++i) {
|
||||
const ledger_monitor& monitor = term.line[i];
|
||||
|
||||
if (!monitor.monitor_id.empty()) {
|
||||
std::ostringstream mon_key_c, mon_key_d, mon_path, mon_name;
|
||||
mon_key_c << "monitor." << monitor.monitor_id << ".COM";
|
||||
mon_key_d << "monitor." << monitor.monitor_id << ".DATA";
|
||||
|
||||
mon_path << device_dir << "/monitor" << i; // 用monitor+序号作为目录
|
||||
mon_name << monitor.monitor_id;
|
||||
|
||||
std::string file_path_m = mon_path.str() + "/" + mon_name.str() + ".log";
|
||||
|
||||
// 共用一个 appender 实例
|
||||
SharedAppenderPtr monitor_appender(new RollingFileAppender(file_path_m, 1 * 1024 * 1024, 2));
|
||||
monitor_appender->setLayout(std::unique_ptr<Layout>(new PatternLayout("%D{%Y-%m-%d %H:%M:%S} [%p] [%c] %m%n")));
|
||||
|
||||
Logger mon_logger_c = init_logger(mon_key_c.str(), mon_path.str(), mon_name.str(), monitor_appender);
|
||||
Logger mon_logger_d = init_logger(mon_key_d.str(), mon_path.str(), mon_name.str(), monitor_appender);
|
||||
|
||||
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监测点级日志初始化完毕",
|
||||
monitor.monitor_name.c_str(), monitor.monitor_id.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//单个终端的日志删除
|
||||
void remove_loggers_by_terminal_id(const std::string& terminal_id) {
|
||||
// 遍历所有终端
|
||||
for (size_t t = 0; t < terminal_devlist.size(); ++t) {
|
||||
terminal_dev& term = terminal_devlist[t];
|
||||
if (term.terminal_id != terminal_id) continue;
|
||||
|
||||
// 删除终端日志 logger
|
||||
std::string com_key = "terminal." + terminal_id + ".COM";
|
||||
std::string data_key = "terminal." + terminal_id + ".DATA";
|
||||
|
||||
if (logger_map.count(com_key)) {
|
||||
logger_map[com_key].logger.removeAllAppenders();
|
||||
logger_map.erase(com_key);
|
||||
}
|
||||
|
||||
if (logger_map.count(data_key)) {
|
||||
logger_map[data_key].logger.removeAllAppenders();
|
||||
logger_map.erase(data_key);
|
||||
}
|
||||
|
||||
// 删除监测点日志 logger
|
||||
for (size_t i = 0; i < term.line.size(); ++i) {
|
||||
const ledger_monitor& monitor = term.line[i];
|
||||
if (!monitor.monitor_id.empty()) {
|
||||
std::string mon_prefix = "monitor." + monitor.monitor_id;
|
||||
std::string mon_com_key = mon_prefix + ".COM";
|
||||
std::string mon_data_key = mon_prefix + ".DATA";
|
||||
|
||||
if (logger_map.count(mon_com_key)) {
|
||||
logger_map[mon_com_key].logger.removeAllAppenders();
|
||||
logger_map.erase(mon_com_key);
|
||||
}
|
||||
|
||||
if (logger_map.count(mon_data_key)) {
|
||||
logger_map[mon_data_key].logger.removeAllAppenders();
|
||||
logger_map.erase(mon_data_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "[LOG] Logger for terminal_id=" << terminal_id << " removed." << std::endl;
|
||||
break; // 找到匹配终端后退出
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////封装函数,C/C++通用
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// 公共函数
|
||||
void log4_log_with_level(const char* key, const char* msg, int level) {
|
||||
std::map<std::string, TypedLogger>::iterator it = logger_map.find(key);
|
||||
if (it == logger_map.end()) return;
|
||||
|
||||
Logger logger = it->second.logger;
|
||||
switch (level) {
|
||||
case 0: LOG4CPLUS_DEBUG(logger, msg); break;
|
||||
case 1: LOG4CPLUS_INFO(logger, msg); break;
|
||||
case 2: LOG4CPLUS_WARN(logger, msg); break;
|
||||
case 3: LOG4CPLUS_ERROR(logger, msg); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
// 四个包装函数
|
||||
void log_debug(const char* key, const char* msg) { log4_log_with_level(key, msg, 0); }
|
||||
void log_info (const char* key, const char* msg) { log4_log_with_level(key, msg, 1); }
|
||||
void log_warn (const char* key, const char* msg) { log4_log_with_level(key, msg, 2); }
|
||||
void log_error(const char* key, const char* msg) { log4_log_with_level(key, msg, 3); }
|
||||
|
||||
void send_reply_to_queue_c(const char* guid, const char* step, const char* result) {
|
||||
send_reply_to_queue(std::string(guid), std::string(step), std::string(result));
|
||||
}
|
||||
|
||||
//标准化日志接口
|
||||
void format_log_msg(char* buf, size_t buf_size, const char* fmt, ...) {
|
||||
// 写入时间
|
||||
time_t now = time(NULL);
|
||||
struct tm tm_info;
|
||||
localtime_r(&now, &tm_info);
|
||||
strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S ", &tm_info); // 时间+空格
|
||||
|
||||
// 处理可变参数并写入剩余内容
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf + strlen(buf), buf_size - strlen(buf), fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
111
LFtid1056/cloudfront/code/log4.h
Normal file
111
LFtid1056/cloudfront/code/log4.h
Normal file
@@ -0,0 +1,111 @@
|
||||
#ifndef LOG4_H
|
||||
#define LOG4_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
//防止#include <log4cplus/logger.h>里的冲突
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
//防止#include <log4cplus/logger.h>里的冲突
|
||||
|
||||
#include "logger.h"
|
||||
#include <set>
|
||||
#include "loggingmacros.h"
|
||||
|
||||
#include "appender.h"
|
||||
|
||||
#define LOGTYPE_COM 1
|
||||
#define LOGTYPE_DATA 2
|
||||
|
||||
struct TypedLogger {
|
||||
log4cplus::Logger logger;
|
||||
int logtype;
|
||||
TypedLogger();
|
||||
TypedLogger(const log4cplus::Logger& l, int t);
|
||||
};
|
||||
|
||||
struct DebugSwitch {
|
||||
bool debug_open;
|
||||
std::set<std::string> targets;
|
||||
int min_level;
|
||||
std::map<int, bool> type_enable;
|
||||
|
||||
DebugSwitch();
|
||||
void open();
|
||||
void close();
|
||||
void set_target(const std::string& name);
|
||||
void set_level(int level);
|
||||
void enable_type(int type);
|
||||
void disable_type(int type);
|
||||
bool match(const std::string& logger_name, int level, int logtype);
|
||||
};
|
||||
|
||||
extern std::map<std::string, TypedLogger> logger_map;
|
||||
extern DebugSwitch g_debug_switch;
|
||||
|
||||
extern void send_reply_to_queue(const std::string& guid, const std::string& step, const std::string& result);
|
||||
|
||||
|
||||
std::string get_front_type_from_subdir();
|
||||
|
||||
|
||||
// 不带 Appender 的版本
|
||||
log4cplus::Logger init_logger(const std::string& full_name,
|
||||
const std::string& file_dir,
|
||||
const std::string& base_file);
|
||||
|
||||
// 带 Appender 的版本
|
||||
log4cplus::Logger init_logger(const std::string& full_name,
|
||||
const std::string& file_dir,
|
||||
const std::string& base_file,
|
||||
log4cplus::SharedAppenderPtr fileAppender);
|
||||
|
||||
void process_log_command(const std::string& id, const std::string& level, const std::string& grade, const std::string& logtype_str);
|
||||
|
||||
|
||||
void update_log_entries_countdown();
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
void remove_loggers_by_terminal_id(const std::string& terminal_id_cstr);
|
||||
void init_logger_process();
|
||||
void init_loggers();
|
||||
void init_loggers_bydevid(const std::string& dev_id);
|
||||
|
||||
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 send_reply_to_queue_c(const char* guid, const char* step, const char* result);
|
||||
void format_log_msg(char* buf, size_t buf_size, const char* fmt, ...);
|
||||
|
||||
//宏定义
|
||||
#define DIY_LOG(LEVEL_FUNC, KEY, ...) \
|
||||
do { \
|
||||
char buf[256]; \
|
||||
format_log_msg(buf, sizeof(buf), __VA_ARGS__); \
|
||||
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__)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif // LOG4_H
|
||||
472
LFtid1056/cloudfront/code/log4cplus/config.h
Normal file
472
LFtid1056/cloudfront/code/log4cplus/config.h
Normal file
@@ -0,0 +1,472 @@
|
||||
/* include/log4cplus/config.h. Generated from config.h.in by configure. */
|
||||
/* include/log4cplus/config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
#ifndef LOG4CPLUS_CONFIG_H
|
||||
|
||||
#define LOG4CPLUS_CONFIG_H
|
||||
|
||||
/* define if the compiler supports basic C++11 syntax */
|
||||
/* #undef HAVE_CXX11 */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you have the `fcntl' function. */
|
||||
#define HAVE_FCNTL 1
|
||||
|
||||
/* Define to 1 if you have the `flock' function. */
|
||||
#define HAVE_FLOCK 1
|
||||
|
||||
/* Define to 1 if you have the `ftime' function. */
|
||||
#define HAVE_FTIME 1
|
||||
|
||||
/* Define to 1 if the system has the `constructor' function attribute */
|
||||
#define HAVE_FUNC_ATTRIBUTE_CONSTRUCTOR 1
|
||||
|
||||
/* Define to 1 if the system has the `constructor_priority' function attribute
|
||||
*/
|
||||
#define HAVE_FUNC_ATTRIBUTE_CONSTRUCTOR_PRIORITY 1
|
||||
|
||||
/* */
|
||||
#define HAVE_GETADDRINFO 1
|
||||
|
||||
/* */
|
||||
#define HAVE_GETHOSTBYNAME_R 1
|
||||
|
||||
/* Define to 1 if you have the `getpid' function. */
|
||||
#define HAVE_GETPID 1
|
||||
|
||||
/* Define to 1 if you have the `gmtime_r' function. */
|
||||
#define HAVE_GMTIME_R 1
|
||||
|
||||
/* Define to 1 if you have the `htonl' function. */
|
||||
#define HAVE_HTONL 1
|
||||
|
||||
/* Define to 1 if you have the `htons' function. */
|
||||
#define HAVE_HTONS 1
|
||||
|
||||
/* Define to 1 if you have the `iconv' function. */
|
||||
/* #undef HAVE_ICONV */
|
||||
|
||||
/* Define to 1 if you have the `iconv_close' function. */
|
||||
/* #undef HAVE_ICONV_CLOSE */
|
||||
|
||||
/* Define to 1 if you have the `iconv_open' function. */
|
||||
/* #undef HAVE_ICONV_OPEN */
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `advapi32' library (-ladvapi32). */
|
||||
/* #undef HAVE_LIBADVAPI32 */
|
||||
|
||||
/* Define to 1 if you have the `libiconv' function. */
|
||||
/* #undef HAVE_LIBICONV */
|
||||
|
||||
/* Define to 1 if you have the `libiconv_close' function. */
|
||||
/* #undef HAVE_LIBICONV_CLOSE */
|
||||
|
||||
/* Define to 1 if you have the `libiconv_open' function. */
|
||||
/* #undef HAVE_LIBICONV_OPEN */
|
||||
|
||||
/* Define to 1 if you have the `kernel32' library (-lkernel32). */
|
||||
/* #undef HAVE_LIBKERNEL32 */
|
||||
|
||||
/* Define to 1 if you have the `oleaut32' library (-loleaut32). */
|
||||
/* #undef HAVE_LIBOLEAUT32 */
|
||||
|
||||
/* Define to 1 if you have the `ws2_32' library (-lws2_32). */
|
||||
/* #undef HAVE_LIBWS2_32 */
|
||||
|
||||
/* Define to 1 if you have the `localtime_r' function. */
|
||||
#define HAVE_LOCALTIME_R 1
|
||||
|
||||
/* Define to 1 if you have the `lockf' function. */
|
||||
#define HAVE_LOCKF 1
|
||||
|
||||
/* Define to 1 if you have the `lstat' function. */
|
||||
#define HAVE_LSTAT 1
|
||||
|
||||
/* Define to 1 if you have the `mbstowcs' function. */
|
||||
#define HAVE_MBSTOWCS 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
/* #undef HAVE_MEMORY_H */
|
||||
|
||||
/* Define to 1 if you have the `ntohl' function. */
|
||||
#define HAVE_NTOHL 1
|
||||
|
||||
/* Define to 1 if you have the `ntohs' function. */
|
||||
#define HAVE_NTOHS 1
|
||||
|
||||
/* Define to 1 if you have the `OutputDebugStringW' function. */
|
||||
/* #undef HAVE_OUTPUTDEBUGSTRINGW */
|
||||
|
||||
/* Define to 1 if you have the `pipe' function. */
|
||||
#define HAVE_PIPE 1
|
||||
|
||||
/* Define to 1 if you have the `pipe2' function. */
|
||||
#define HAVE_PIPE2 1
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
#define HAVE_POLL 1
|
||||
|
||||
/* Define if you have POSIX threads libraries and header files. */
|
||||
#define HAVE_PTHREAD 1
|
||||
|
||||
/* Have PTHREAD_PRIO_INHERIT. */
|
||||
#define HAVE_PTHREAD_PRIO_INHERIT 1
|
||||
|
||||
/* If available, contains the Python version number currently in use. */
|
||||
/* #undef HAVE_PYTHON */
|
||||
|
||||
/* Define to 1 if you have the `shutdown' function. */
|
||||
#define HAVE_SHUTDOWN 1
|
||||
|
||||
/* Define to 1 if you have the `stat' function. */
|
||||
#define HAVE_STAT 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Defined if the compiler understands __thread or __declspec(thread)
|
||||
construct. */
|
||||
#define HAVE_TLS_SUPPORT 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if the system has the `init_priority' variable attribute */
|
||||
#define HAVE_VAR_ATTRIBUTE_INIT_PRIORITY 1
|
||||
|
||||
/* Define to 1 if you have the `vfprintf_s' function. */
|
||||
/* #undef HAVE_VFPRINTF_S */
|
||||
|
||||
/* Define to 1 if you have the `vfwprintf_s' function. */
|
||||
/* #undef HAVE_VFWPRINTF_S */
|
||||
|
||||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#define HAVE_VSNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `vsnwprintf' function. */
|
||||
/* #undef HAVE_VSNWPRINTF */
|
||||
|
||||
/* Define to 1 if you have the `vsprintf_s' function. */
|
||||
/* #undef HAVE_VSPRINTF_S */
|
||||
|
||||
/* Define to 1 if you have the `vswprintf_s' function. */
|
||||
/* #undef HAVE_VSWPRINTF_S */
|
||||
|
||||
/* Define to 1 if you have the `wcstombs' function. */
|
||||
#define HAVE_WCSTOMBS 1
|
||||
|
||||
/* Define to 1 if you have the `_vsnprintf' function. */
|
||||
/* #undef HAVE__VSNPRINTF */
|
||||
|
||||
/* Define to 1 if you have the `_vsnprintf_s' function. */
|
||||
/* #undef HAVE__VSNPRINTF_S */
|
||||
|
||||
/* Define to 1 if you have the `_vsnwprintf' function. */
|
||||
/* #undef HAVE__VSNWPRINTF */
|
||||
|
||||
/* Define to 1 if you have the `_vsnwprintf_s' function. */
|
||||
/* #undef HAVE__VSNWPRINTF_S */
|
||||
|
||||
/* Defined if the compiler supports __FUNCTION__ macro. */
|
||||
/* #undef HAVE___FUNCTION___MACRO */
|
||||
|
||||
/* Defined if the compiler supports __func__ symbol. */
|
||||
/* #undef HAVE___FUNC___SYMBOL */
|
||||
|
||||
/* Defined if the compiler supports __PRETTY_FUNCTION__ macro. */
|
||||
/* #undef HAVE___PRETTY_FUNCTION___MACRO */
|
||||
|
||||
/* Defined for --enable-debugging builds. */
|
||||
/* #undef LOG4CPLUS_DEBUGGING */
|
||||
|
||||
/* Defined if the compiler understands __declspec(dllimport) or
|
||||
__attribute__((visibility("default"))) or __global construct. */
|
||||
#define LOG4CPLUS_DECLSPEC_EXPORT __attribute__ ((visibility("default")))
|
||||
|
||||
/* Defined if the compiler understands __declspec(dllimport) or
|
||||
__attribute__((visibility("default"))) or __global construct. */
|
||||
#define LOG4CPLUS_DECLSPEC_IMPORT __attribute__ ((visibility("default")))
|
||||
|
||||
/* Defined if the compiler understands __attribute__((visibility("hidden")))
|
||||
or __hidden construct. */
|
||||
#define LOG4CPLUS_DECLSPEC_PRIVATE __attribute__ ((visibility("hidden")))
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_ARPA_INET_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_ENAMETOOLONG 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_ERRNO_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_FCNTL 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_FCNTL_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_FLOCK 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_FTIME 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_FUNCTION_MACRO 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_FUNC_ATTRIBUTE_CONSTRUCTOR 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_FUNC_ATTRIBUTE_CONSTRUCTOR_PRIORITY 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_FUNC_SYMBOL 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_GETADDRINFO 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_GETHOSTBYNAME_R 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_GETPID 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_GETTID 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_GMTIME_R 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_HTONL 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_HTONS 1
|
||||
|
||||
/* */
|
||||
/* #undef LOG4CPLUS_HAVE_ICONV */
|
||||
|
||||
/* */
|
||||
/* #undef LOG4CPLUS_HAVE_ICONV_CLOSE */
|
||||
|
||||
/* */
|
||||
/* #undef LOG4CPLUS_HAVE_ICONV_H */
|
||||
|
||||
/* */
|
||||
/* #undef LOG4CPLUS_HAVE_ICONV_OPEN */
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_LIMITS_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_LOCALTIME_R 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_LOCKF 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_LSTAT 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_MBSTOWCS 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_NETDB_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_NETINET_IN_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_NETINET_TCP_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_NTOHL 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_NTOHS 1
|
||||
|
||||
/* */
|
||||
/* #undef LOG4CPLUS_HAVE_OUTPUTDEBUGSTRING */
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_PIPE 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_PIPE2 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_POLL 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_POLL_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_PRETTY_FUNCTION_MACRO 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_SHUTDOWN 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_STAT 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_STDARG_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_STDIO_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_STDLIB_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_SYSLOG_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_SYS_FILE_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_SYS_SOCKET_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_SYS_STAT_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_SYS_SYSCALL_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_SYS_TIMEB_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_SYS_TIME_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_TIME_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_TLS_SUPPORT 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_UNISTD_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_VAR_ATTRIBUTE_INIT_PRIORITY 1
|
||||
|
||||
/* */
|
||||
/* #undef LOG4CPLUS_HAVE_VFPRINTF_S */
|
||||
|
||||
/* */
|
||||
/* #undef LOG4CPLUS_HAVE_VFWPRINTF_S */
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_VSNPRINTF 1
|
||||
|
||||
/* */
|
||||
/* #undef LOG4CPLUS_HAVE_VSNWPRINTF */
|
||||
|
||||
/* */
|
||||
/* #undef LOG4CPLUS_HAVE_VSPRINTF_S */
|
||||
|
||||
/* */
|
||||
/* #undef LOG4CPLUS_HAVE_VSWPRINTF_S */
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_WCHAR_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_WCSTOMBS 1
|
||||
|
||||
/* */
|
||||
/* #undef LOG4CPLUS_HAVE__VSNPRINTF */
|
||||
|
||||
/* */
|
||||
/* #undef LOG4CPLUS_HAVE__VSNPRINTF_S */
|
||||
|
||||
/* */
|
||||
/* #undef LOG4CPLUS_HAVE__VSNWPRINTF */
|
||||
|
||||
/* */
|
||||
/* #undef LOG4CPLUS_HAVE__VSNWPRINTF_S */
|
||||
|
||||
/* Define if this is a single-threaded library. */
|
||||
/* #undef LOG4CPLUS_SINGLE_THREADED */
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_THREAD_LOCAL_VAR thread_local
|
||||
|
||||
/* */
|
||||
/* #undef LOG4CPLUS_USE_PTHREADS */
|
||||
|
||||
/* Define when iconv() is available. */
|
||||
/* #undef LOG4CPLUS_WITH_ICONV */
|
||||
|
||||
/* Defined to enable unit tests. */
|
||||
/* #undef LOG4CPLUS_WITH_UNIT_TESTS */
|
||||
|
||||
/* Define for C99 compilers/standard libraries that support more than just the
|
||||
"C" locale. */
|
||||
/* #undef LOG4CPLUS_WORKING_C_LOCALE */
|
||||
|
||||
/* Define for compilers/standard libraries that support more than just the "C"
|
||||
locale. */
|
||||
/* #undef LOG4CPLUS_WORKING_LOCALE */
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#define LT_OBJDIR ".libs/"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT ""
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "log4cplus"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "log4cplus 2.1.2"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "log4cplus"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "2.1.2"
|
||||
|
||||
/* Define to necessary symbol if this constant uses a non-standard name on
|
||||
your system. */
|
||||
/* #undef PTHREAD_CREATE_JOINABLE */
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Defined to the actual TLS support construct. */
|
||||
#define TLS_SUPPORT_CONSTRUCT thread_local
|
||||
|
||||
/* Substitute for socklen_t */
|
||||
/* #undef socklen_t */
|
||||
|
||||
#endif // LOG4CPLUS_CONFIG_H
|
||||
248
LFtid1056/cloudfront/code/log4cplus/config/defines.hxx
Normal file
248
LFtid1056/cloudfront/code/log4cplus/config/defines.hxx
Normal file
@@ -0,0 +1,248 @@
|
||||
/* include/log4cplus/config/defines.hxx. Generated from defines.hxx.in by configure. */
|
||||
#ifndef LOG4CPLUS_CONFIG_DEFINES_HXX
|
||||
#define LOG4CPLUS_CONFIG_DEFINES_HXX
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_SYSLOG_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_ARPA_INET_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_NETINET_IN_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_NETINET_TCP_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_SYS_TIMEB_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_SYS_TIME_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_SYS_STAT_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_SYS_SYSCALL_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_SYS_FILE_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_TIME_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_SYS_SOCKET_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_NETDB_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_UNISTD_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_FCNTL_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_STDARG_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_STDIO_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_STDLIB_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_ERRNO_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_WCHAR_H 1
|
||||
|
||||
/* */
|
||||
/* #undef LOG4CPLUS_HAVE_ICONV_H */
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_LIMITS_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_FTIME 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_GETADDRINFO 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_GETHOSTBYNAME_R 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_GETPID 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_GMTIME_R 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_HTONL 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_HTONS 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_LOCALTIME_R 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_LSTAT 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_FCNTL 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_LOCKF 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_FLOCK 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_NTOHL 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_NTOHS 1
|
||||
|
||||
/* Define to 1 if you have the `shutdown' function. */
|
||||
#define LOG4CPLUS_HAVE_SHUTDOWN 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_PIPE 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_PIPE2 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_POLL 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_POLL_H 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_STAT 1
|
||||
|
||||
/* Define if this is a single-threaded library. */
|
||||
/* #undef LOG4CPLUS_SINGLE_THREADED */
|
||||
|
||||
/* */
|
||||
/* #undef LOG4CPLUS_USE_PTHREADS */
|
||||
|
||||
/* Define for compilers/standard libraries that support more than just the "C"
|
||||
locale. */
|
||||
/* #undef LOG4CPLUS_WORKING_LOCALE */
|
||||
|
||||
/* Define for C99 compilers/standard libraries that support more than just the
|
||||
"C" locale. */
|
||||
/* #undef LOG4CPLUS_WORKING_C_LOCALE */
|
||||
|
||||
/* Define to int if undefined. */
|
||||
/* #undef socklen_t */
|
||||
|
||||
/* Defined for --enable-debugging builds. */
|
||||
/* #undef LOG4CPLUS_DEBUGGING */
|
||||
|
||||
/* Defined if the compiler understands __declspec(dllexport) or
|
||||
__attribute__((visibility("default"))) construct. */
|
||||
#define LOG4CPLUS_DECLSPEC_EXPORT __attribute__ ((visibility("default")))
|
||||
|
||||
/* Defined if the compiler understands __declspec(dllimport) or
|
||||
__attribute__((visibility("default"))) construct. */
|
||||
#define LOG4CPLUS_DECLSPEC_IMPORT __attribute__ ((visibility("default")))
|
||||
|
||||
/* Defined if the compiler understands
|
||||
__attribute__((visibility("hidden"))) construct. */
|
||||
#define LOG4CPLUS_DECLSPEC_PRIVATE __attribute__ ((visibility("hidden")))
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_TLS_SUPPORT 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_THREAD_LOCAL_VAR thread_local
|
||||
|
||||
/* Defined if the host OS provides ENAMETOOLONG errno value. */
|
||||
#define LOG4CPLUS_HAVE_ENAMETOOLONG 1
|
||||
|
||||
/* */
|
||||
#define LOG4CPLUS_HAVE_VSNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `vsnwprintf' function. */
|
||||
/* #undef LOG4CPLUS_HAVE_VSNWPRINTF */
|
||||
|
||||
/* Define to 1 if you have the `_vsnwprintf' function. */
|
||||
/* #undef LOG4CPLUS_HAVE__VSNWPRINTF */
|
||||
|
||||
/* */
|
||||
/* #undef LOG4CPLUS_HAVE__VSNPRINTF */
|
||||
|
||||
/* Define to 1 if you have the `vfprintf_s' function. */
|
||||
/* #undef LOG4CPLUS_HAVE_VFPRINTF_S */
|
||||
|
||||
/* Define to 1 if you have the `vfwprintf_s' function. */
|
||||
/* #undef LOG4CPLUS_HAVE_VFWPRINTF_S */
|
||||
|
||||
/* Define to 1 if you have the `vsprintf_s' function. */
|
||||
/* #undef LOG4CPLUS_HAVE_VSPRINTF_S */
|
||||
|
||||
/* Define to 1 if you have the `vswprintf_s' function. */
|
||||
/* #undef LOG4CPLUS_HAVE_VSWPRINTF_S */
|
||||
|
||||
/* Define to 1 if you have the `_vsnprintf_s' function. */
|
||||
/* #undef LOG4CPLUS_HAVE__VSNPRINTF_S */
|
||||
|
||||
/* Define to 1 if you have the `_vsnwprintf_s' function. */
|
||||
/* #undef LOG4CPLUS_HAVE__VSNWPRINTF_S */
|
||||
|
||||
/* Defined if the compiler supports __FUNCTION__ macro. */
|
||||
#define LOG4CPLUS_HAVE_FUNCTION_MACRO 1
|
||||
|
||||
/* Defined if the compiler supports __PRETTY_FUNCTION__ macro. */
|
||||
#define LOG4CPLUS_HAVE_PRETTY_FUNCTION_MACRO 1
|
||||
|
||||
/* Defined if the compiler supports __func__ symbol. */
|
||||
#define LOG4CPLUS_HAVE_FUNC_SYMBOL 1
|
||||
|
||||
/* Define to 1 if you have the `mbstowcs' function. */
|
||||
#define LOG4CPLUS_HAVE_MBSTOWCS 1
|
||||
|
||||
/* Define to 1 if you have the `wcstombs' function. */
|
||||
#define LOG4CPLUS_HAVE_WCSTOMBS 1
|
||||
|
||||
/* Define to 1 if you have Linux style syscall(SYS_gettid). */
|
||||
#define LOG4CPLUS_HAVE_GETTID 1
|
||||
|
||||
/* Define when iconv() is available. */
|
||||
/* #undef LOG4CPLUS_WITH_ICONV */
|
||||
|
||||
/* Define to 1 if you have the `iconv' function. */
|
||||
/* #undef LOG4CPLUS_HAVE_ICONV */
|
||||
|
||||
/* Define to 1 if you have the `iconv_close' function. */
|
||||
/* #undef LOG4CPLUS_HAVE_ICONV_CLOSE */
|
||||
|
||||
/* Define to 1 if you have the `iconv_open' function. */
|
||||
/* #undef LOG4CPLUS_HAVE_ICONV_OPEN */
|
||||
|
||||
/* Define to 1 if you have the `OutputDebugString' function. */
|
||||
/* #undef LOG4CPLUS_HAVE_OUTPUTDEBUGSTRING */
|
||||
|
||||
/* Define to 1 if the system has the `constructor' function attribute
|
||||
with priority */
|
||||
#define LOG4CPLUS_HAVE_FUNC_ATTRIBUTE_CONSTRUCTOR_PRIORITY 1
|
||||
|
||||
/* Define to 1 if the system has the `constructor' function attribute */
|
||||
#define LOG4CPLUS_HAVE_FUNC_ATTRIBUTE_CONSTRUCTOR 1
|
||||
|
||||
/* Define to 1 if the system has the `init_priority' variable attribute */
|
||||
#define LOG4CPLUS_HAVE_VAR_ATTRIBUTE_INIT_PRIORITY 1
|
||||
|
||||
/* Defined to enable unit tests. */
|
||||
/* #undef LOG4CPLUS_WITH_UNIT_TESTS */
|
||||
|
||||
#endif // LOG4CPLUS_CONFIG_DEFINES_HXX
|
||||
1
LFtid1056/cloudfront/code/log4cplus/config/stamp-h2
Normal file
1
LFtid1056/cloudfront/code/log4cplus/config/stamp-h2
Normal file
@@ -0,0 +1 @@
|
||||
timestamp for include/log4cplus/config/defines.hxx
|
||||
1
LFtid1056/cloudfront/code/log4cplus/stamp-h1
Normal file
1
LFtid1056/cloudfront/code/log4cplus/stamp-h1
Normal file
@@ -0,0 +1 @@
|
||||
timestamp for include/log4cplus/config.h
|
||||
597
LFtid1056/cloudfront/code/main.cpp
Normal file
597
LFtid1056/cloudfront/code/main.cpp
Normal file
@@ -0,0 +1,597 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <memory>
|
||||
#include <queue> //任务队列
|
||||
#include <csignal> //信号处理
|
||||
#include <iostream> //标准输入输出
|
||||
#include <string> //字符串
|
||||
#include <vector> //数组型容器
|
||||
#include <map> //映射
|
||||
#include <mutex> //锁
|
||||
#include <thread> //线程
|
||||
#include <condition_variable> //线程控制
|
||||
#include <atomic> //原子操作
|
||||
#include <chrono> //时间
|
||||
#include <ctime> //时间
|
||||
#include <sstream> //流处理
|
||||
#include <cstdio> //字符处理
|
||||
#include <iomanip> //格式控制
|
||||
#include <functional> //类消费者绑定
|
||||
#include <unistd.h> //获取目录
|
||||
#include <array>
|
||||
#include <list>
|
||||
#include <cstdio>
|
||||
#include <sys/stat.h>
|
||||
#include <fnmatch.h>
|
||||
#include <libgen.h>
|
||||
#include <cstdlib>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "interface.h" //用于访问接口
|
||||
#include "log4.h" //用于日志
|
||||
#include "curl/curl.h" //用于访问接口
|
||||
#include "nlohmann/json.hpp" //用于构造json
|
||||
#include "worker.h" //shell接口
|
||||
#include "rocketmq.h"
|
||||
#include "rocketmq/MQClientException.h"
|
||||
#include "front.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////全局变量
|
||||
|
||||
//前置程序路径
|
||||
std::string FRONT_PATH;
|
||||
|
||||
|
||||
|
||||
//初始化标志
|
||||
int INITFLAG = 0;
|
||||
|
||||
//前置标置
|
||||
std::string subdir = "cfg_stat_data"; //默认稳态
|
||||
uint32_t g_node_id = 0;
|
||||
int g_front_seg_index = 0; //默认单进程
|
||||
int g_front_seg_num = 0; //默认单进程
|
||||
|
||||
//实时进程标志
|
||||
int three_secs_enabled = 0;
|
||||
|
||||
//稳态进程自动注册报告标志
|
||||
int auto_register_report_enabled = 0;
|
||||
|
||||
//mq生产线程和定时线程都加上死锁计数器
|
||||
uint32_t g_mqproducer_blocked_times = 0;
|
||||
uint32_t g_ontime_blocked_times = 0;
|
||||
|
||||
//进程控制
|
||||
std::atomic<bool> running{true};
|
||||
void onSignal(int){ running = false; }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern int G_TEST_FLAG; //测试线程开启开关
|
||||
extern int TEST_PORT; //测试端口号
|
||||
|
||||
extern std::string FRONT_INST;
|
||||
|
||||
extern std::mutex queue_data_list_mutex;
|
||||
extern std::list<queue_data_t> queue_data_list;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 功能函数
|
||||
|
||||
template<typename T, typename... Args>
|
||||
std::unique_ptr<T> make_unique(Args&&... args) {
|
||||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
//处理参数
|
||||
bool parse_param(int argc, char* argv[]) {
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
std::string arg = argv[i];
|
||||
|
||||
// 处理 -s 参数
|
||||
if (arg == "-s" && i + 1 < argc) {
|
||||
std::string val = argv[++i];
|
||||
auto pos = val.find('_');
|
||||
if (pos != std::string::npos) {
|
||||
try {
|
||||
g_front_seg_index = std::stoi(val.substr(0, pos));
|
||||
g_front_seg_num = std::stoi(val.substr(pos + 1));
|
||||
} catch (...) {
|
||||
std::cerr << "Invalid -s format." << std::endl;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// 处理 -s1_5 这种紧凑写法
|
||||
if (arg.rfind("-s", 0) == 0 && arg.length() > 2) {
|
||||
std::string val = arg.substr(2);
|
||||
auto pos = val.find('_');
|
||||
if (pos != std::string::npos) {
|
||||
try {
|
||||
g_front_seg_index = std::stoi(val.substr(0, pos));
|
||||
g_front_seg_num = std::stoi(val.substr(pos + 1));
|
||||
} catch (...) {
|
||||
std::cerr << "Invalid -s format." << std::endl;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// 处理 -d 或 -D 参数
|
||||
if ((arg == "-d" || arg == "-D") && i + 1 < argc) {
|
||||
subdir = argv[++i];
|
||||
continue;
|
||||
}
|
||||
if ((arg.rfind("-d", 0) == 0 || arg.rfind("-D", 0) == 0) && arg.length() > 2) {
|
||||
subdir = arg.substr(2);
|
||||
continue;
|
||||
}
|
||||
// 这里可以继续添加其它参数解析,例如 -x, -y
|
||||
// if (arg == "-x" ... ) {...}
|
||||
}
|
||||
|
||||
// 输出结果
|
||||
std::cout << "g_front_seg_index: " << g_front_seg_index << "\n";
|
||||
std::cout << "g_front_seg_num : " << g_front_seg_num << "\n";
|
||||
std::cout << "subdir : " << subdir << "\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
//获取前置类型
|
||||
void init_global_function_enable() {
|
||||
if (subdir == "cfg_stat_data") { // 历史稳态
|
||||
g_node_id = STAT_DATA_BASE_NODE_ID;
|
||||
auto_register_report_enabled = 1;
|
||||
} else if (subdir == "cfg_3s_data") { // 实时
|
||||
g_node_id = THREE_SECS_DATA_BASE_NODE_ID;
|
||||
three_secs_enabled = 1;
|
||||
} else if (subdir == "cfg_soe_comtrade") { // 告警、录波、暂态
|
||||
g_node_id = SOE_COMTRADE_BASE_NODE_ID;
|
||||
} else if (subdir == "cfg_recallhis_data") { // 补招
|
||||
g_node_id = RECALL_HIS_DATA_BASE_NODE_ID;
|
||||
}
|
||||
}
|
||||
|
||||
//获取功能名称
|
||||
std::string get_front_msg_from_subdir() {
|
||||
if (subdir.find("cfg_3s_data") != std::string::npos)
|
||||
return "实时数据进程";
|
||||
else if (subdir.find("cfg_soe_comtrade") != std::string::npos)
|
||||
return "暂态和告警进程";
|
||||
else if (subdir.find("cfg_recallhis_data") != std::string::npos)
|
||||
return "稳态补招进程";
|
||||
else if (subdir.find("cfg_stat_data") != std::string::npos)
|
||||
return "稳态统计进程";
|
||||
else
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
//获取前置路径
|
||||
std::string get_parent_directory() {
|
||||
// 获取当前工作目录
|
||||
char cwd[PATH_MAX];
|
||||
if (!getcwd(cwd, sizeof(cwd))) {
|
||||
// 获取失败
|
||||
return "";
|
||||
}
|
||||
// dirname 可能会修改传入的字符串,需要副本
|
||||
std::string current_dir(cwd);
|
||||
std::unique_ptr<char[]> temp(new char[current_dir.size() + 1]);
|
||||
std::strcpy(temp.get(), current_dir.c_str());
|
||||
|
||||
// 获取父目录
|
||||
char* parent = dirname(temp.get());
|
||||
if (!parent) return "";
|
||||
|
||||
// 返回绝对路径
|
||||
return std::string(parent);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////主要类结构
|
||||
|
||||
//------------------- Front 类(C++) -------------------
|
||||
|
||||
//构造函数
|
||||
Front::Front():
|
||||
m_worker(this),
|
||||
m_threadPool(std::thread::hardware_concurrency()) // 用系统核数初始化线程池
|
||||
{
|
||||
|
||||
//初始化g_node_id
|
||||
init_global_function_enable();
|
||||
|
||||
//配置初始化
|
||||
init_config();
|
||||
|
||||
//启动进程日志
|
||||
init_logger_process();
|
||||
DIY_WARNLOG("process","【WARN】前置的%s%d号进程 进程级日志初始化完毕", get_front_msg_from_subdir(), g_front_seg_index);
|
||||
|
||||
//读取台账
|
||||
parse_device_cfg_web();
|
||||
|
||||
//初始化日志
|
||||
init_loggers();
|
||||
|
||||
//读取模型,下载文件
|
||||
parse_model_cfg_web();
|
||||
|
||||
//解析文件
|
||||
Set_xml_nodeinfo();
|
||||
|
||||
StartFrontThread(); //开启主线程
|
||||
|
||||
StartMQConsumerThread(); //开启消费者线程
|
||||
|
||||
StartMQProducerThread(); //开启生产者线程
|
||||
|
||||
StartTimerThread(); //开启定时线程
|
||||
|
||||
//启动worker 根据启动标志启动
|
||||
if(G_TEST_FLAG){
|
||||
if(!m_worker.startServer(TEST_PORT)) {
|
||||
std::cerr << "[testshell] startServer failed.\n";
|
||||
}
|
||||
}
|
||||
|
||||
//初始化标志
|
||||
std::this_thread::sleep_for(std::chrono::seconds(3));
|
||||
INITFLAG = 1;
|
||||
|
||||
}
|
||||
|
||||
Front::~Front() {
|
||||
FormClosing();
|
||||
}
|
||||
|
||||
// ============ 关闭所有运行中的线程============
|
||||
void Front::FormClosing() {
|
||||
//确保testshell关闭
|
||||
m_worker.stopServer();
|
||||
|
||||
// **确保前置线程被关闭**
|
||||
if(m_FrontThread.joinable()) {
|
||||
m_bIsFrontThreadCancle = true;
|
||||
m_FrontThread.join(); // **等待前置线程结束**
|
||||
}
|
||||
|
||||
// 定时线程
|
||||
if (m_TimerThread.joinable()) {
|
||||
m_IsTimerCancel = true;
|
||||
m_TimerThread.join();
|
||||
}
|
||||
|
||||
// 生产者线程
|
||||
if (m_MQProducerThread.joinable()) {
|
||||
m_IsMQProducerCancel = true;
|
||||
m_MQProducerThread.join();
|
||||
}
|
||||
|
||||
// 消费者线程
|
||||
m_IsMQConsumerCancel = true;
|
||||
|
||||
if (m_mqConsumer) {
|
||||
try {
|
||||
m_mqConsumer->shutdown();
|
||||
} catch (...) {
|
||||
std::cerr << "mq consumer shutdown error" << std::endl;
|
||||
}
|
||||
m_mqConsumer.reset();
|
||||
}
|
||||
|
||||
m_listener.reset();
|
||||
|
||||
if (m_MQConsumerThread.joinable()) {
|
||||
m_MQConsumerThread.join();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//============ 线程函数 ============
|
||||
|
||||
void Front::StartFrontThread() {
|
||||
m_bIsFrontThreadCancle = false;
|
||||
m_FrontThread = std::thread(&Front::FrontThread, this);
|
||||
}
|
||||
|
||||
void Front::StartMQConsumerThread() {
|
||||
m_IsMQConsumerCancel = false;
|
||||
m_MQConsumerThread = std::thread(&Front::mqconsumerThread, this);
|
||||
}
|
||||
|
||||
void Front::StartMQProducerThread() {
|
||||
m_IsMQProducerCancel = false;
|
||||
m_MQProducerThread = std::thread(&Front::mqproducerThread, this);
|
||||
}
|
||||
|
||||
void Front::StartTimerThread() {
|
||||
m_IsTimerCancel = false;
|
||||
m_TimerThread = std::thread(&Front::OnTimerThread, this);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////主功能线程
|
||||
|
||||
void Front::FrontThread() {
|
||||
std::cout << "FrontThread::run() is called ...... \n";
|
||||
|
||||
try {
|
||||
while (!m_bIsFrontThreadCancle) {
|
||||
check_3s_config(); // 实时数据触发
|
||||
create_recall_xml(); // 生成待补招xml文件
|
||||
check_ledger_update(); // 触发台账更新
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "[FrontThread] Caught exception: " << e.what() << std::endl;
|
||||
} catch (...) {
|
||||
std::cerr << "[FrontThread] Caught unknown exception" << std::endl;
|
||||
}
|
||||
|
||||
// 设置重启标志
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_threadCheckMutex);
|
||||
m_needRestartFrontThread = true;
|
||||
}
|
||||
|
||||
std::cout << "[FrontThread] exited, will be restarted by monitor\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////定时任务
|
||||
|
||||
void Front::OnTimerThread()
|
||||
{
|
||||
try {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
std::cout << "OnTimerThread::run() is called ...... \n";
|
||||
|
||||
int counter = 0;
|
||||
send_heartbeat_to_queue("1");
|
||||
|
||||
while (!m_IsTimerCancel)
|
||||
{
|
||||
update_log_entries_countdown();
|
||||
|
||||
if (counter >= 30) {
|
||||
send_heartbeat_to_queue("1");
|
||||
counter = 0;
|
||||
}
|
||||
counter++;
|
||||
|
||||
g_ontime_blocked_times = 0;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "[OnTimerThread] Caught exception: " << e.what() << std::endl;
|
||||
} catch (...) {
|
||||
std::cerr << "[OnTimerThread] Caught unknown exception" << std::endl;
|
||||
}
|
||||
|
||||
// 设置重启标志
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_threadCheckMutex);
|
||||
m_needRestartTimerThread = true;
|
||||
}
|
||||
|
||||
std::cout << "[OnTimerThread] exited, will be restarted by monitor\n";
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////消费者线程
|
||||
|
||||
void Front::mqconsumerThread()
|
||||
{
|
||||
try {
|
||||
std::string consumerGroup = subdir + std::to_string(g_front_seg_index);
|
||||
std::string nameServer = G_MQCONSUMER_IPPORT;
|
||||
std::vector<rocketmq::Subscription> subscriptions;
|
||||
|
||||
if (g_node_id == THREE_SECS_DATA_BASE_NODE_ID) {
|
||||
subscriptions.emplace_back(FRONT_INST + "_" + G_MQCONSUMER_TOPIC_RT, G_MQCONSUMER_TAG_RT, myMessageCallbackrtdata);
|
||||
}
|
||||
subscriptions.emplace_back(FRONT_INST + "_" + G_MQCONSUMER_TOPIC_UD, G_MQCONSUMER_TAG_UD, myMessageCallbackupdate);
|
||||
if (g_node_id == RECALL_HIS_DATA_BASE_NODE_ID) {
|
||||
subscriptions.emplace_back(FRONT_INST + "_" + G_MQCONSUMER_TOPIC_RC, G_MQCONSUMER_TAG_RC, myMessageCallbackrecall);
|
||||
}
|
||||
subscriptions.emplace_back(FRONT_INST + "_" + G_MQCONSUMER_TOPIC_SET, G_MQCONSUMER_TAG_SET, myMessageCallbackset);
|
||||
subscriptions.emplace_back(FRONT_INST + "_" + G_MQCONSUMER_TOPIC_LOG, G_MQCONSUMER_TAG_LOG, myMessageCallbacklog);
|
||||
|
||||
m_mqConsumer = make_unique<rocketmq::DefaultMQPushConsumer>(consumerGroup);
|
||||
m_mqConsumer->setNamesrvAddr(nameServer);
|
||||
m_mqConsumer->setSessionCredentials(G_MQCONSUMER_ACCESSKEY, G_MQCONSUMER_SECRETKEY, G_MQCONSUMER_CHANNEL);
|
||||
m_mqConsumer->setInstanceName("inst_" + std::to_string(sGetMsTime()));
|
||||
m_mqConsumer->setConsumeFromWhere(rocketmq::CONSUME_FROM_LAST_OFFSET);
|
||||
|
||||
std::map<std::string, rocketmq::Subscription::CallbackT> callbackMap;
|
||||
for (const auto& sub : subscriptions) {
|
||||
std::string key = sub.topic + ":" + sub.tag;
|
||||
callbackMap.emplace(key, sub.callback);
|
||||
m_mqConsumer->subscribe(sub.topic, sub.tag);
|
||||
std::cout << "[mqconsumerThread] 已订阅 Topic=\"" << sub.topic << "\", Tag=\"" << sub.tag << "\"" << std::endl;
|
||||
}
|
||||
|
||||
m_listener = std::make_shared<rocketmq::SubscriberListener>(callbackMap);
|
||||
m_mqConsumer->registerMessageListener(m_listener.get());
|
||||
|
||||
m_mqConsumer->start();
|
||||
std::cout << "[mqconsumerThread] Consumer 已启动,等待消息..." << std::endl;
|
||||
|
||||
// ✳️ 保持线程不主动退出,由 RocketMQ 内部驱动执行回调
|
||||
// 如果 RocketMQ 内部机制失败或意外退出线程,就走 catch
|
||||
}
|
||||
catch (const rocketmq::MQClientException& e) {
|
||||
std::cerr << "[mqconsumerThread] MQClientException: " << e.what() << std::endl;
|
||||
std::lock_guard<std::mutex> lock(m_threadCheckMutex);
|
||||
m_needRestartConsumerThread = true;
|
||||
return;
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "[mqconsumerThread] std::exception: " << e.what() << std::endl;
|
||||
std::lock_guard<std::mutex> lock(m_threadCheckMutex);
|
||||
m_needRestartConsumerThread = true;
|
||||
return;
|
||||
} catch (...) {
|
||||
std::cerr << "[mqconsumerThread] Unknown exception" << std::endl;
|
||||
std::lock_guard<std::mutex> lock(m_threadCheckMutex);
|
||||
m_needRestartConsumerThread = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// 程序运行中,消费者会通过回调处理消息,线程保持存活即可
|
||||
std::cout << "[mqconsumerThread] Consumer 线程正在运行,等待消息到达..." << std::endl;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////生产者线程
|
||||
|
||||
void Front::mqproducerThread()
|
||||
{
|
||||
try {
|
||||
// 1. 初始化生产者
|
||||
InitializeProducer(m_producer);
|
||||
std::cout << "\n[mqproducerThread] is running ...... \n\n";
|
||||
|
||||
uint32_t count = 0;
|
||||
|
||||
while (!m_IsMQProducerCancel) {
|
||||
queue_data_t data;
|
||||
bool data_gotten = false;
|
||||
|
||||
if(INITFLAG)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(queue_data_list_mutex);
|
||||
if (!queue_data_list.empty()) {
|
||||
data = queue_data_list.front();
|
||||
queue_data_list.pop_front();
|
||||
data_gotten = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (data_gotten) {
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto ms_part = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
now.time_since_epoch()) % 1000;
|
||||
auto time_t_part = std::chrono::system_clock::to_time_t(now);
|
||||
std::tm tm_buf;
|
||||
localtime_r(&time_t_part, &tm_buf);
|
||||
char timeStr[32];
|
||||
std::strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", &tm_buf);
|
||||
|
||||
std::cout << "BEGIN my_queue_send no." << count
|
||||
<< " >>>> " << timeStr
|
||||
<< "." << std::setw(3) << std::setfill('0') << ms_part.count()
|
||||
<< std::endl;
|
||||
|
||||
// 调用实际发送
|
||||
my_rocketmq_send(data, m_producer);
|
||||
|
||||
now = std::chrono::system_clock::now();
|
||||
ms_part = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
now.time_since_epoch()) % 1000;
|
||||
time_t_part = std::chrono::system_clock::to_time_t(now);
|
||||
localtime_r(&time_t_part, &tm_buf);
|
||||
std::strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", &tm_buf);
|
||||
|
||||
std::cout << "END my_queue_send no." << count++
|
||||
<< " >>>> " << timeStr
|
||||
<< "." << std::setw(3) << std::setfill('0') << ms_part.count()
|
||||
<< "\n\n";
|
||||
}
|
||||
|
||||
g_mqproducer_blocked_times = 0;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
|
||||
std::cout << "[mqproducerThread] 正常退出\n";
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "[mqproducerThread] std::exception: " << e.what() << std::endl;
|
||||
std::lock_guard<std::mutex> lock(m_threadCheckMutex);
|
||||
m_needRestartProducerThread = true;
|
||||
}
|
||||
catch (...) {
|
||||
std::cerr << "[mqproducerThread] unknown exception\n";
|
||||
std::lock_guard<std::mutex> lock(m_threadCheckMutex);
|
||||
m_needRestartProducerThread = true;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////用例,除通讯外其他功能都可实现
|
||||
|
||||
//int main(int argc char** argv) //变为线程
|
||||
|
||||
extern thread_info_t thread_info[THREAD_CONNECTIONS];
|
||||
|
||||
void* cloudfrontthread(void* arg) {
|
||||
///////////////////////////////////////
|
||||
ThreadArgs* args = static_cast<ThreadArgs*>(arg);
|
||||
int argc = args->argc;
|
||||
char **argv = args->argv;
|
||||
|
||||
printf("argc = %d, argv[0] = %s\n", argc, argv[0]);
|
||||
|
||||
//添加线程处理
|
||||
int index = *(int*)argv[0];
|
||||
|
||||
// 更新线程状态为运行中
|
||||
pthread_mutex_lock(&thread_info[index].lock);
|
||||
printf("cloudfrontthread %d started\n", index);
|
||||
thread_info[index].state = THREAD_RUNNING;
|
||||
pthread_mutex_unlock(&thread_info[index].lock);
|
||||
|
||||
///////////////////////////////////////
|
||||
// 解析命令行参数
|
||||
if(!parse_param(argc,argv)){
|
||||
std::cerr << "process param error,exit" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// 线程使用完后清理参数
|
||||
delete args;
|
||||
|
||||
//路径获取
|
||||
FRONT_PATH = get_parent_directory();
|
||||
std::cout << "FRONT_PATH:" << FRONT_PATH << std::endl;
|
||||
|
||||
//声明前置
|
||||
std::unique_ptr<Front> FrontProcess;
|
||||
FrontProcess = make_unique<Front>();
|
||||
|
||||
std::cout << "[Main] Program running in background.\n";
|
||||
|
||||
// 5) 主线程保持后台运行
|
||||
while(running) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(FrontProcess->m_threadCheckMutex);
|
||||
|
||||
if (FrontProcess->m_needRestartFrontThread) {
|
||||
std::cout << "[Monitor] Restarting FrontThread..." << std::endl;
|
||||
FrontProcess->StartFrontThread();
|
||||
FrontProcess->m_needRestartFrontThread = false;
|
||||
}
|
||||
|
||||
if (FrontProcess->m_needRestartConsumerThread) {
|
||||
std::cout << "[Monitor] Restarting MQConsumerThread..." << std::endl;
|
||||
FrontProcess->StartMQConsumerThread();
|
||||
FrontProcess->m_needRestartConsumerThread = false;
|
||||
}
|
||||
|
||||
if (FrontProcess->m_needRestartProducerThread) {
|
||||
std::cout << "[Monitor] Restarting MQProducerThread..." << std::endl;
|
||||
FrontProcess->StartMQProducerThread();
|
||||
FrontProcess->m_needRestartProducerThread = false;
|
||||
}
|
||||
|
||||
if (FrontProcess->m_needRestartTimerThread) {
|
||||
std::cout << "[Monitor] Restarting TimerThread..." << std::endl;
|
||||
FrontProcess->StartTimerThread();
|
||||
FrontProcess->m_needRestartTimerThread = false;
|
||||
}
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::seconds(60));//每分钟检测一次
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
1618
LFtid1056/cloudfront/code/rocketmq.cpp
Normal file
1618
LFtid1056/cloudfront/code/rocketmq.cpp
Normal file
File diff suppressed because it is too large
Load Diff
590
LFtid1056/cloudfront/code/worker.cpp
Normal file
590
LFtid1056/cloudfront/code/worker.cpp
Normal file
@@ -0,0 +1,590 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <fnmatch.h>
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
|
||||
// socket 网络编程
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "worker.h"
|
||||
#include "interface.h"
|
||||
#include "rocketmq.h"
|
||||
#include "log4.h"
|
||||
#include "front.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//shell日志打印开关
|
||||
bool showinshellflag =false;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern std::list<std::string> errorList, warnList, normalList;
|
||||
extern std::mutex errorListMutex, warnListMutex, normalListMutex;
|
||||
|
||||
extern std::vector<terminal_dev> terminal_devlist;
|
||||
extern std::mutex ledgermtx;
|
||||
|
||||
extern std::list<queue_data_t> queue_data_list;
|
||||
|
||||
extern int IED_COUNT;
|
||||
extern int INITFLAG;
|
||||
extern int g_front_seg_index;
|
||||
extern std::string subdir;
|
||||
|
||||
extern int G_TEST_NUM;
|
||||
extern int G_TEST_TYPE;
|
||||
|
||||
extern bool errorOutputEnabled;
|
||||
extern bool warnOutputEnabled;
|
||||
extern bool normalOutputEnabled;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////测试登录类
|
||||
|
||||
Worker::Worker(Front* front)
|
||||
: m_front(front), listenFD(-1), running(false), historyIndex(-1), stopViewLog(true), g_stopTelnetTest(true) {}
|
||||
|
||||
Worker::~Worker() {
|
||||
stopServer();
|
||||
}
|
||||
|
||||
// 启动 Telnet 服务(监听端口)
|
||||
bool Worker::startServer(int port) {
|
||||
if (running) return false;
|
||||
|
||||
listenFD = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (listenFD < 0) return false;
|
||||
|
||||
int opt = 1;
|
||||
setsockopt(listenFD, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
||||
|
||||
sockaddr_in addr{};
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
addr.sin_port = htons(port);
|
||||
|
||||
if (bind(listenFD, (sockaddr*)&addr, sizeof(addr)) < 0) return false;
|
||||
if (listen(listenFD, 5) < 0) return false;
|
||||
|
||||
running = true;
|
||||
serverThread = std::thread(&Worker::acceptLoop, this);
|
||||
|
||||
std::thread periodicThread(&Worker::doPeriodicTask, this);
|
||||
periodicThread.detach();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 停止 Telnet 服务
|
||||
void Worker::stopServer() {
|
||||
if (!running) return;
|
||||
running = false;
|
||||
shutdown(listenFD, SHUT_RDWR);
|
||||
close(listenFD);
|
||||
if (serverThread.joinable()) serverThread.join();
|
||||
}
|
||||
|
||||
// 发送字符串
|
||||
void Worker::sendStr(int fd, const std::string& s) {
|
||||
send(fd, s.c_str(), s.size(), 0);
|
||||
}
|
||||
|
||||
// 接收客户端连接主循环
|
||||
void Worker::acceptLoop() {
|
||||
while (running) {
|
||||
sockaddr_in caddr;
|
||||
socklen_t clen = sizeof(caddr);
|
||||
int cfd = accept(listenFD, (sockaddr*)&caddr, &clen);
|
||||
if (cfd >= 0) std::thread(&Worker::sessionThread, this, cfd).detach();
|
||||
}
|
||||
}
|
||||
|
||||
//打印提示符
|
||||
void Worker::printPrompt(int clientFD)
|
||||
{
|
||||
sendStr(clientFD, "\r\n>");
|
||||
}
|
||||
|
||||
// 客户端会话线程处理函数
|
||||
void Worker::sessionThread(int clientFD) {
|
||||
sendTelnetNegotiation(clientFD);
|
||||
sendStr(clientFD, "\r\nWelcome to the test shell. Type 'help'.\r\n> ");
|
||||
|
||||
while (true) {
|
||||
char buf[512];
|
||||
int n = recv(clientFD, buf, sizeof(buf), 0);
|
||||
if (n <= 0) break;
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
unsigned char c = (unsigned char)buf[i];
|
||||
|
||||
// 如果不是可打印字符,且也不是 上/下箭头、退格、回车等,就忽略
|
||||
bool isPrintable = (c >= 32 && c <= 126); //可见字符范围
|
||||
bool isArrowOrEsc = (c == 0x1b); //ESC
|
||||
bool isEnter = (c == '\r' || c == '\n'); //换行
|
||||
bool isBackspace = (c == 0x7f || c == 0x08);//退格
|
||||
bool isTab = (c == '\t'); //tab
|
||||
if( !isPrintable && !isArrowOrEsc && !isEnter && !isBackspace && !isTab )
|
||||
{
|
||||
// 跳过不认识的控制字符:如 '\0'
|
||||
continue;
|
||||
}
|
||||
|
||||
// Telnet 协议协商处理
|
||||
if (c == IAC) {
|
||||
if (i + 1 < n && (buf[i+1] == TELDO || buf[i+1] == DONT || buf[i+1] == WILL || buf[i+1] == WONT)) i += 2;
|
||||
else i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 退出 viewlog / telnet 流程
|
||||
if (c == '`') {
|
||||
stopViewLog = true; // [MOD] 支持停止日志查看
|
||||
g_stopTelnetTest = true; // [MOD] 停止 telnet 测试
|
||||
sendStr(clientFD, "\r\n[Log view stopped]\r\n> ");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 2) 回车/换行 => 执行命令
|
||||
if (c == '\r' || c == '\n')
|
||||
{
|
||||
// 如果当前是 '\r' 并且下一个是 '\n',就跳过 '\n'
|
||||
if (c == '\r') {
|
||||
if (i + 1 < n && buf[i+1] == '\n') {
|
||||
i++;
|
||||
}
|
||||
// 这里再加一步,如果紧跟着是 '\0',也跳过
|
||||
if (i + 1 < n && buf[i+1] == '\0') {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
// 如果当前是 '\n',也可以检查一下下一个是不是 '\0'(有些客户端可能发 '\n\0')
|
||||
else {
|
||||
if (i + 1 < n && buf[i+1] == '\0') {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// 现在把 当前输入的指令 前后空白去掉
|
||||
std::string cmdtrim = trim(currentCommand);
|
||||
if (!cmdtrim.empty()) { //输入指令非空则记录到历史
|
||||
|
||||
if (commandHistory.empty() || commandHistory.back() != cmdtrim) { //防止连续重复的历史记录
|
||||
commandHistory.push_back(cmdtrim);
|
||||
}
|
||||
|
||||
historyIndex = commandHistory.size(); //更新历史指令下标
|
||||
|
||||
processCommand(cmdtrim, clientFD); //处理当前指令
|
||||
}
|
||||
|
||||
// 处理后清空并打印新的提示符
|
||||
currentCommand.clear();
|
||||
printPrompt(clientFD);
|
||||
|
||||
// 回车后处理新的命令行
|
||||
continue;
|
||||
}
|
||||
|
||||
// 上/下箭头处理
|
||||
if (c == 0x1b && i + 2 < n && buf[i+1] == '[') {
|
||||
char arrow = buf[i+2];
|
||||
if (arrow == 'A') handleUpArrow(clientFD);
|
||||
else if (arrow == 'B') handleDownArrow(clientFD);
|
||||
i += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 退格处理
|
||||
if (c == 0x7f || c == 0x08) {
|
||||
if (!currentCommand.empty()) {
|
||||
currentCommand.pop_back();
|
||||
sendStr(clientFD, "\b \b");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// 普通字符输入
|
||||
currentCommand.push_back((char)c);
|
||||
sendBytes(clientFD, (const char*)&c, 1);
|
||||
}
|
||||
}
|
||||
|
||||
close(clientFD);
|
||||
}
|
||||
|
||||
// 发送 Telnet 协商指令
|
||||
void Worker::sendTelnetNegotiation(int clientFD) {
|
||||
unsigned char will_echo[3] = { IAC, WILL, TELOPT_ECHO };
|
||||
unsigned char will_sga[3] = { IAC, WILL, TELOPT_SUPPRESS_GO_AHEAD };
|
||||
unsigned char dont_lin[3] = { IAC, DONT, TELOPT_LINEMODE };
|
||||
sendBytes(clientFD, (const char*)will_echo, 3);
|
||||
sendBytes(clientFD, (const char*)will_sga, 3);
|
||||
sendBytes(clientFD, (const char*)dont_lin, 3);
|
||||
}
|
||||
|
||||
// 发送字节数组
|
||||
void Worker::sendBytes(int fd, const char* buf, int len) {
|
||||
send(fd, buf, len, 0);
|
||||
}
|
||||
|
||||
void Worker::setTestNum(int num) {
|
||||
std::lock_guard<std::mutex> locker(testMutex);
|
||||
G_TEST_NUM = num;
|
||||
}
|
||||
|
||||
void Worker::setTestType(int type) {
|
||||
std::lock_guard<std::mutex> locker(testMutex);
|
||||
G_TEST_TYPE = type;
|
||||
}
|
||||
|
||||
// 日志控制
|
||||
void Worker::setTestlog(bool flag) {
|
||||
redirectErrorOutput(flag);
|
||||
redirectWarnOutput(flag);
|
||||
redirectNormalOutput(flag);
|
||||
}
|
||||
|
||||
void Worker::doPeriodicTask() {
|
||||
while (running) {
|
||||
{
|
||||
std::lock_guard<std::mutex> locker(testMutex);
|
||||
std::cout << "[PeriodicTask] G_TEST_NUM = " << G_TEST_NUM
|
||||
<< ", G_TEST_TYPE = " << G_TEST_TYPE << std::endl;
|
||||
|
||||
if (G_TEST_NUM != 0) {
|
||||
std::cout << "[PeriodicTask] Executing rocketmq_test_300()\n";
|
||||
rocketmq_test_300(G_TEST_NUM, g_front_seg_index, G_TEST_TYPE,m_front);
|
||||
}
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::seconds(60)); // 每 60 秒执行一次
|
||||
}
|
||||
}
|
||||
|
||||
// 命令处理逻辑扩展
|
||||
void Worker::processCommand(const std::string &cmd, int clientFD) {
|
||||
std::cout << "Received command: " << cmd << std::endl;
|
||||
|
||||
if (cmd == "help") {
|
||||
std::string helpText =
|
||||
"Available commands:\r\n"
|
||||
"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"
|
||||
"rc - Execute rocketmq_test_rc\r\n"
|
||||
"rt - Execute rocketmq_test_rt\r\n"
|
||||
"ud - Execute rocketmq_test_ud\r\n"
|
||||
"set - Execute rocketmq_test_set\r\n"
|
||||
"log - Execute rocketmq_test_log\r\n"
|
||||
"upload - Execute upload file\r\n"
|
||||
"qvvr - Execute http_test_qvvr\r\n"
|
||||
"ledger <id> - Execute ledger with optional terminal_id\r\n"
|
||||
"viewlog <level> - View logs (ERROR, WARN, NORMAL, DEBUG)\r\n"
|
||||
"value <valuename> - Execute value print with valuename\r\n"
|
||||
"exit - Exit the shell\r\n"
|
||||
"help - Show this help message\r\n";
|
||||
sendStr(clientFD, "\r\x1B[K" + helpText);
|
||||
} else if (cmd.find("viewlog") == 0) {
|
||||
showinshellflag = true;
|
||||
handleViewLogCommand(cmd, clientFD);
|
||||
} else if (cmd.find("G_TEST_NUM=") == 0) {
|
||||
int num = std::atoi(cmd.substr(9).c_str());
|
||||
setTestNum(num);
|
||||
sendStr(clientFD, "\r\x1B[KTEST_NUM updated\r\n");
|
||||
} else if (cmd.find("G_TEST_TYPE=") == 0) {
|
||||
int type = std::atoi(cmd.substr(10).c_str());
|
||||
setTestType(type);
|
||||
sendStr(clientFD, "\r\x1B[KTEST_TYPE updated\r\n");
|
||||
} else if (cmd.find("LOG=") == 0) {
|
||||
int flag = std::atoi(cmd.substr(4).c_str());
|
||||
setTestlog(flag);
|
||||
sendStr(clientFD, "\r\x1B[KLOG updated\r\n");
|
||||
} else if (cmd == "rc") {
|
||||
rocketmq_test_rc(m_front);
|
||||
sendStr(clientFD, "\r\x1B[KExecuted rocketmq_test_rc\r\n");
|
||||
} else if (cmd == "rt") {
|
||||
rocketmq_test_rt(m_front);
|
||||
sendStr(clientFD, "\r\x1B[KExecuted rocketmq_test_rt\r\n");
|
||||
} else if (cmd == "ud") {
|
||||
rocketmq_test_ud(m_front);
|
||||
sendStr(clientFD, "\r\x1B[KExecuted rocketmq_test_ud\r\n");
|
||||
} else if (cmd == "set") {
|
||||
rocketmq_test_set(m_front);
|
||||
sendStr(clientFD, "\r\x1B[KExecuted rocketmq_test_set\r\n");
|
||||
} else if (cmd == "upload") {
|
||||
Fileupload_test();
|
||||
sendStr(clientFD, "\r\x1B[KExecuted upload file\r\n");
|
||||
} else if (cmd == "qvvr") {
|
||||
qvvr_test();
|
||||
sendStr(clientFD, "\r\x1B[KExecuted http_test_qvvr\r\n");
|
||||
} else if (cmd.find("ledger") == 0) {
|
||||
size_t pos = cmd.find(' ');
|
||||
if (pos != std::string::npos) {
|
||||
std::string terminalId = cmd.substr(pos + 1);
|
||||
ledger(terminalId.c_str(), clientFD);
|
||||
sendStr(clientFD, "\r\x1B[KExecuted ledger with terminal_id\r\n");
|
||||
} else {
|
||||
ledger("", clientFD);
|
||||
sendStr(clientFD, "\r\x1B[KExecuted ledger without parameters\r\n");
|
||||
}
|
||||
} else if (cmd.find("value") == 0) {
|
||||
size_t pos = cmd.find(' ');
|
||||
if (pos != std::string::npos) {
|
||||
std::string var = cmd.substr(pos + 1);
|
||||
sendStr(clientFD, "\r\x1B[KExecuted value with variable name: " + var + "\r\n");
|
||||
value_print(var, clientFD);
|
||||
} else {
|
||||
sendStr(clientFD, "\r\x1B[KPlease provide a variable name\r\n");
|
||||
}
|
||||
} else if (cmd == "exit") {
|
||||
sendStr(clientFD, "\r\x1B[KGoodbye! Exiting shell...\r\n");
|
||||
shutdown(clientFD, SHUT_RDWR);
|
||||
close(clientFD);
|
||||
return;
|
||||
} else {
|
||||
sendStr(clientFD, "\r\x1B[KUnknown command\r\n");
|
||||
}
|
||||
|
||||
// 打印提示符
|
||||
sendStr(clientFD, "> ");
|
||||
}
|
||||
|
||||
// 上箭头历史回溯
|
||||
void Worker::handleUpArrow(int fd) {
|
||||
if (!commandHistory.empty() && historyIndex > 0) {
|
||||
historyIndex--;
|
||||
currentCommand = commandHistory[historyIndex];
|
||||
sendStr(fd, "\r\x1B[K> " + currentCommand);
|
||||
}
|
||||
}
|
||||
|
||||
// 下箭头历史前进
|
||||
void Worker::handleDownArrow(int fd) {
|
||||
if (!commandHistory.empty() && historyIndex < (int)commandHistory.size() - 1) {
|
||||
historyIndex++;
|
||||
currentCommand = commandHistory[historyIndex];
|
||||
sendStr(fd, "\r\x1B[K> " + currentCommand);
|
||||
} else {
|
||||
currentCommand.clear();
|
||||
sendStr(fd, "\r\x1B[K> ");
|
||||
}
|
||||
}
|
||||
|
||||
// 字符串 trim
|
||||
std::string Worker::trim(const std::string& s) {
|
||||
auto start = s.begin();
|
||||
while (start != s.end() && std::isspace(*start)) ++start;
|
||||
auto end = s.end();
|
||||
do { --end; } while (std::distance(start, end) > 0 && std::isspace(*end));
|
||||
return (start <= end) ? std::string(start, end + 1) : "";
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////测试shell用的函数
|
||||
|
||||
void Worker::printLedgerinshell(const terminal_dev& dev, int fd) {
|
||||
std::ostringstream os;
|
||||
os << "\r\x1B[K------------------------------------\n";
|
||||
os << "\r\x1B[K|-- terminal_id: " << dev.terminal_id << "\n";
|
||||
os << "\r\x1B[K|-- terminal_code: " << dev.terminal_code << "\n";
|
||||
os << "\r\x1B[K|-- dev_ip: " << dev.addr_str << "\n";
|
||||
os << "\r\x1B[K|-- dev_port: " << dev.port << "\n";
|
||||
os << "\r\x1B[K|-- dev_type: " << dev.dev_type << "\n";
|
||||
os << "\r\x1B[K|-- dev_key: " << dev.dev_key << "\n";
|
||||
os << "\r\x1B[K|-- dev_series: " << dev.dev_series << "\n";
|
||||
os << "\r\x1B[K|-- dev_processNo: " << dev.processNo << "\n";
|
||||
os << "\r\x1B[K|-- maxProcessNum: " << dev.maxProcessNum << "\n";
|
||||
os << "\r\x1B[K|-- org_name: " << dev.org_name << "\n";
|
||||
os << "\r\x1B[K|-- maint_name: " << dev.maint_name << "\n";
|
||||
os << "\r\x1B[K|-- station_name: " << dev.station_name << "\n";
|
||||
os << "\r\x1B[K|-- tmnl_factory: " << dev.tmnl_factory << "\n";
|
||||
os << "\r\x1B[K|-- tmnl_status: " << dev.tmnl_status << "\n";
|
||||
os << "\r\x1B[K|-- timestamp: " << dev.timestamp << "\n";
|
||||
|
||||
for (size_t i = 0; i < dev.line.size(); ++i) {
|
||||
const auto& ld = dev.line[i];
|
||||
if (ld.monitor_id.empty()) continue;
|
||||
os << "\r\x1B[K|-- line[" << i << "]:\n";
|
||||
os << "\r\x1B[K |-- monitor_id: " << ld.monitor_id << "\n";
|
||||
os << "\r\x1B[K |-- monitor_name: " << ld.monitor_name << "\n";
|
||||
os << "\r\x1B[K |-- logical_device_seq: " << ld.logical_device_seq << "\n";
|
||||
os << "\r\x1B[K |-- terminal_code: " << ld.terminal_code << "\n";
|
||||
os << "\r\x1B[K |-- voltage_level: " << ld.voltage_level << "\n";
|
||||
os << "\r\x1B[K |-- terminal_connect: " << ld.terminal_connect << "\n";
|
||||
os << "\r\x1B[K |-- status: " << ld.status << "\n";
|
||||
os << "\r\x1B[K |-- timestamp: " << ld.timestamp << "\n";
|
||||
}
|
||||
|
||||
os << "\r\x1B[K------------------------------------\n";
|
||||
sendStr(fd, os.str());
|
||||
}
|
||||
|
||||
void Worker::ledger(const std::string& terminal_id, int fd) {
|
||||
sendStr(fd, "\r\x1B[Kprint ledger in shell\n");
|
||||
std::lock_guard<std::mutex> lock(ledgermtx);
|
||||
bool found = false;
|
||||
|
||||
if (terminal_id.empty()) {
|
||||
for (const auto& dev : terminal_devlist) {
|
||||
printLedgerinshell(dev, fd);
|
||||
}
|
||||
} else {
|
||||
for (const auto& dev : terminal_devlist) {
|
||||
if (dev.terminal_id == terminal_id) {
|
||||
printLedgerinshell(dev, fd);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
std::ostringstream msg;
|
||||
msg << "\r\x1B[Kterminal not exist: " << terminal_id << "\n";
|
||||
sendStr(fd, msg.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////打印指定的变量名
|
||||
|
||||
void Worker::value_print(const std::string& variableName, int clientFD) {
|
||||
std::string output;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(ledgermtx);
|
||||
std::cout << "value_print hold lock !!!!!!!!!!!" << std::endl;
|
||||
|
||||
if (variableName == "frontindex") {
|
||||
output = "frontindex = " + std::to_string(g_front_seg_index);
|
||||
} else if (variableName == "iedcount") {
|
||||
output = "ledger list = " + std::to_string(terminal_devlist.size()) +
|
||||
", ied config count = " + std::to_string(IED_COUNT);
|
||||
} else if (variableName == "frontfun") {
|
||||
output = "frontfun = " + subdir;
|
||||
} else if (variableName == "log") {
|
||||
output = "showinshellflag = " + std::to_string(showinshellflag) +
|
||||
", normalOutputEnabled = " + std::to_string(normalOutputEnabled) +
|
||||
", warnOutputEnabled = " + std::to_string(warnOutputEnabled) +
|
||||
", errorOutputEnabled = " + std::to_string(errorOutputEnabled);
|
||||
} else if (variableName == "init") {
|
||||
output = "INITFLAG = " + std::to_string(INITFLAG);
|
||||
} else {
|
||||
output = "Unknown variable name: " + variableName;
|
||||
}
|
||||
|
||||
std::cout << "value_print free lock !!!!!!!!!!!" << std::endl;
|
||||
}
|
||||
|
||||
sendStr(clientFD, "\r\x1B[K" + output + "\r\n");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////日志开关控制
|
||||
|
||||
//日志消息列表
|
||||
std::list<std::string>* getLogList(const std::string& level) {
|
||||
if (level == "ERROR") return &errorList;
|
||||
if (level == "WARN") return &warnList;
|
||||
if (level == "NORMAL") return &normalList;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//日志锁
|
||||
std::mutex* getLogMutex(const std::string& level) {
|
||||
if (level == "ERROR") return &errorListMutex;
|
||||
if (level == "WARN") return &warnListMutex;
|
||||
if (level == "NORMAL") return &normalListMutex;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Worker::handleViewLogCommand(const std::string& command, int clientFD) {
|
||||
std::istringstream iss(command);
|
||||
std::string cmd, level;
|
||||
iss >> cmd >> level;
|
||||
std::transform(level.begin(), level.end(), level.begin(), ::toupper);
|
||||
|
||||
if (level.empty()) {
|
||||
sendStr(clientFD, "\r\x1B[KUsage: viewlog [ERROR|WARN|NORMAL]\r\n> ");
|
||||
return;
|
||||
}
|
||||
|
||||
std::list<std::string>* logList = getLogList(level);
|
||||
std::mutex* logMutex = getLogMutex(level);
|
||||
|
||||
if (!logList || !logMutex) {
|
||||
sendStr(clientFD, "\r\x1B[KInvalid log level! Use ERROR, WARN, NORMAL.\r\n> ");
|
||||
return;
|
||||
}
|
||||
|
||||
stopViewLog = false;
|
||||
showinshellflag = true;
|
||||
sendStr(clientFD, "\r\x1B[KViewing logs for level: " + level + " (Press '`' to exit)\r\n> ");
|
||||
|
||||
char inputBuf[16];
|
||||
|
||||
while (!stopViewLog) {
|
||||
// 1. 监听 shell 输入退出符号 `
|
||||
fd_set read_fds;
|
||||
FD_ZERO(&read_fds);
|
||||
FD_SET(clientFD, &read_fds);
|
||||
|
||||
timeval timeout;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 500000; // 500ms
|
||||
|
||||
int activity = select(clientFD + 1, &read_fds, nullptr, nullptr, &timeout);
|
||||
if (activity > 0 && FD_ISSET(clientFD, &read_fds)) {
|
||||
int n = recv(clientFD, inputBuf, sizeof(inputBuf), 0);
|
||||
if (n > 0 && strchr(inputBuf, '`')) {
|
||||
stopViewLog = true;
|
||||
showinshellflag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 输出日志
|
||||
std::string logEntry;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(*logMutex);
|
||||
if (!logList->empty()) {
|
||||
logEntry = logList->front();
|
||||
logList->pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
if (!logEntry.empty()) {
|
||||
sendStr(clientFD, "\r\x1B[K" + logEntry + "\r\n");
|
||||
} else {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 打印退出提示
|
||||
sendStr(clientFD, "\r\x1B[K\nLog view stopped. Returning to shell.\r\n> ");
|
||||
}
|
||||
|
||||
BIN
LFtid1056/cloudfront/lib/libcrypto.so
Normal file
BIN
LFtid1056/cloudfront/lib/libcrypto.so
Normal file
Binary file not shown.
BIN
LFtid1056/cloudfront/lib/libcrypto.so.1.0.0
Normal file
BIN
LFtid1056/cloudfront/lib/libcrypto.so.1.0.0
Normal file
Binary file not shown.
BIN
LFtid1056/cloudfront/lib/libcrypto.so.1.1
Normal file
BIN
LFtid1056/cloudfront/lib/libcrypto.so.1.1
Normal file
Binary file not shown.
BIN
LFtid1056/cloudfront/lib/libcurl.a
Normal file
BIN
LFtid1056/cloudfront/lib/libcurl.a
Normal file
Binary file not shown.
41
LFtid1056/cloudfront/lib/libcurl.la
Normal file
41
LFtid1056/cloudfront/lib/libcurl.la
Normal file
@@ -0,0 +1,41 @@
|
||||
# libcurl.la - a libtool library file
|
||||
# Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1.3
|
||||
#
|
||||
# Please DO NOT delete this file!
|
||||
# It is necessary for linking the library.
|
||||
|
||||
# The name that we can dlopen(3).
|
||||
dlname='libcurl.so.4'
|
||||
|
||||
# Names of this library.
|
||||
library_names='libcurl.so.4.3.0 libcurl.so.4 libcurl.so'
|
||||
|
||||
# The name of the static archive.
|
||||
old_library='libcurl.a'
|
||||
|
||||
# Linker flags that can not go in dependency_libs.
|
||||
inherited_linker_flags=''
|
||||
|
||||
# Libraries that this one depends upon.
|
||||
dependency_libs=''
|
||||
|
||||
# Names of additional weak libraries provided by this library
|
||||
weak_library_names=''
|
||||
|
||||
# Version information for libcurl.
|
||||
current=7
|
||||
age=3
|
||||
revision=0
|
||||
|
||||
# Is this an already installed library?
|
||||
installed=yes
|
||||
|
||||
# Should we warn about portability when linking against -modules?
|
||||
shouldnotlink=no
|
||||
|
||||
# Files to dlopen/dlpreopen
|
||||
dlopen=''
|
||||
dlpreopen=''
|
||||
|
||||
# Directory that this library needs to be installed in:
|
||||
libdir='/home/pq/curl/lib'
|
||||
BIN
LFtid1056/cloudfront/lib/libcurl.so
Normal file
BIN
LFtid1056/cloudfront/lib/libcurl.so
Normal file
Binary file not shown.
BIN
LFtid1056/cloudfront/lib/libcurl.so.4
Normal file
BIN
LFtid1056/cloudfront/lib/libcurl.so.4
Normal file
Binary file not shown.
BIN
LFtid1056/cloudfront/lib/libcurl.so.4.3.0
Normal file
BIN
LFtid1056/cloudfront/lib/libcurl.so.4.3.0
Normal file
Binary file not shown.
BIN
LFtid1056/cloudfront/lib/libcurl.so.4.7.0
Normal file
BIN
LFtid1056/cloudfront/lib/libcurl.so.4.7.0
Normal file
Binary file not shown.
BIN
LFtid1056/cloudfront/lib/libssl.so
Normal file
BIN
LFtid1056/cloudfront/lib/libssl.so
Normal file
Binary file not shown.
BIN
LFtid1056/cloudfront/lib/libssl.so.1.0.0
Normal file
BIN
LFtid1056/cloudfront/lib/libssl.so.1.0.0
Normal file
Binary file not shown.
BIN
LFtid1056/cloudfront/lib/libssl.so.1.1
Normal file
BIN
LFtid1056/cloudfront/lib/libssl.so.1.1
Normal file
Binary file not shown.
Reference in New Issue
Block a user