一、zlog 簡介
zlog 是純 C 實現的高效能、執行緒安全、靈活配置的日誌庫。支援多輸出目的地 (檔案、標準輸出、syslog、網路)、分級過濾、動態重載配置、格式化宏。GitHub: HardySimpson/zlog。
二、安裝與編譯
# 從原始碼編譯
git clone https://github.com/HardySimpson/zlog.git
cd zlog
make && sudo make install
# 預設安裝至 /usr/local/lib, /usr/local/include
# 專案中鏈結
gcc -o myapp myapp.c -lzlog -lpthread
三、配置檔詳解 (zlog.conf)
# 全域格式定義
[formats]
simple = "%m%n"
standard = "%d(%V) [%p] %c %f:%L - %m%n"
detail = "%d{%Y-%m-%d %H:%M:%S.%q} [%V] [%p] %c %F:%L - %m%n"
# 規則:分類 + 等級 + 輸出動作
[rules]
# 格式: category.level > output;output...
*.* > stdout;file_all
myapp.DEBUG > file_debug
myapp.ERROR > file_error;stderr
network.WARN > syslog
# 輸出定義
[outputs]
stdout = stdout
stderr = stderr
file_all = file:/var/log/myapp/all.log
file_debug = file:/var/log/myapp/debug.log
file_error = file:/var/log/myapp/error.log
syslog = syslog:local0
# 檔案輪轉參數 (可選)
[file_all]
path = /var/log/myapp/all.log
max_size = 100M
max_count = 10
rotate = true
[file_debug]
path = /var/log/myapp/debug.log
max_size = 50M
max_count = 5
關鍵格式佔位符
| 符號 | 含義 |
%d | 時間 (可加 {format} 如 %d{%H:%M:%S}) |
%V | 日誌等級 (DEBUG/INFO/WARN/ERROR/FATAL) |
%p | 進程 ID |
%c | 分類名稱 |
%f | 檔案名 |
%F | 完整路徑檔案名 |
%L | 行號 |
%m | 使用者訊息 |
%n | 換行符 |
%t | 執行緒 ID |
四、核心 API 與宏
#include
// 初始化 (通常在 main 一開始)
int rc = zlog_init("zlog.conf");
if (rc) { fprintf(stderr, "zlog init failed\n"); return 1; }
// 取得分類記錄器
zlog_category_t *cat = zlog_get_category("myapp");
if (!cat) { fprintf(stderr, "get cat failed\n"); zlog_fini(); return 1; }
// 記錄宏 (自動捕獲 __FILE__, __LINE__, __func__)
#define ZLOG_DEBUG(cat, fmt, ...) zlog_debug(cat, fmt, ##__VA_ARGS__)
#define ZLOG_INFO(cat, fmt, ...) zlog_info(cat, fmt, ##__VA_ARGS__)
#define ZLOG_WARN(cat, fmt, ...) zlog_warn(cat, fmt, ##__VA_ARGS__)
#define ZLOG_ERROR(cat, fmt, ...) zlog_error(cat, fmt, ##__VA_ARGS__)
#define ZLOG_FATAL(cat, fmt, ...) zlog_fatal(cat, fmt, ##__VA_ARGS__)
// 使用範例
ZLOG_INFO(cat, "Server started on port %d", 8080);
ZLOG_DEBUG(cat, "Processing request id=%lu", req_id);
ZLOG_ERROR(cat, "DB connect failed: %s", strerror(errno));
// 動態修改等級 (熱更新)
zlog_set_level(cat, ZLOG_LEVEL_DEBUG);
// 關閉
zlog_fini();
五、完整範例程式
// main.c
#include
#include
int main() {
if (zlog_init("zlog.conf")) return 1;
zlog_category_t *cat = zlog_get_category("myapp");
if (!cat) { zlog_fini(); return 1; }
ZLOG_INFO(cat, "Application starting...");
for (int i = 0; i < 5; i++) {
ZLOG_DEBUG(cat, "Loop iteration %d", i);
usleep(100000);
}
ZLOG_WARN(cat, "This is a warning");
ZLOG_ERROR(cat, "Simulated error: %s", "disk full");
zlog_fini();
return 0;
}
六、進階特性
- 動態重載配置:發送
SIGHUP 給進程,zlog 自動重讀配置檔 (無需重啟)。
- 多執行緒安全:內部鎖保護,直接在多執行緒呼叫宏安全。
- 自定義輸出:實作
zlog_output_vtable 介面寫入 Kafka、HTTP、資料庫等。
- 效能模式:
zlog_profile 啟用效能統計;非同步模式 (需手動實作佇列+專用執行緒) 降低延遲。
- 原始介面:
zlog_log(cat, level, file, line, func, fmt, ...) 完全控制。
七、最佳實踐
- 配置檔與程式碼分離,部署時只改配置。
- 分類 (category) 依模組劃分:
network, db, auth, business。
- 生產環境預設
INFO,除錯時動態調 DEBUG。
- 錯誤日誌必須包含
errno/strerror 上下文。
- 檔案輪轉設定
max_size/max_count 防止磁碟寫滿。
- 避免在高頻熱路徑 (如封包處理迴路) 直接呼叫
ZLOG_DEBUG,改用條件編譯或取樣。
八、zlog vs 其他日誌庫
| 庫 | 語言 | 特點 |
| zlog | C | 純 C、配置檔驅動、執行緒安全、輕量 |
| log4c | C | log4j 移植、XML 配置、較重、更新緩慢 |
| spdlog | C++ | Header-only、極快、fmt 格式化、需 C++11 |
| glog | C++ | Google、旗標整合、需 C++ |
| syslog | C | 系統級、網路集中、格式固定、無分級過濾 |