多線程下打斷點會阻塞當前線程,破壞原本的併發時序,導致難以復現競態條件。正解是非阻塞異步日誌記錄關鍵節點,事後離線分析。
// vcpkg install log4cplus
// CMakeLists.txt
find_package(log4cplus REQUIRED)
target_link_libraries(myapp PRIVATE log4cplus)
# log4cplus.properties
log4cplus.rootLogger=DEBUG, ASYNCFILE
log4cplus.appender.ASYNCFILE=log4cplus::AsyncAppender
log4cplus.appender.ASYNCFILE.Appender=ROLFILE
log4cplus.appender.ROLFILE=log4cplus::RollingFileAppender
log4cplus.appender.ROLFILE.File=logs/mt_debug.log
log4cplus.appender.ROLFILE.MaxFileSize=50MB
log4cplus.appender.ROLFILE.MaxBackupIndex=10
log4cplus.appender.ROLFILE.Layout=log4cplus::PatternLayout
log4cplus.appender.ROLFILE.Layout.ConversionPattern=%d{%Y-%m-%d %H:%M:%S.%q} [%t] %-5p %c{2} %x - %m%n
#include
#include
static log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("MT"));
void Worker::process(Task t) {
LOG4CPLUS_DEBUG(logger, "TID=" << std::this_thread::get_id() << " start task " << t.id);
// ... 業務邏輯
LOG4CPLUS_DEBUG(logger, "TID=" << std::this_thread::get_id() << " lock mutex");
std::lock_guard lk(mtx);
LOG4CPLUS_DEBUG(logger, "TID=" << std::this_thread::get_id() << " got mutex");
// ...
LOG4CPLUS_DEBUG(logger, "TID=" << std::this_thread::get_id() << " finish task " << t.id);
}
%t(線程 ID/名)、%q(毫秒級時間戳),可用 grep/awk 重構時序圖。log4cplus::NDC(嵌套診斷上下文)標記請求鏈路:log4cplus::NDCContextCreator _ctx("Req-" + reqId);