modify log4 function and add data trace function

This commit is contained in:
lnk
2026-03-06 16:27:58 +08:00
parent d5916f5559
commit 748f8481bc
9 changed files with 888 additions and 424 deletions

View File

@@ -4,7 +4,7 @@
#include "../log4cplus/fileappender.h"
#include "../log4cplus/layout.h"
#include "../log4cplus/ndc.h"
#include "../log4cplus/log4.h"
//#include "../log4cplus/log4.h"
#include "../log4cplus/spi/loggingevent.h"
#include <iostream>
#include <map>
@@ -18,21 +18,47 @@
//目录创建
#include <sys/stat.h>
#include <sys/types.h>
//kafka结构定义
#include "../json/mms_json_inter.h"
#include "../mms/rdb_client.h"
#include "../include/node.h"//lnk20241223
#include "../log4cplus/log4.h"//后移防止min/max定义冲突
///////////////////////////////////////////////lnk20260303添加日志上送控制
#include <unordered_map>
#include <chrono>
#include <mutex>
#include <atomic>
#include <memory>
struct LogLevelCache { //记录日志等级的缓存减少频繁访问全局map的开销
std::unordered_map<std::string, int> term_min; // terminal_id -> min level
std::unordered_map<std::string, int> mp_min; // mp_id -> min level
};
// append线程只读不加锁
static std::shared_ptr<LogLevelCache> g_level_cache_sp;
///////////////////////////////////////////////
//用来控制日志上送的结构
struct LOGEntry {
std::string id;
std::string level; // terminal / measurepoint
int code; //code
int min_grade;
int countdown;
};
//日志上送map管理
std::map<std::string, LOGEntry> g_log_entries;
pthread_mutex_t g_log_mutex = PTHREAD_MUTEX_INITIALIZER;
/////////////////////////////////////////////外部定义
extern unsigned int g_node_id;
extern int g_front_seg_index;
extern std::string FRONT_INST;
extern char subdir[128];
extern node_t* g_node;
//mq
extern QMutex kafka_data_list_mutex; //Kafka发送数据锁
extern QList<Ckafka_data_t> kafka_data_list; //kafka发送数据链表
@@ -42,12 +68,153 @@ extern std::string intToString(int number);
//日志主题
extern std::string G_LOG_TOPIC;
/////////////////////////////////////////////////////////
//log4命名空间
using namespace log4cplus;
using namespace log4cplus::helpers;
///////////////////////////////////////////////////////////////
static std::string extract_logger_id(const std::string& logger_name);
////////////////////////////////////////////////////////辅助函数
///////////////////////////////////////////////////////lnk20260303添加日志上送控制
//用于在台账中查询日志上送控制项的日志等级字符串转换为整数
static int int_to_loglevel(int v, int default_level = WARN_LOG_LEVEL)
{
switch (v) {
case 0: return ERROR_LOG_LEVEL;
case 1: return WARN_LOG_LEVEL;
case 2: return INFO_LOG_LEVEL;
case 3: return DEBUG_LOG_LEVEL;
default: return default_level;
}
}
// 构建日志等级缓存,减少 append 线程访问全局 map 的开销
static LogLevelCache* build_cache_unlocked()
{
LogLevelCache* nc = new LogLevelCache;
// 没 node / 没 clients返回空 cache查不到会兜底 WARN
if (!g_node || g_node->n_clients <= 0 || !g_node->clients) {
return nc;
}
// 你 LD_info 是固定 10 个就用 10如果不是改成实际长度
const int MAX_LD = 10;
for (int iedno = 0; iedno < g_node->n_clients; ++iedno) {
ied_t* ied = g_node->clients[iedno];
if (!ied || !ied->usr_ext) continue;
ied_usr_t* ied_usr = (ied_usr_t*)ied->usr_ext;
// terminal_id 必须有效
const char* tid = ied_usr->terminal_id;
if (!tid || tid[0] == '\0') continue;
const std::string terminal_id(tid);
// 装置级阈值0~3 -> log4cplus level默认 WARN
const int term_lv = int_to_loglevel(ied_usr->log_level, WARN_LOG_LEVEL);
nc->term_min[terminal_id] = term_lv;
// 监测点阈值:若非法/缺失,兜底用装置级 term_lv
for (int i = 0; i < MAX_LD; ++i) {
const char* mp = ied_usr->LD_info[i].mp_id;
if (!mp || mp[0] == '\0') continue;
const std::string mp_id(mp);
// mp 的 log_level 优先;非法则用 term_lv
const int mp_lv = int_to_loglevel(ied_usr->LD_info[i].log_level, term_lv);
nc->mp_min[mp_id] = mp_lv;
}
}
return nc;
}
//用于更新日志等级缓存的函数,获取最新的日志上送控制项并更新到缓存中,调用时需持锁
void refresh_log_level_cache_locked()
{
std::shared_ptr<LogLevelCache> nc(build_cache_unlocked());
std::atomic_store(&g_level_cache_sp, nc);
}
const int LOGTYPE_DEFAULT = LOG_CODE_OTHER; // 默认日志类型,表示不区分具体类型的日志上送控制
static const int LOGTYPE_WILDCARD = 999; // 用于匹配任意日志类型的特殊值
static const char* ID_WILDCARD = "all"; // 用于匹配任意 ID 的特殊值
static std::string build_debug_key(const std::string& id,
const std::string& level, // terminal/measurepoint/process
int code) // 日志类型
{
std::ostringstream oss;
oss << id << "|" << level << "|" << code;
return oss.str();
}
static bool find_entry_allow(const std::string& key, int level_val)
{
std::map<std::string, LOGEntry>::iterator it = g_log_entries.find(key);
if (it == g_log_entries.end() || it->second.countdown <= 0) return false;
return level_val >= it->second.min_grade;
}
static bool allow_low_level_send(const std::string& id,
const std::string& level_str,
int code,
int level_val)
{
pthread_mutex_lock(&g_log_mutex);
// 1) 精确
if (find_entry_allow(build_debug_key(id, level_str, code), level_val)) {
pthread_mutex_unlock(&g_log_mutex);
return true;
}
// 2) logtype 通配
if (find_entry_allow(build_debug_key(id, level_str, LOGTYPE_WILDCARD), level_val)) {
pthread_mutex_unlock(&g_log_mutex);
return true;
}
// 3) id 通配
if (find_entry_allow(build_debug_key(ID_WILDCARD, level_str, code), level_val)) {
pthread_mutex_unlock(&g_log_mutex);
return true;
}
// 4) 双通配
if (find_entry_allow(build_debug_key(ID_WILDCARD, level_str, LOGTYPE_WILDCARD), level_val)) {
pthread_mutex_unlock(&g_log_mutex);
return true;
}
pthread_mutex_unlock(&g_log_mutex);
return false;
}
static int get_min_send_level_cached(const std::string& level_str, const std::string& logger_name)
{
const int DEFAULT_LEVEL = WARN_LOG_LEVEL;
if (level_str == "process") return DEFAULT_LEVEL;
const std::string id = extract_logger_id(logger_name); //terminal.<id> / monitor.<mp>
if (id.empty()) return DEFAULT_LEVEL;
std::shared_ptr<LogLevelCache> c = std::atomic_load(&g_level_cache_sp);
if (!c) return DEFAULT_LEVEL;
if (level_str == "terminal") {
auto it = c->term_min.find(id);
return (it != c->term_min.end()) ? it->second : DEFAULT_LEVEL;
}
if (level_str == "measurepoint") {
auto it = c->mp_min.find(id);
return (it != c->mp_min.end()) ? it->second : DEFAULT_LEVEL;
}
return DEFAULT_LEVEL;
}
///////////////////////////////////////////////////////lnk20260303添加日志上送控制
std::string get_front_type_from_subdir() {
if (std::strstr(subdir, "cfg_3s_data") != NULL)
return "realTime";
@@ -79,12 +246,11 @@ bool create_directory_recursive(const std::string& path) {
}
//////////////////////////////////////////////////////////////////////
std::string extract_logger_id(const std::string& logger_name) {
size_t first = logger_name.find('.');
size_t last = logger_name.rfind('.');
if (first != std::string::npos && last != std::string::npos && first + 1 < last) {
return logger_name.substr(first + 1, last - first - 1); // 去掉开头"terminal."和结尾".COM"
}
return "";
if (logger_name == "process") return "process";
size_t pos = logger_name.find('.');
if (pos == std::string::npos) return "";
// 取第一个 '.' 后面的全部terminal.<id> / monitor.<mp>
return logger_name.substr(pos + 1);
}
std::string get_level_str(int level) {
@@ -98,7 +264,7 @@ std::string get_level_str(int level) {
}
//////////////////////////////////////////////////////////////////////
TypedLogger::TypedLogger() {}
TypedLogger::TypedLogger(const Logger& l, int t) : logger(l), logtype(t) {}
TypedLogger::TypedLogger(const Logger& l, int t) : logger(l), code(t) {}
DebugSwitch::DebugSwitch() : debug_open(false), min_level(WARN_LOG_LEVEL) {}
void DebugSwitch::open() { debug_open = true; }
@@ -132,46 +298,65 @@ LOG_TLS int g_log_code_tls = 0;
class SendAppender : public Appender {
protected:
void append(const spi::InternalLoggingEvent& event) {
void append(const spi::InternalLoggingEvent& event) override {
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
else if (logger_name.find("terminal") != std::string::npos)
level_str = "terminal";
else
level_str = "process";
// ★读取 TLS 中的 code(在打日志的线程里由宏设定)
int code = g_log_code_tls; // 若未显式传入,则为 0
int code = g_log_code_tls; // TLS code
int safe_logtype = code; // ★关键:用 code 当 logtype 维度
if (level == ERROR_LOG_LEVEL || level == WARN_LOG_LEVEL || g_debug_switch.match(logger_name, level, logtype)) {
std::ostringstream oss;
oss << "{\"processNo\":\"" << intToString(g_front_seg_index)
<< "\",\"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()
// ★新增:输出 code 字段(整型)
<< "\",\"code\":\"" << code
<< "\",\"log\":\"" << escape_json(msg) << "\"}";
bool allow_send = false;
int min_send_level = get_min_send_level_cached(level_str, logger_name);
std::string jsonString = oss.str();
// ① 高于台账阈值:直接上送
if (level >= min_send_level) {
allow_send = true;
} else {
// ② 低等级:默认不上送,除非命令打开
std::string ctrl_id;
if (level_str == "process") ctrl_id = "process";
else ctrl_id = extract_logger_id(logger_name);
Ckafka_data_t connect_info;
connect_info.strTopic = QString::fromStdString(G_LOG_TOPIC);
connect_info.strText = QString::fromStdString(jsonString);
kafka_data_list_mutex.lock();
kafka_data_list.append(connect_info);
kafka_data_list_mutex.unlock();
if (!ctrl_id.empty()) {
allow_send = allow_low_level_send(ctrl_id, level_str, safe_logtype, level);
}
}
if (!allow_send) return;
// ③ 限频:同一条日志
const std::string rkey = make_key(logger_name, level, code, msg);
if (!should_emit(rkey)) return;
std::ostringstream oss;
oss << "{\"processNo\":\"" << intToString(g_front_seg_index)
<< "\",\"nodeId\":\"" << FRONT_INST
<< "\",\"businessId\":\"" << extract_logger_id(logger_name)
<< "\",\"level\":\"" << level_str
<< "\",\"grade\":\"" << get_level_str(level)
<< "\",\"logtype\":\"" << safe_logtype
<< "\",\"frontType\":\"" << get_front_type_from_subdir()
<< "\",\"code\":" << code
<< ",\"log\":\"" << escape_json(msg) << "\"}";
Ckafka_data_t connect_info;
connect_info.strTopic = QString::fromStdString(G_LOG_TOPIC);
connect_info.strText = QString::fromStdString(oss.str());
kafka_data_list_mutex.lock();
kafka_data_list.append(connect_info);
kafka_data_list_mutex.unlock();
}
std::string escape_json(const std::string& input) {
@@ -198,25 +383,58 @@ public:
virtual ~SendAppender() {
destructorImpl(); // 重要!释放 log4cplus 基类资源
}
//////////////////////////////////////////////////////////////////20260303添加日志上送控制 - 频率限制实现
private:
struct RateState {
uint64_t hit_count;
std::chrono::steady_clock::time_point last_emit;
bool has_emit;
RateState() : hit_count(0), last_emit(), has_emit(false) {}
};
static std::unordered_map<std::string, RateState> s_rate_map;
static std::mutex s_rate_mutex;
static std::string make_key(const std::string& logger_name, int level, int code, const std::string& msg) {
std::ostringstream oss;
oss << logger_name << "|" << level << "|" << code << "|" << msg;
return oss.str();
}
static bool should_emit(const std::string& key) {
using namespace std::chrono;
const auto now = steady_clock::now();
std::lock_guard<std::mutex> lk(s_rate_mutex);
RateState& st = s_rate_map[key];
const int RESET_SEC = 3600;
if (st.has_emit) {
auto idle = duration_cast<seconds>(now - st.last_emit).count();
if (idle >= RESET_SEC) st.hit_count = 0;
}
st.hit_count++;
const int period_sec = (st.hit_count > 3) ? 300 : 1;
if (!st.has_emit) {
st.last_emit = now;
st.has_emit = true;
return true;
}
const auto elapsed = duration_cast<seconds>(now - st.last_emit).count();
if (elapsed >= period_sec) {
st.last_emit = now;
return true;
}
return false;
}
};
//用来控制日志上送的结构
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");
}
//////////////////////////////////////////////////////////////////20260303添加日志上送控制 - 频率限制实现
std::unordered_map<std::string, SendAppender::RateState> SendAppender::s_rate_map;
std::mutex SendAppender::s_rate_mutex;
// 外部线程中调用每秒更新所有倒计时0 则删除
void update_log_entries_countdown() {
@@ -236,25 +454,25 @@ void update_log_entries_countdown() {
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;
void process_log_command(const std::string& id,
const std::string& level,
const std::string& grade,
int code)
{
if (level != "terminal" && level != "measurepoint" && level != "process") 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);
std::string key = build_debug_key(id, level, code);
pthread_mutex_lock(&g_log_mutex);
LOGEntry& entry = g_log_entries[key]; // 会自动 insert 或取已有
LOGEntry& entry = g_log_entries[key];
entry.id = id;
entry.level = level;
entry.logtype = type;
entry.code = code;
entry.min_grade = grade_level;
entry.countdown = 60; // 重置倒计时
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) {
@@ -286,7 +504,7 @@ log4cplus::Logger init_logger(const std::string& full_name,
//进程的日志
void init_logger_process() {
std::string base_dir = std::string("/FeProject/") + subdir + "/processNo" + intToString(g_front_seg_index) + "/log";
logger_map["process"] = TypedLogger(init_logger(std::string("process"), base_dir, std::string("process")), LOGTYPE_DATA);
logger_map["process"] = TypedLogger(init_logger(std::string("process"), base_dir, std::string("process")), LOGTYPE_DEFAULT);
std::cout << "process log init ok" << std::endl;
}
@@ -321,12 +539,10 @@ void init_loggers_bydevid(const char* dev_id)
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";
std::string device_key = std::string("terminal.") + dev_id;
// 添加判断:终端日志 logger 是否已存在
if (logger_map.find(device_key_c) == logger_map.end() &&
logger_map.find(device_key_d) == logger_map.end()) {
if (logger_map.find(device_key) == logger_map.end()) {
// 所有终端日志com 和 data写到同一个 device 日志文件中
std::string file_path_t = device_dir + "/" + dev_id + ".log";
@@ -335,27 +551,23 @@ void init_loggers_bydevid(const char* dev_id)
SharedAppenderPtr device_appender = SharedAppenderPtr(new RollingFileAppender(file_path_t, 1 * 1024 * 1024, 2));
device_appender->setLayout(std::auto_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); //用终端id作为日志文件名
Logger device_logger_d = init_logger(device_key_d, device_dir, dev_id, device_appender); //用终端id作为日志文件名
logger_map[device_key_c] = TypedLogger(device_logger_c, LOGTYPE_COM);
logger_map[device_key_d] = TypedLogger(device_logger_d, LOGTYPE_DATA);
Logger device_logger = init_logger(device_key, device_dir, dev_id, device_appender); //用终端id作为日志文件名
logger_map[device_key] = TypedLogger(device_logger, LOGTYPE_DEFAULT);
DIY_INFOLOG(device_key_d.c_str(),"【NORMAL】终端id:%s终端级日志初始化完毕", ied_usr->terminal_id);
DIY_INFOLOG(device_key.c_str(),"【NORMAL】终端id:%s终端级日志初始化完毕", ied_usr->terminal_id);
}
// 初始化监测点
// 监测点 logger 名称格式monitor.<mp_id>.COM / .DATA
// 监测点 logger 名称格式monitor.<mp_id>
for (int i = 0; i < 10; ++i) {
if (strlen(ied_usr->LD_info[i].mp_id) > 0){
std::ostringstream mon_key_c, mon_key_d, mon_path, mon_name;
mon_key_c << "monitor." << ied_usr->LD_info[i].mp_id << ".COM";
mon_key_d << "monitor." << ied_usr->LD_info[i].mp_id << ".DATA";
std::ostringstream mon_key, mon_path, mon_name;
mon_key << "monitor." << ied_usr->LD_info[i].mp_id;
mon_path << device_dir << "/monitor" << i;//终端路径下用monitor+序号作为目录
mon_name << ied_usr->LD_info[i].mp_id;
// 添加判断:监测点 logger 是否已存在
if (logger_map.find(mon_key_c.str()) == logger_map.end() &&
logger_map.find(mon_key_d.str()) == logger_map.end()) {
if (logger_map.find(mon_key.str()) == logger_map.end()) {
// 所有监测点日志com 和 data写到同一个 monitor 日志文件中
std::string file_path_m = mon_path.str() + "/" + mon_name.str() + ".log";
@@ -364,12 +576,10 @@ void init_loggers_bydevid(const char* dev_id)
SharedAppenderPtr monitor_appender = SharedAppenderPtr(new RollingFileAppender(file_path_m, 1 * 1024 * 1024, 2));
monitor_appender->setLayout(std::auto_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);
Logger mon_logger = init_logger(mon_key.str(), mon_path.str(), mon_name.str(),monitor_appender);//用监测点号作为日志文件名
logger_map[mon_key.str()] = TypedLogger(mon_logger, LOGTYPE_DEFAULT);
DIY_INFOLOG(mon_key_d.str().c_str(),"【NORMAL】监测点:%s - id:%s监测点级日志初始化完毕", ied_usr->LD_info[i].name,ied_usr->LD_info[i].mp_id);
DIY_INFOLOG(mon_key.str().c_str(),"【NORMAL】监测点:%s - id:%s监测点级日志初始化完毕", ied_usr->LD_info[i].name,ied_usr->LD_info[i].mp_id);
}
}
@@ -377,6 +587,9 @@ void init_loggers_bydevid(const char* dev_id)
break; // 只匹配一个 terminal_id
}
//lnk20260303添加日志上送控制 - 初始化时构建日志等级缓存
refresh_log_level_cache_locked();
}
void init_loggers() {
@@ -402,8 +615,7 @@ void init_loggers() {
std::string device_dir = base_dir + "/" + ip_str;
std::string device_key_c = std::string("terminal.") + ied_usr->terminal_id + ".COM";
std::string device_key_d = std::string("terminal.") + ied_usr->terminal_id + ".DATA";
std::string device_key = std::string("terminal.") + ied_usr->terminal_id;
// 所有终端日志com 和 data写到同一个 device 日志文件中
std::string file_path_t = device_dir + "/" + ied_usr->terminal_id + ".log";
@@ -412,21 +624,18 @@ void init_loggers() {
SharedAppenderPtr device_appender = SharedAppenderPtr(new RollingFileAppender(file_path_t, 1 * 1024 * 1024, 2));
device_appender->setLayout(std::auto_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, ied_usr->terminal_id, device_appender); //用终端id作为日志文件名
Logger device_logger_d = init_logger(device_key_d, device_dir, ied_usr->terminal_id, device_appender); //用终端id作为日志文件名
Logger device_logger = init_logger(device_key, device_dir, ied_usr->terminal_id, device_appender); //用终端id作为日志文件名
logger_map[device_key_c] = TypedLogger(device_logger_c, LOGTYPE_COM);
logger_map[device_key_d] = TypedLogger(device_logger_d, LOGTYPE_DATA);
logger_map[device_key] = TypedLogger(device_logger, LOGTYPE_DEFAULT);
DIY_INFOLOG(device_key_d.c_str(),"【NORMAL】终端id:%s终端级日志初始化完毕", ied_usr->terminal_id);
DIY_INFOLOG(device_key.c_str(),"【NORMAL】终端id:%s终端级日志初始化完毕", ied_usr->terminal_id);
// 初始化监测点
// 监测点 logger 名称格式monitor.<mp_id>.COM / .DATA
// 监测点 logger 名称格式monitor.<mp_id>
for (int i = 0; i < 10; ++i) {
if (strlen(ied_usr->LD_info[i].mp_id) > 0){
std::ostringstream mon_key_c, mon_key_d, mon_path, mon_name;
mon_key_c << "monitor." << ied_usr->LD_info[i].mp_id << ".COM";
mon_key_d << "monitor." << ied_usr->LD_info[i].mp_id << ".DATA";
std::ostringstream mon_key, mon_path, mon_name;
mon_key << "monitor." << ied_usr->LD_info[i].mp_id;
mon_path << device_dir << "/monitor" << i;//终端路径下用monitor+序号作为目录
mon_name << ied_usr->LD_info[i].mp_id;
@@ -437,19 +646,19 @@ void init_loggers() {
SharedAppenderPtr monitor_appender = SharedAppenderPtr(new RollingFileAppender(file_path_m, 1 * 1024 * 1024, 2));
monitor_appender->setLayout(std::auto_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 mon_logger = init_logger(mon_key.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);
logger_map[mon_key.str()] = TypedLogger(mon_logger, LOGTYPE_DEFAULT);
DIY_INFOLOG(mon_key_d.str().c_str(),"【NORMAL】监测点:%s - id:%s监测点级日志初始化完毕", ied_usr->LD_info[i].name,ied_usr->LD_info[i].mp_id);
DIY_INFOLOG(mon_key.str().c_str(),"【NORMAL】监测点:%s - id:%s监测点级日志初始化完毕", ied_usr->LD_info[i].name,ied_usr->LD_info[i].mp_id);
}
}
}
//lnk20260303添加日志上送控制 - 初始化时构建日志等级缓存
refresh_log_level_cache_locked();
}
void remove_loggers_by_terminal_id(const char* terminal_id_cstr) {
@@ -465,37 +674,24 @@ void remove_loggers_by_terminal_id(const char* terminal_id_cstr) {
if (strcmp(ied_usr->terminal_id, terminal_id.c_str()) != 0) continue;
// 删除终端日志 logger
std::string com_key = "terminal." + terminal_id + ".COM";
std::string data_key = "terminal." + terminal_id + ".DATA";
std::string terminal_key = "terminal." + terminal_id;;
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);
if (logger_map.count(terminal_key)) {
logger_map[terminal_key].logger.removeAllAppenders();
logger_map.erase(terminal_key);
}
// 删除监测点日志 logger
for (int i = 0; i < 10; ++i) {
const char* mp_id = ied_usr->LD_info[i].mp_id;
if (strlen(mp_id) > 0) {
std::string mon_prefix = std::string("monitor.") + mp_id;
std::string mon_key = std::string("monitor.") + mp_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_key)) {
logger_map[mon_key].logger.removeAllAppenders();
logger_map.erase(mon_key);
}
if (logger_map.count(mon_data_key)) {
logger_map[mon_data_key].logger.removeAllAppenders();
logger_map.erase(mon_data_key);
}
}
}