Fix(logger): preserve queued logs on shutdown; record exit signal

This commit is contained in:
yuanyuanxiang
2026-05-27 08:51:49 +02:00
parent 268a427172
commit 1fd431ba76
3 changed files with 37 additions and 4 deletions

View File

@@ -228,16 +228,19 @@ private:
}
// 后台线程处理日志
// 退出语义stop() 设 running=false 后,本线程必须把队列里**已入队**的日志
// 全部刷盘再退出。否则进程死亡前最后几条 Mprintf包括退出原因会丢失。
void processLogs()
{
threadRun = true;
while (running) {
while (true) {
std::unique_lock<std::mutex> lock(queueMutex);
cv.wait(lock, [this]() {
return !running || !logQueue.empty();
});
while (running && !logQueue.empty()) {
// drain不带 running 判断,确保 stop() 时残留条目也写完
while (!logQueue.empty()) {
std::string logEntry = logQueue.front();
logQueue.pop();
lock.unlock();
@@ -247,7 +250,9 @@ private:
lock.lock();
}
lock.unlock();
// 队列已空再决定要不要退出
if (!running) break;
}
threadRun = false;
}

View File

@@ -786,8 +786,12 @@ static void daemonize()
}
// 信号处理:收到 SIGTERM/SIGINT 时优雅退出
// 注意handler 内不能调 MprintfLogger 用 mutex/string/condvar非 async-signal-safe
// 只在这里记 sig_atomic_t 标志位main 退出循环后再补一行日志。
static volatile sig_atomic_t g_lastSignal = 0;
static void signalHandler(int sig)
{
g_lastSignal = sig;
g_bExit = S_CLIENT_EXIT;
}
@@ -1060,6 +1064,14 @@ int main(int argc, char* argv[])
}
}
// 退出原因留痕signal handler 不能直接打日志,在这里补一行。
if (g_lastSignal != 0) {
Mprintf(">>> Exit by signal %d (g_bExit=%d)\n",
(int)g_lastSignal, (int)g_bExit);
} else {
Mprintf(">>> Exit normally (g_bExit=%d)\n", (int)g_bExit);
}
Logger::getInstance().stop();
removePidFile();
return 0;

View File

@@ -604,9 +604,13 @@ static void fillLoginInfo(LOGIN_INFOR& info)
// ============== Signal Handling ==============
// 注意signal handler 内不能调 NSLog/MprintfNSLog 走 Foundation 锁,
// Mprintf 走 Logger mutex/condvar都不是 async-signal-safe。只在这里
// 记 sig_atomic_t 标志位main 退出循环后再补一行日志。
static volatile sig_atomic_t g_lastSignal = 0;
static void signalHandler(int sig)
{
NSLog(@"Received signal %d, shutting down...", sig);
g_lastSignal = sig;
g_running = false;
g_bExit = S_CLIENT_EXIT; // 通知所有工作线程退出
}
@@ -934,6 +938,14 @@ int main(int argc, const char* argv[])
}
}
// 退出原因留痕signal handler 不能直接打日志,在这里补一行。
if (g_lastSignal != 0) {
Mprintf(">>> Exit by signal %d (g_bExit=%d)\n",
(int)g_lastSignal, (int)g_bExit);
} else {
Mprintf(">>> Exit normally (g_bExit=%d)\n", (int)g_bExit);
}
NSLog(@"Shutting down...");
// Release power assertions
@@ -944,6 +956,10 @@ int main(int argc, const char* argv[])
// Display assertion is managed by ScreenHandler (released in stop())
// powerActivity is automatically released when exiting @autoreleasepool
(void)powerActivity; // Suppress unused variable warning
// 显式停止日志,确保上面 Mprintf 的退出原因落盘。
// 不依赖 ~Logger() 的静态析构次序,避免后续新增日志相关静态对象时踩坑。
Logger::getInstance().stop();
}
return 0;