use ledger log level

This commit is contained in:
lnk
2026-02-04 17:03:14 +08:00
parent 787d1f20be
commit 2b4c939b79
8 changed files with 105 additions and 10 deletions

View File

@@ -631,7 +631,8 @@ int terminal_ledger_web(std::map<std::string, terminal_dev>& terminal_dev_map,
//dev.station_name = safe_str(item, "stationName");
//dev.tmnl_factory = safe_str(item, "manufacturer");
//dev.tmnl_status = safe_str(item, "status");
dev.dev_type = safe_str(item, "devType");
dev.dev_type = safe_str(item, "devType");
dev.DevLogLevel = safe_str(item, "DevLogLevel");
//dev.dev_key = safe_str(item, "devKey");
//dev.dev_series = safe_str(item, "series");
//dev.port = safe_str(item, "port");
@@ -652,6 +653,7 @@ int terminal_ledger_web(std::map<std::string, terminal_dev>& terminal_dev_map,
m.logical_device_seq = safe_str(mon, "lineNo");
m.voltage_level = safe_str(mon, "voltageLevel");
m.terminal_connect = safe_str(mon, "ptType");
m.LineLogLevel = safe_str(mon, "LineLogLevel");
//m.timestamp = safe_str(mon, "updateTime");
m.status = safe_str(mon, "status");
@@ -802,6 +804,9 @@ int parse_device_cfg_web()
terminal_devlist.push_back(dev);
}
//记录所有logger等级
refresh_log_level_cache_locked();
// 判断监测点接线类型
for (auto& dev : terminal_devlist) {
for (auto& mon : dev.line) {
@@ -1292,7 +1297,7 @@ int transfer_json_qvvr_data(const std::string& dev_id, ushort monitor_id,
// =====【新增:业务失败也当异常处理】=====
if (j_r.contains("code")
&& j_r["code"].is_string()
&& j_r["code"].get<std::string>() != "0") {
&& j_r["code"].get<std::string>() != "A0000") {
DIY_ERRORLOG_CODE(mpid.c_str(),2,LOG_CODE_TRANSIENT_COMM,"暂态接口业务失败(code=%s),无法上送暂态事件",j_r["code"].get<std::string>().c_str());

View File

@@ -204,6 +204,7 @@ public:
std::string terminal_connect; //监测点接线方式
std::string timestamp; //更新时间
std::string status; //监测点状态
std::string LineLogLevel; //监测点日志级别
double PT1; // 电压变比1
double PT2; // 电压变比2
double CT1; // 电流变比1
@@ -217,6 +218,7 @@ class update_dev
public:
std::string guid; // ★新增:供发送回复使用
std::string DevLogLevel; //装置日志级别
std::string terminal_id;
std::string terminal_name;
std::string org_name;
@@ -250,6 +252,7 @@ public:
std::string logical_device_seq; //监测点序号
std::string voltage_level; //监测点电压等级
std::string terminal_connect; //监测点接线方式
std::string LineLogLevel; //监测点日志级别
std::string timestamp; //更新时间
std::string status; //监测点状态
double PT1; // 电压变比1
@@ -286,6 +289,8 @@ public:
std::vector<NameFixValue> dz_internal_info_list; //内部定值信息列表
std::vector<DZ_kzz_bit> control_words;
std::string DevLogLevel; //装置日志级别
std::string terminal_id;
std::string terminal_name;
std::string org_name;

View File

@@ -19,7 +19,7 @@
#include <fnmatch.h>
#include <unordered_map>
#include <chrono>
#include <memory>
//////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "log4cplus/logger.h"
#include "log4cplus/configurator.h"
@@ -58,9 +58,17 @@ static const char* ID_WILDCARD = "all"; // id 通配字段
std::map<std::string, TypedLogger> logger_map;
DebugSwitch g_debug_switch;
/////////////////////////////////////////////////
struct LogLevelCache { //日志等级缓存
// terminal_id -> min_level
std::unordered_map<std::string, int> term_min;
// monitor_id -> min_level
std::unordered_map<std::string, int> mp_min;
};
// 原子指针append 线程只读它,不加锁
static std::shared_ptr<LogLevelCache> g_level_cache_sp;
///////////////////////////////////////////////////////////////
//用来控制日志上送的结构
struct LOGEntry {
std::string id; //测点和装置需要的id
@@ -122,6 +130,16 @@ std::string get_level_str(int level) {
default: return "UNKNOWN";
}
}
static int str_to_loglevel(const std::string& s, int default_level = WARN_LOG_LEVEL)
{
if (s == "DEBUG") return DEBUG_LOG_LEVEL;
if (s == "NORMAL") return INFO_LOG_LEVEL; // NORMAL 当 INFO
if (s == "INFO") return INFO_LOG_LEVEL;
if (s == "WARN") return WARN_LOG_LEVEL;
if (s == "ERROR") return ERROR_LOG_LEVEL;
return default_level; // 空/非法都兜底
}
//////////////////////////////////////////////////////////////////////
TypedLogger::TypedLogger() {}
TypedLogger::TypedLogger(const Logger& l, int t) : logger(l), logtype(t) {}
@@ -149,9 +167,35 @@ bool DebugSwitch::match(const std::string& logger_name, int level, int logtype)
}
return false;
}
////////////////////////////////////////////////////////////////////////////////////
static LogLevelCache* build_cache_unlocked()
{
LogLevelCache* nc = new LogLevelCache;
nc->term_min.reserve(terminal_devlist.size());
for (const terminal_dev& t : terminal_devlist) {
const int t_lv = str_to_loglevel(t.DevLogLevel, WARN_LOG_LEVEL);
if (!t.terminal_id.empty())
nc->term_min[t.terminal_id] = t_lv;
for (const ledger_monitor& m : t.line) {
if (m.monitor_id.empty()) continue;
// 监测点优先;空/非法自动兜底到终端 t_lv
const int m_lv = str_to_loglevel(m.LineLogLevel, t_lv);
nc->mp_min[m.monitor_id] = m_lv;
}
}
return nc;
}
void refresh_log_level_cache_locked()
{
std::shared_ptr<LogLevelCache> nc(build_cache_unlocked());
std::atomic_store_explicit(&g_level_cache_sp, nc, std::memory_order_release);
}
//////////////////////////////////////////////////////////////////////////////////
/*class SendAppender : public Appender {
protected:
void append(const spi::InternalLoggingEvent& event) {
@@ -285,25 +329,25 @@ private:
int level_val) {//告警等级
pthread_mutex_lock(&g_log_mutex);
// 1) 精确匹配id + level + logtype
// 1) 精确匹配id + level + logtype //这个id指定日志种类指定级别的日志
if (find_entry_allow(build_debug_key(id, level_str, logtype), level_val)) {
pthread_mutex_unlock(&g_log_mutex);
return true;
}
// 2) logtype 通配id + level + -1
// 2) logtype 通配id + level + -1 //这个id指定日志级别的所有日志
if (find_entry_allow(build_debug_key(id, level_str, LOGTYPE_WILDCARD), level_val)) {
pthread_mutex_unlock(&g_log_mutex);
return true;
}
// 3) id 通配:* + level + logtype
// 3) id 通配:* + level + logtype //这个id的指定级别的日志
if (find_entry_allow(build_debug_key(ID_WILDCARD, level_str, logtype), level_val)) {
pthread_mutex_unlock(&g_log_mutex);
return true;
}
// 4) 双通配:* + level + -1
// 4) 双通配:* + level + -1 //所有指定级别的日志,即根据台账的等级来上送所有日志
if (find_entry_allow(build_debug_key(ID_WILDCARD, level_str, LOGTYPE_WILDCARD), level_val)) {
pthread_mutex_unlock(&g_log_mutex);
return true;
@@ -313,7 +357,30 @@ private:
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);
if (id.empty()) return DEFAULT_LEVEL;
std::shared_ptr<LogLevelCache> c =
std::atomic_load_explicit(&g_level_cache_sp, std::memory_order_acquire);
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;
}
protected:
void append(const spi::InternalLoggingEvent& event) override {
@@ -336,7 +403,15 @@ protected:
bool allow_send = false;
if (level >= WARN_LOG_LEVEL) {
int min_send_level = get_min_send_level_cached(level_str, logger_name);
std::cout << "[LOG] logger: " << logger_name
<< ", level_str: " << level_str
<< ", level: " << level
<< ", min_send_level: " << min_send_level << std::endl;
// ① 高于“台账阈值”的日志:直接上送
if (level >= min_send_level) {
allow_send = true;
} else {
// NORMAL/DEBUG 默认不上送,必须命令打开

View File

@@ -87,6 +87,8 @@ void process_log_command(const std::string& id, const std::string& level, const
void update_log_entries_countdown();
void refresh_log_level_cache_locked();
extern "C" {
#endif
void remove_loggers_by_terminal_id(const std::string& terminal_id_cstr);

View File

@@ -756,6 +756,7 @@ bool parseJsonMessageUD(const std::string& json_str, const std::string& output_d
//json_data.tmnl_factory = item.value("manufacturer", "");
//json_data.tmnl_status = item.value("status", "");
json_data.dev_type = item.value("devType", "");
json_data.DevLogLevel = item.value("DevLogLevel", "WARN");
//json_data.dev_key = item.value("devKey", "");
//json_data.dev_series = item.value("series", "");
@@ -783,6 +784,7 @@ bool parseJsonMessageUD(const std::string& json_str, const std::string& output_d
m.monitor_name = monitor_item.value("name", "");
m.logical_device_seq = monitor_item.value("lineNo", "");
m.voltage_level = monitor_item.value("voltageLevel", "");
m.LineLogLevel = monitor_item.value("LineLogLevel", "WARN");
// status 可能是数字,统一转成字符串存
if (monitor_item.contains("status") && monitor_item["status"].is_number_integer())
m.status = std::to_string(monitor_item["status"].get<int>());
@@ -871,6 +873,8 @@ bool parseJsonMessageUD(const std::string& json_str, const std::string& output_d
}
}
reply_list.push_back(std::move(one));
refresh_log_level_cache_locked();
}
else if(code_str == "ledger_modify"){
@@ -929,6 +933,8 @@ bool parseJsonMessageUD(const std::string& json_str, const std::string& output_d
}
reply_list.push_back(std::move(one));
refresh_log_level_cache_locked();
}
}
@@ -984,6 +990,8 @@ bool parseJsonMessageUD(const std::string& json_str, const std::string& output_d
}
}
reply_list.push_back(std::move(one));
refresh_log_level_cache_locked();
}
}
} else {