日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Nginx源代码分析 - 日志处理

發布時間:2023/11/27 生活经验 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Nginx源代码分析 - 日志处理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

我看Nginx源代碼的時候,感覺整個系統都在傳遞log指針。log在nginx里是比較關鍵的。日志和內存分配是最基礎的兩個起點代碼,最好是在自己寫的程序框架中早點完善并實現。以免未來要用大量的精力調整。

1. 日志的源代碼位置

日志的源代碼在src/code/ngx_log.c及ngx_log.h里。

2. 日志的初始化

在main()函數一開始,對一些基礎數據進行初始化,其中之一就是日志,源代碼如下:

??? log = ngx_log_init();
??? if (log == NULL) {
??????? return 1;
??? }

3. 傳遞日志指針

在創建任何結構或執行任何函數,無論那種結構體都至少會包含一個向下傳遞的日志指針,例如以下代碼:

??? init_cycle.log = log;
??? ngx_cycle = &init_cycle;

??? init_cycle.pool = ngx_create_pool(1024, log);
??? if (init_cycle.pool == NULL) {
??????? return 1;
??? }

說明cycle結構體內含有日志指針、在創建內存池的時候最后一個參數也是日志指針。

我們在列舉一些結構,例如:

struct ngx_connection_s {
??? void?????????????? *data;
??? ngx_event_t??????? *read;
??? ngx_event_t??????? *write;

??? ngx_socket_t??????? fd;

??? ngx_recv_pt???????? recv;
??? ngx_send_pt???????? send;
??? ngx_recv_chain_pt?? recv_chain;
??? ngx_send_chain_pt?? send_chain;

??? ngx_listening_t??? *listening;

??? off_t?????????????? sent;

??? ngx_log_t????????? *log;

在connection結構里也傳遞了log指針。

4. 日志的分級

為了開發調試方便,日志被分成很多等級,我們可以只寫入我們關心等級的日志,Nginx的調試等級分成了兩個維度,如下:

#define NGX_LOG_STDERR??????????? 0
#define NGX_LOG_EMERG???????????? 1
#define NGX_LOG_ALERT???????????? 2
#define NGX_LOG_CRIT????????????? 3
#define NGX_LOG_ERR?????????????? 4
#define NGX_LOG_WARN????????????? 5
#define NGX_LOG_NOTICE??????????? 6
#define NGX_LOG_INFO????????????? 7
#define NGX_LOG_DEBUG???????????? 8

#define NGX_LOG_DEBUG_CORE??????? 0x010
#define NGX_LOG_DEBUG_ALLOC?????? 0x020
#define NGX_LOG_DEBUG_MUTEX?????? 0x040
#define NGX_LOG_DEBUG_EVENT?????? 0x080
#define NGX_LOG_DEBUG_HTTP??????? 0x100
#define NGX_LOG_DEBUG_MAIL??????? 0x200
#define NGX_LOG_DEBUG_MYSQL?????? 0x400

#define NGX_LOG_DEBUG_FIRST?????? NGX_LOG_DEBUG_CORE
#define NGX_LOG_DEBUG_LAST??????? NGX_LOG_DEBUG_MYSQL
#define NGX_LOG_DEBUG_CONNECTION 0x80000000
#define NGX_LOG_DEBUG_ALL???????? 0x7ffffff0


第一個維度是0-8,當我們在配置文件中如下設置:

#error_log logs/debug.log debug;
#error_log logs/error.log notice;
#error_log logs/error.log info;

常量如何與字符串對應起來的可以看,log.c文件中的一段定義:

static const char *err_levels[] = {
??? "stderr", "emerg", "alert", "crit", "error",
??? "warn", "notice", "info", "debug"
};

在nginx的判斷中只要是debug就一定會輸出小于8的所有信息,源代碼如下:

#define ngx_log_error(level, log, args...)??????????????????????????????????? \
??? if ((log)-> log_level >= level) ngx_log_error_core(level, log, args)

或者我們管這種維度叫做 error 維度。

另外一個維度是0x10以上,我們可以自由擴展,這個維度是按照疊加效果計算的,源代碼如下:
#define ngx_log_debug(level, log, args...)??????????????????????????????????? \
??? if ((log)-> log_level & level)???????????????????????????????????????????? \
??????? ngx_log_error_core(NGX_LOG_DEBUG, log, args)

ngx_set_error_log_levels() {

...

??????? for (n = 1; n <= NGX_LOG_DEBUG; n++) {
??????????? if (ngx_strcmp(value[i].data, err_levels[n]) == 0) {

??????????????? if (log->log_level != 0) {
??????????????????? ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
?????????????????????????????????????? "duplicate log level \"%s\"",
?????????????????????????????????????? value[i].data);
??????????????????? return NGX_CONF_ERROR;
??????????????? }

??????????????? log->log_level = n;
??????????????? continue;
??????????? }
??????? }

...

}

