首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

修改 Nginx 源碼自定義訪問日誌時間格式:從編譯到驗證全流程實戰

     編輯:關於C語言

公司需將 Nginx 訪問日誌存入數據庫進行分析,但默認時間格式 [17/Jun/2013:14:42:13 +0400] 無法直接存入 DATETIME 類型字段,只能作字符串存儲,導致按天查詢分析極不方便。經研究發現需修改源碼重新編譯。本文記錄基於 Nginx 1.4.1 版本的完整修改流程。

目標格式轉換

原格式目標格式
17/Jun/2013:14:42:13 +04002013-06-17 22:39:02 (標準 SQL DATETIME)

需修改的兩個核心文件

  1. src/core/ngx_times.c — 時間緩存生成邏輯
  2. src/http/modules/ngx_http_log_module.c — 日誌模塊時間字段定義

一、 修改 ngx_times.c (三處關鍵點)

1. 緩存數組大小定義 (第 49-50 行)

// 原代碼
static u_char cached_http_log_time[NGX_TIME_SLOTS][sizeof("28/Sep/1970:12:00:00 +0600")];

// 修改後
static u_char cached_http_log_time[NGX_TIME_SLOTS][sizeof("1970-09-28 12:00:00")];

2. 緩存長度初始化 (第 64 行)

// 原代碼
ngx_cached_http_log_time.len = sizeof("28/Sep/1970:12:00:00 +0600") - 1;

// 修改後
ngx_cached_http_log_time.len = sizeof("1970-09-28 12:00:00") - 1;

3. 時間格式化核心邏輯 (第 151-158 行,最關鍵)

// 原代碼
p2 = &cached_http_log_time[slot][0];
(void) ngx_sprintf(p2, "%02d/%s/%d:%02d:%02d:%02d %c%02d%02d",
    tm.ngx_tm_mday,
    months[tm.ngx_tm_mon - 1],
    tm.ngx_tm_year,
    tm.ngx_tm_hour,
    tm.ngx_tm_min,
    tm.ngx_tm_sec,
    tp->gmtoff < 0 ? '-' : '+',
    ngx_abs(tp->gmtoff / 60),
    ngx_abs(tp->gmtoff % 60));

// 修改後:標準 ISO 格式,去除時區偏移(或按需保留)
p2 = &cached_http_log_time[slot][0];
(void) ngx_sprintf(p2, "%4d-%02d-%02d %02d:%02d:%02d",
    tm.ngx_tm_year,
    tm.ngx_tm_mon,
    tm.ngx_tm_mday,
    tm.ngx_tm_hour,
    tm.ngx_tm_min,
    tm.ngx_tm_sec
    // 如需時區可保留後三參數
);

說明:此處實際是將 HTTP 日誌時間格式(原為 p2)改為與緩存時間(p1)一致的標準格式。若需保留時區,可在格式字符串後追加 %c%02d%02d 及對應參數。

二、 修改 ngx_http_log_module.c (一處)

日誌變量定義 (第 220 行左右)

// 原代碼
{ ngx_string("time_local"), sizeof("28/Sep/1970:12:00:00 +0600") - 1, ... }

// 修改後
{ ngx_string("time_local"), sizeof("1970-09-28 12:00:00") - 1, ... }

此處長度必須與 ngx_times.c 中緩存長度一致,否則日誌輸出會截斷或越界。

三、 重新編譯安裝與驗證

# 進入源碼目錄
./configure --prefix=/usr/local/nginx  # 按原安裝參數
make
make install

# 熱替換啟動
killall -9 nginx
/usr/local/nginx/sbin/nginx

四、 效果驗證

[root@localhost objs]# tail -n 0 -f /usr/local/nginx/logs/access.log
10.10.8.120 - - [2013-06-18 03:24:24] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 ..."
10.10.8.120 - - [2013-06-18 03:24:24] "GET /favicon.ico HTTP/1.1" 404 570 "-" "Mozilla/5.0 ..."

時間格式已完美變為 [YYYY-MM-DD HH:MM:SS],可直接導入數據庫 DATETIME 字段,支持高效按天/小時分組查詢。

五、 避坑提示

  1. 備份原始源碼:修改前務必備份,編譯失敗可快速回滾
  2. 保持編譯參數一致:./configure 參數需與原安裝完全一致,否則模塊缺失
  3. 時區處理:修改後默認使用本地時間(無時區偏移),如業務跨時區請評估是否保留時區信息
  4. 日誌分析工具兼容性:修改格式後,現有分析腳本(如 GoAccess、AWStats)可能需同步調整正則

本文參考網上資料整理,如有版權問題請聯系。更多技術博文請訪問:Linux開源技術博客 或 平凡的日子

本文出自 “平凡的日子” 博客,轉載請保留出處:原文鏈接

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved