add recall reply

This commit is contained in:
lnk
2025-09-15 16:36:21 +08:00
parent a298ff847a
commit f27d208959
6 changed files with 271 additions and 152 deletions

View File

@@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////////////////////////////////
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
@@ -705,12 +705,54 @@ void Worker::handleViewLogCommand(const std::string& command, int clientFD) {
stopViewLog = false;
showinshellflag = true;
sendStr(clientFD, "\r\x1B[KViewing logs for level: " + level + " (Press '`' to exit)\r\n> ");
sendStr(clientFD, std::string("\r\x1B[KViewing logs for level: ") + level + " (Press '`' to exit)\r\n> ");
char inputBuf[16];
// --- 新增 begin: 目录创建 + 唯一文件名生成 + 打开文件 ---
// 递归创建目录的小工具(最小实现,按‘/’逐级创建)
auto ensure_dir = [](const std::string& path) -> bool {
if (path.empty()) return false;
std::string cur;
cur.reserve(path.size());
for (size_t i = 0; i < path.size(); ++i) {
cur.push_back(path[i]);
if (path[i] == '/' && cur.size() > 1) {
if (::access(cur.c_str(), F_OK) != 0) {
if (::mkdir(cur.c_str(), 0755) != 0 && errno != EEXIST) return false;
}
}
}
// 末级(若不以 / 结尾)
if (cur.back() != '/') {
if (::access(cur.c_str(), F_OK) != 0) {
if (::mkdir(cur.c_str(), 0755) != 0 && errno != EEXIST) return false;
}
}
return true;
};
const std::string logDir = "/FeProject/dat/log";
if (!ensure_dir(logDir)) {
sendStr(clientFD, "\r\x1B[KFailed to create log directory: /FeProject/dat/log\r\n> ");
return;
}
std::string filePath = logDir + "/temp.log";
int index = 1;
while (::access(filePath.c_str(), F_OK) == 0) {
filePath = logDir + "/temp_" + std::to_string(index++) + ".log";
}
std::ofstream logFile(filePath.c_str(), std::ios::out | std::ios::trunc);
if (!logFile.is_open()) {
sendStr(clientFD, "\r\x1B[KFailed to open log file for writing.\r\n> ");
return;
}
// --- 新增 end ---
while (!stopViewLog) {
// 1. 监听 shell 输入退出符号 `
// 1) 监听 shell 输入退出符号 `
fd_set read_fds;
FD_ZERO(&read_fds);
FD_SET(clientFD, &read_fds);
@@ -722,31 +764,47 @@ void Worker::handleViewLogCommand(const std::string& command, int clientFD) {
int activity = select(clientFD + 1, &read_fds, nullptr, nullptr, &timeout);
if (activity > 0 && FD_ISSET(clientFD, &read_fds)) {
int n = recv(clientFD, inputBuf, sizeof(inputBuf), 0);
if (n > 0 && strchr(inputBuf, '`')) {
if (n > 0 && std::memchr(inputBuf, '`', static_cast<size_t>(n))) {
stopViewLog = true;
showinshellflag = false;
break;
}
}
// 2. 输出日志
std::string logEntry;
// --- 修改 begin: 批量获取日志swap 全取,减少加锁时间) ---
std::list<std::string> tempLogs;
{
std::lock_guard<std::mutex> lock(*logMutex);
if (!logList->empty()) {
logEntry = logList->front();
logList->pop_front();
tempLogs.swap(*logList); // 把 logList 中的内容全取出
}
}
// --- 修改 end ---
if (!logEntry.empty()) {
sendStr(clientFD, "\r\x1B[K" + logEntry + "\r\n");
if (!tempLogs.empty()) {
for (const auto& logEntry : tempLogs) {
if (!logEntry.empty()) {
sendStr(clientFD, std::string("\r\x1B[K") + logEntry + "\r\n");
// --- 新增 begin: 写入文件 + 及时落盘 ---
logFile << logEntry << '\n';
// --- 新增 end ---
}
}
// --- 新增 begin: 刷新文件缓冲,保证实时可见 ---
logFile.flush();
// --- 新增 end ---
} else {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}
// 3. 打印退出提示
// 3) 打印退出提示
sendStr(clientFD, "\r\x1B[K\nLog view stopped. Returning to shell.\r\n> ");
// --- 新增 begin: 关闭文件 ---
logFile.close();
// --- 新增 end ---
}