按照這個邏輯,nginx只認第一有效設置,不能使用這樣的配置

error_log logs/debug.log debug | info;

錯誤是 [emerg] 3596#0: duplicate log level "info" in /data/services/nginx/conf/nginx.conf:6

但可以寫

error_log logs/debug.log debug | langwan;

寫錯了沒事 :)


或者我們管這個維度叫做 debug 維度,相關源代碼如下:

#define NGX_LOG_DEBUG_FIRST?????? NGX_LOG_DEBUG_CORE
#define NGX_LOG_DEBUG_LAST??????? NGX_LOG_DEBUG_MYSQL

ngx_set_error_log_levels() {

...

??????? for (n = 0, d = NGX_LOG_DEBUG_FIRST; d <= NGX_LOG_DEBUG_LAST; d <<= 1) {
??????????? if (ngx_strcmp(value[i].data, debug_levels[n++]) == 0) {
??????????????? if (log->log_level & ~NGX_LOG_DEBUG_ALL) {
??????????????????? ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
?????????????????????????????????????? "invalid log level \"%s\"",
?????????????????????????????????????? value[i].data);
??????????????????? return NGX_CONF_ERROR;
??????????????? }

??????????????? log->log_level |= d;
??????????? }
??????? }

...

}

由于NGX_LOG_DEBUG_ALL的限制,限制了0-8這9個等級,不能出現在相同的配置里,例如下面的設置是錯誤的:

error_log logs/debug.log debug | debug_alloc;

錯誤是 [emerg] 3579#0: invalid log level "debug_alloc" in /data/services/nginx/conf/nginx.conf:6

只能寫成

error_log logs/debug.log debug_http | debug_alloc;

5. debug與debug_http之間的關系

實際上開啟了debug等級會輸出所有debug_開頭的調試信息,如果我們想過濾一下信息,只能詳細去按照 debug_http|debug_alloc 這樣去設置,否則光設置debug就全出來了,具體表示關系的代碼如下:

??? if (log->log_level == 0) {
??????? log->log_level = NGX_LOG_ERR;

??? } else if (log->log_level == NGX_LOG_DEBUG) {
??????? log->log_level = NGX_LOG_DEBUG_ALL;
??? }

?? 當錯誤等級包含NGX_LOG_DEBUG設置所有的調試等級給log_level。

6. 默認的錯誤等級

上面的代碼實際上也已經說明了,默認的錯誤等級是NGX_LOG_ERR

7. 錯誤日志有關的四個函數之間的調度關系

ngx_log_error() 按照優先級的大小判定是否輸出錯誤信息,例如:

error_log logs/debug.log error;

不會輸出 NGX_LOG_WARN、NGX_LOG_NOTICE、NGX_LOG_INFO、NGX_LOG_DEBUG 信息。

ngx_log_debug() 系列函數一共有10個,這里的0-8表示參數個數,不代表錯誤等級,用于輸出DEBUG_HTTP等調試信息。這9個函數均是ngx_log_debug()的一種宏定義,例如:

#define ngx_log_debug3(level, log, err, fmt, arg1, arg2, arg3)??????????????? \
??? if ((log)->log_level & level)???????????????????????????????????????????? \
??????? ngx_log_debug_core(log, err, fmt, arg1, arg2, arg3)

剩下還有ngx_log_debug_core()、與ngx_log_error_core()兩個函數

總結

以上是生活随笔為你收集整理的Nginx源代码分析 - 日志处理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。