add log level control by ledger
This commit is contained in:
@@ -11,6 +11,8 @@
|
||||
#include <algorithm>
|
||||
#include <interface.h>
|
||||
|
||||
#include "cloudfront/code/log4.h"
|
||||
|
||||
// 配置参数
|
||||
constexpr int BASE_RECONNECT_DELAY = 20000; // 基础重连延迟(ms)
|
||||
constexpr int MAX_RECONNECT_DELAY = 60000; // 最大重连延迟(ms)
|
||||
|
||||
@@ -601,7 +601,7 @@ int terminal_ledger_web(std::map<std::string, terminal_dev>& terminal_dev_map,
|
||||
|
||||
// 2. 安全读取 code/msg
|
||||
std::string code = json_data.value("code", "not found");
|
||||
std::string msg = json_data.value("msg", "not found");
|
||||
std::string msg = json_data.value("message", "not found");
|
||||
std::cout << "code: " << code << "\n";
|
||||
std::cout << "msg : " << msg << "\n";
|
||||
|
||||
@@ -632,12 +632,12 @@ int terminal_ledger_web(std::map<std::string, terminal_dev>& terminal_dev_map,
|
||||
//dev.tmnl_factory = safe_str(item, "manufacturer");
|
||||
//dev.tmnl_status = safe_str(item, "status");
|
||||
dev.dev_type = safe_str(item, "devType");
|
||||
dev.DevLogLevel = safe_str(item, "DevLogLevel");
|
||||
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");
|
||||
//dev.timestamp = safe_str(item, "updateTime");
|
||||
dev.Righttime = safe_str(item, "Righttime");
|
||||
dev.Righttime = safe_str(item, "rightTime");
|
||||
dev.processNo = safe_str(item, "node");
|
||||
dev.maxProcessNum = safe_str(item, "maxProcessNum");
|
||||
|
||||
@@ -653,7 +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.LineLogLevel = safe_str(mon, "lineLogLevel");
|
||||
//m.timestamp = safe_str(mon, "updateTime");
|
||||
m.status = safe_str(mon, "status");
|
||||
|
||||
|
||||
@@ -59,15 +59,10 @@ 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;
|
||||
std::shared_ptr<LogLevelCache> g_level_cache_sp;
|
||||
///////////////////////////////////////////////////////////////
|
||||
//用来控制日志上送的结构
|
||||
struct LOGEntry {
|
||||
@@ -131,6 +126,16 @@ std::string get_level_str(int level) {
|
||||
}
|
||||
}
|
||||
|
||||
const char* loglevel_to_str(int lv) {
|
||||
switch (lv) {
|
||||
case DEBUG_LOG_LEVEL: return "DEBUG";
|
||||
case INFO_LOG_LEVEL: return "NORMAL";
|
||||
case WARN_LOG_LEVEL: return "WARN";
|
||||
case ERROR_LOG_LEVEL: return "ERROR";
|
||||
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;
|
||||
@@ -196,74 +201,7 @@ void refresh_log_level_cache_locked()
|
||||
std::atomic_store_explicit(&g_level_cache_sp, nc, std::memory_order_release);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
/*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();
|
||||
|
||||
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";
|
||||
|
||||
// ★读取 TLS 中的 code(在打日志的线程里由宏设定)
|
||||
int code = g_log_code_tls; // 若未显式传入,则为 0
|
||||
|
||||
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
|
||||
<< "\",\"time\":\"" << now_yyyy_mm_dd_hh_mm_ss()
|
||||
<< "\",\"grade\":\"" << get_level_str(level)
|
||||
// ★新增:输出 code 字段(整型)
|
||||
<< "\",\"code\":\"" << code
|
||||
<< "\",\"log\":\"" << escape_json(msg) << "\"}";
|
||||
|
||||
std::string jsonString = oss.str();
|
||||
|
||||
queue_data_t connect_info;
|
||||
connect_info.strTopic = G_LOG_TOPIC;
|
||||
connect_info.strText = jsonString;
|
||||
connect_info.tag = G_LOG_TAG;
|
||||
connect_info.key = G_LOG_KEY;
|
||||
|
||||
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 基类资源
|
||||
}
|
||||
};*/
|
||||
class SendAppender : public Appender {
|
||||
private:
|
||||
struct RateState {
|
||||
@@ -601,7 +539,7 @@ void init_loggers_bydevid(const std::string& dev_id)
|
||||
// 添加判断:终端日志 logger 是否已存在
|
||||
if (logger_map.find(device_key) == logger_map.end()) {
|
||||
|
||||
// 所有终端日志(com 和 data)写到同一个 device 日志文件中
|
||||
// 所有终端日志写到同一个 device 日志文件中
|
||||
std::string file_path_t = device_dir + "/" + dev_id + ".log";
|
||||
|
||||
// 共用一个 appender 实例
|
||||
@@ -749,7 +687,11 @@ extern "C" {
|
||||
// 公共函数
|
||||
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;
|
||||
if (it == logger_map.end()) {
|
||||
std::cout << "[LOG][MISS] logger not found, key="
|
||||
<< (key ? key : "NULL") << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
Logger logger = it->second.logger;
|
||||
switch (level) {
|
||||
|
||||
@@ -39,6 +39,15 @@ extern LOG_TLS_SPEC int g_log_code_tls;
|
||||
# define PRINTF_LIKE(fmt_index, first_arg)
|
||||
#endif
|
||||
/////////////////////////////////////////
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
////////////////////////////////////
|
||||
struct TypedLogger {
|
||||
log4cplus::Logger logger;
|
||||
int logtype;
|
||||
@@ -67,9 +76,8 @@ extern DebugSwitch g_debug_switch;
|
||||
|
||||
extern void send_reply_to_queue(const std::string& guid, const int code, const std::string& result);
|
||||
|
||||
|
||||
//std::string get_front_type_from_subdir();
|
||||
|
||||
extern std::shared_ptr<LogLevelCache> g_level_cache_sp;
|
||||
const char* loglevel_to_str(int lv);
|
||||
|
||||
// 不带 Appender 的版本
|
||||
log4cplus::Logger init_logger(const std::string& full_name,
|
||||
|
||||
@@ -756,7 +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.DevLogLevel = item.value("devLogLevel", "WARN");
|
||||
//json_data.dev_key = item.value("devKey", "");
|
||||
//json_data.dev_series = item.value("series", "");
|
||||
|
||||
@@ -773,7 +773,7 @@ bool parseJsonMessageUD(const std::string& json_str, const std::string& output_d
|
||||
json_data.mac = item.value("ip", "");
|
||||
//json_data.port = item.value("port", "");
|
||||
//json_data.timestamp = item.value("updateTime", "");
|
||||
json_data.Righttime = item.value("Righttime", "");
|
||||
json_data.Righttime = item.value("rightTime", "");
|
||||
|
||||
if (item.contains("monitorData") && item["monitorData"].is_array()) {
|
||||
for (const auto& monitor_item : item["monitorData"]) {
|
||||
@@ -784,7 +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");
|
||||
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>());
|
||||
|
||||
@@ -301,7 +301,8 @@ extern bool normalOutputEnabled;
|
||||
"G_TEST_TYPE=<num> - Set the G_TEST_TYPE 0:use ledger,1:use number\r\n"
|
||||
"TESTLEDGER <processNo>,<start>,<count> - Batch send UD ledger updates (e.g. TESTLEDGER 3,1,50)\r\n"
|
||||
"LOG=<bool> - Set the LOG\r\n"
|
||||
"MAX=<int> - Set the MAX_ITEMS\r\n"
|
||||
"LOGLIST - List all registered loggers\r\n"
|
||||
"MAX=<int> - Set the MAX_ITEMS\r\n"
|
||||
"dir - Execute rocketmq_test_getdir\r\n"
|
||||
"rc - Execute rocketmq_test_rc\r\n"
|
||||
"rt - Execute rocketmq_test_rt\r\n"
|
||||
@@ -368,6 +369,40 @@ extern bool normalOutputEnabled;
|
||||
int flag = std::atoi(cmd.substr(4).c_str());
|
||||
setTestlog(flag);
|
||||
sendStr(clientFD, "\r\x1B[KLOG updated\r\n");
|
||||
}else if (cmd == "LOGLIST" || cmd == "loglist") {
|
||||
std::ostringstream oss;
|
||||
|
||||
// 1️⃣ 打印 logger_map
|
||||
oss << "\r\x1B[KRegistered loggers (" << logger_map.size() << "):\r\n";
|
||||
for (const auto& it : logger_map) {
|
||||
oss << " " << it.first << "\r\n";
|
||||
}
|
||||
|
||||
// 2️⃣ 打印 LogLevelCache(原子只读)
|
||||
std::shared_ptr<LogLevelCache> cache =
|
||||
std::atomic_load_explicit(&g_level_cache_sp, std::memory_order_acquire);
|
||||
|
||||
if (!cache) {
|
||||
oss << "\r\x1B[K[LogLevelCache] <EMPTY>\r\n";
|
||||
} else {
|
||||
oss << "\r\x1B[K[LogLevelCache] terminal levels ("
|
||||
<< cache->term_min.size() << "):\r\n";
|
||||
|
||||
for (const auto& kv : cache->term_min) {
|
||||
oss << " terminal." << kv.first
|
||||
<< " -> " << loglevel_to_str(kv.second) << "\r\n";
|
||||
}
|
||||
|
||||
oss << "\r\x1B[K[LogLevelCache] monitor levels ("
|
||||
<< cache->mp_min.size() << "):\r\n";
|
||||
|
||||
for (const auto& kv : cache->mp_min) {
|
||||
oss << " monitor." << kv.first
|
||||
<< " -> " << loglevel_to_str(kv.second) << "\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
sendStr(clientFD, oss.str());
|
||||
}else if (cmd.find("MAX=") == 0) {
|
||||
int flag = std::atoi(cmd.substr(4).c_str());
|
||||
setMaxItems(flag);
|
||||
@@ -488,6 +523,7 @@ void Worker::printLedgerinshell(const terminal_dev& dev, int fd) {
|
||||
os << "\r\x1B[K|-- timestamp : " << dev.timestamp << "\n";
|
||||
os << "\r\x1B[K|-- Righttime : " << dev.Righttime << "\n";
|
||||
os << "\r\x1B[K|-- mac : " << dev.mac << "\n";
|
||||
os << "\r\x1B[K|-- loglevel : " << dev.DevLogLevel << "\n";
|
||||
|
||||
// ========================= 终端级 · 内部定值 =========================
|
||||
// internal_values(ushort 列表)与 dz_internal_info_list 一一对应,仅展示前 MAX_ITEMS 条
|
||||
@@ -553,6 +589,7 @@ void Worker::printLedgerinshell(const terminal_dev& dev, int fd) {
|
||||
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 |-- loglevel : " << ld.LineLogLevel << "\n";
|
||||
os << "\r\x1B[K |-- CT1=" << ld.CT1 << ", CT2=" << ld.CT2
|
||||
<< ", PT1=" << ld.PT1 << ", PT2=" << ld.PT2 << "\n";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user