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

@@ -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 默认不上送,必须命令打开