diff --git a/cfg_parse/cfg_parser.cpp b/cfg_parse/cfg_parser.cpp index e9bf1f5..96d7332 100644 --- a/cfg_parse/cfg_parser.cpp +++ b/cfg_parse/cfg_parser.cpp @@ -11825,8 +11825,11 @@ void value_print(const char *variableName, QTcpSocket *clientSocket) { clientSocket->write(buffer); } else if (strcmp(variableName, "frontfun") == 0) { sprintf(buffer, "frontfun = %s", subdir); - clientSocket->write(buffer); - } else { + clientSocket->write(buffer); + } else if (strcmp(variableName, "log") == 0) { + sprintf(buffer, "showinshellflag = %d,debugOutputEnabled = %d,normalOutputEnabled = %d,warnOutputEnabled = %d,errorOutputEnabled = %d", showinshellflag,debugOutputEnabled,normalOutputEnabled,warnOutputEnabled,errorOutputEnabled); + clientSocket->write(buffer); + }else { clientSocket->write("Unknown variable name\n> "); } pthread_mutex_unlock(&mtx); std::cout << "value_print free lock !!!!!!!!!!!" << std::endl; @@ -11880,6 +11883,7 @@ void Worker::handleViewLogCommand(const QString& command, QTcpSocket* clientSock if (input == "q") { // ? 用户输入 `q`,退出日志模式 std::cout << "Received 'q' from shell socket! Exiting viewlog...\n"; stopViewLog = true; + showinshellflag = false; break; } } @@ -15178,8 +15182,8 @@ void rocketmq_test_300(int mpnum,int front_index) { ied_usr = (ied_usr_t*)ied->usr_ext; //跳过正常的终端 - if(strcmp(ied_usr->terminal_id, "5a7243ae5e0224e9ed18229d6697c3e2") == 0){ - std::cout << "5a7243ae5e0224e9ed18229d6697c3e2 use true message " << std::endl; + if(strcmp(ied_usr->terminal_id, "8499c5ae999d392b4e73112ca0d2d778") == 0){ + std::cout << "8499c5ae999d392b4e73112ca0d2d778 use true message " << std::endl; continue; } @@ -15261,6 +15265,8 @@ static std::streambuf* g_originalCoutBuf = NULL; static std::streambuf* g_originalClogBuf = NULL; static std::streambuf* g_originalCerrBuf = NULL; + + // ------------------ 日志级别枚举(C++98) ------------------ enum LogLevel { LOGERROR, @@ -15341,67 +15347,63 @@ private: switch (m_level) { case LOGERROR: - if (errorOutputEnabled) { + + if (debugOutputEnabled) { + pthread_mutex_lock(&debugListMutex); + debugList.push_back(m_buffer); + pthread_mutex_unlock(&debugListMutex); + } + else if (normalOutputEnabled) { + pthread_mutex_lock(&normalListMutex); + normalList.push_back(m_buffer); + pthread_mutex_unlock(&normalListMutex); + } + else if (warnOutputEnabled) { + pthread_mutex_lock(&warnListMutex); + warnList.push_back(m_buffer); + pthread_mutex_unlock(&warnListMutex); + } + else if (errorOutputEnabled) { pthread_mutex_lock(&errorListMutex); errorList.push_back(m_buffer); pthread_mutex_unlock(&errorListMutex); } - if (warnOutputEnabled) { - pthread_mutex_lock(&warnListMutex); - warnList.push_back(m_buffer); - pthread_mutex_unlock(&warnListMutex); - } - if (normalOutputEnabled) { - pthread_mutex_lock(&normalListMutex); - normalList.push_back(m_buffer); - pthread_mutex_unlock(&normalListMutex); - } - if (debugOutputEnabled) { - pthread_mutex_lock(&debugListMutex); - debugList.push_back(m_buffer); - pthread_mutex_unlock(&debugListMutex); - } + break; case LOGWARN: - if (warnOutputEnabled) { + + if (debugOutputEnabled) { + pthread_mutex_lock(&debugListMutex); + debugList.push_back(m_buffer); + pthread_mutex_unlock(&debugListMutex); + } + else if (normalOutputEnabled) { + pthread_mutex_lock(&normalListMutex); + normalList.push_back(m_buffer); + pthread_mutex_unlock(&normalListMutex); + } + else if (warnOutputEnabled) { pthread_mutex_lock(&warnListMutex); warnList.push_back(m_buffer); pthread_mutex_unlock(&warnListMutex); } - if (normalOutputEnabled) { - pthread_mutex_lock(&normalListMutex); - normalList.push_back(m_buffer); - pthread_mutex_unlock(&normalListMutex); - } - if (debugOutputEnabled) { - pthread_mutex_lock(&debugListMutex); - debugList.push_back(m_buffer); - pthread_mutex_unlock(&debugListMutex); - } + break; case LOGNORMAL: - if (normalOutputEnabled) { + if (debugOutputEnabled) { + pthread_mutex_lock(&debugListMutex); + debugList.push_back(m_buffer); + pthread_mutex_unlock(&debugListMutex); + } + else if (normalOutputEnabled) { pthread_mutex_lock(&normalListMutex); normalList.push_back(m_buffer); pthread_mutex_unlock(&normalListMutex); } - if (debugOutputEnabled) { - pthread_mutex_lock(&debugListMutex); - debugList.push_back(m_buffer); - pthread_mutex_unlock(&debugListMutex); - } - break; - case LOGDEBUG: - // 如果 debug 开关开了,才放进 debugList - if (debugOutputEnabled) { - pthread_mutex_lock(&debugListMutex); - debugList.push_back(m_buffer); - pthread_mutex_unlock(&debugListMutex); - } - break; + break; } m_buffer.clear(); @@ -15421,14 +15423,13 @@ private: static TeeStreamBuf g_errorTeeBuf; static TeeStreamBuf g_warnTeeBuf; static TeeStreamBuf g_normalTeeBuf; -static TeeStreamBuf g_debugTeeBuf; // 新增 debug Tee // ------------------ 我们另外提供一个全局的 debug 输出流 ------------------ // 其原始buf默认为 NULL(不输出到终端),只存到 debugList(若开关开) -static std::ostream g_debug(&g_debugTeeBuf); +//static std::ostream g_debug(&g_debugTeeBuf); // 让 qDebug() 映射到这个全局流 -#define qDebug() g_debug +//#define qDebug() g_debug // ------------------ 重定向函数 ------------------ // 只在第一次启用时,用 init(...) 初始化 TeeStreamBuf; @@ -15481,24 +15482,45 @@ void redirectNormalOutput(bool enabled) } } -// ------------------ 新增:debug 重定向函数 ------------------ -// 由于没有标准的“debug流”,我们这里只切换“是否把内容存入 debugList” -// 并让 g_debugTeeBuf 是否也要输出到某个原始缓冲(可选) -void redirectDebugOutput(bool enabled) +// ------------------ 重定向函数 ------------------ +void redirectDebugOutput(bool enable) { - debugOutputEnabled = enabled; - if (enabled) { - // 如果希望 debug 同时也显示到终端,可以指定原始缓冲区 - // 比如用 std::clog.rdbuf() 作为基底: - g_debugTeeBuf.init(std::clog.rdbuf(), LOGDEBUG); - // 这里我们选择 NULL → 不在终端输出, 只保存在 debugList. - //g_debugTeeBuf.init(NULL, LOGDEBUG); - } else { - // 关闭debug→ 不再写 debugList(虽然还会写 buffer, 但 push_back时不开关) - // 不需要“恢复原始”——因为没有给std::ostream还原。 - g_debugTeeBuf.init(NULL, LOGDEBUG); - // 仅保留init, 让 debugOutputEnabled=false 即可。 + debugOutputEnabled = enable; + // 不去改 clog.rdbuf() + // 不去 install 任何 msg handler +} + +// ------------------ Qt4 消息处理函数 ------------------ +void myQtMsgHandler(QtMsgType type, const char *msg) +{ + // 不论消息类型如何,都写入 debugList + if (debugOutputEnabled) { + pthread_mutex_lock(&debugListMutex); + debugList.push_back(msg); // 将 const char* 转换为 std::string 自动完成 + pthread_mutex_unlock(&debugListMutex); } + + // 同时将消息输出到 stderr(可选) + const char* typeStr = ""; + switch (type) { + case QtDebugMsg: + typeStr = "Debug"; + break; + case QtWarningMsg: + typeStr = "Warning"; + break; + case QtCriticalMsg: + typeStr = "Critical"; + break; + case QtFatalMsg: + typeStr = "Fatal"; + break; + } + fprintf(stderr, "[%s] %s\n", typeStr, msg); + fflush(stderr); + + if (type == QtFatalMsg) + abort(); } // ------------------ 自定义 printf 输出 ------------------ @@ -15530,7 +15552,9 @@ void real_echo_msg(const char *format, ...) { va_start(args, format); vsnprintf(buffer, sizeof(buffer), format, args); va_end(args); - printf("%s", buffer); // 正常打印日志 + + printf("%s", buffer); + fflush(stdout); // ? 确保标准输出立即刷新 } /////////////////////////////////////////////////////////////////////////////// diff --git a/cfg_parse/custom_printf.h b/cfg_parse/custom_printf.h index 772b303..8299e33 100644 --- a/cfg_parse/custom_printf.h +++ b/cfg_parse/custom_printf.h @@ -4,7 +4,7 @@ #include #include - +#include // 鉁 纭繚 QtMsgType 琚纭寘鍚 #ifdef __cplusplus #include @@ -24,7 +24,12 @@ extern bool debugOutputEnabled; void redirectErrorOutput(bool enabled); void redirectWarnOutput(bool enabled); void redirectNormalOutput(bool enabled); -void redirectDebugOutput(bool enabled); +// ------------------ 閲嶅畾鍚戝嚱鏁 ------------------ +void redirectDebugOutput(bool enable); + +// ------------------ Qt 鐨勬秷鎭鐞嗗嚱鏁 (Qt4) ------------------ +// Qt4 浣跨敤 qInstallMsgHandler(...)锛岀鍚: void myMsgHandler(QtMsgType, const char*) +void myQtMsgHandler(QtMsgType type, const char* msg); extern pthread_mutex_t errorListMutex; extern pthread_mutex_t warnListMutex; @@ -37,11 +42,19 @@ void real_echo_msg(const char *format, ...); // **鎷︽埅鎵鏈 `echo_msgX()`锛岃瀹冨悓鏃跺瓨鍏 `normalList`** #define echo_msgX(format, ...) \ do { \ - real_echo_msg(format, ##__VA_ARGS__); /* 璋冪敤鍘熷 `echo_msgX()` */ \ char buffer[1024]; \ snprintf(buffer, sizeof(buffer), format, ##__VA_ARGS__); \ + \ + /* 鉁 鍏堟墦鍗板埌 Shell锛岀‘淇濅笉浼氬崱姝 */ \ + printf("%s", buffer); \ + fflush(stdout); /* 鉁 绔嬪嵆鍒锋柊锛岄槻姝㈡爣鍑嗚緭鍑虹紦瀛 */ \ + \ + /* 鉁 鍏堝垱寤烘棩蹇楀壇鏈紝閬垮厤閿佷綇 `normalList` 杩囦箙 */ \ + std::string logEntry(buffer); \ + \ + /* 鉁 浠呭湪 `normalList` 鎿嶄綔鏃跺姞閿侊紝閬垮厤姝婚攣 */ \ pthread_mutex_lock(&normalListMutex); \ - normalList.push_back(buffer); \ + normalList.push_back(logEntry); \ pthread_mutex_unlock(&normalListMutex); \ } while (0) diff --git a/json/save2json.cpp b/json/save2json.cpp index d3bcee2..94026b5 100644 --- a/json/save2json.cpp +++ b/json/save2json.cpp @@ -615,7 +615,7 @@ void KafkaSendThread::run() debugList.pop_front(); // 只有非空白字符串才会真正返回 } } - pthread_mutex_unlock(&errorListMutex); + pthread_mutex_unlock(&debugListMutex); } else if (normalOutputEnabled) { // 如果 normalOutputEnabled 为 1,优先从 normalList 获取输出 @@ -1538,42 +1538,32 @@ void parse_log(const std::string& json_str) { else if (level == "WARN"){ // 启用告警输出 redirectWarnOutput(true); + redirectErrorOutput(true); } else if (level == "NORMAL"){ // 启用普通输出 redirectNormalOutput(true); + redirectErrorOutput(true); + redirectWarnOutput(true); } else if (level == "DEBUG"){ // 开启 debug (只存到 debugList,不显示在终端) redirectDebugOutput(true); + redirectErrorOutput(true); + redirectWarnOutput(true); + redirectNormalOutput(true); } else{ std::cout << "level error" <write("\nLog view stopped. Returning to shell.\n> "); clientSocket->flush(); } @@ -334,7 +336,7 @@ private: helpText += "log - Execute rocketmq_test_log\n"; helpText += "ledger - Execute ledger with optional terminal_id\n"; helpText += "viewlog - View logs (ERROR, WARN, NORMAL, DEBUG)\n"; - helpText += "value - Execute value print with valuename : iedcount frontfun frontindex remtable\n"; + helpText += "value - Execute value print with valuename : iedcount frontfun frontindex remtable log\n"; helpText += "exit - Exit the shell\n"; helpText += "help - Show this help message\n"; clientSocket->write(helpText.toUtf8());