91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

nginx日志模塊的源碼分析

發布時間:2021-09-17 15:07:56 來源:億速云 閱讀:175 作者:chen 欄目:網絡管理

本篇內容主要講解“nginx日志模塊的源碼分析”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“nginx日志模塊的源碼分析”吧!

ngx_http_log_module簡介

ngx_http_log_module模塊按指定的格式寫訪問日志。

請求在處理結束時,會按請求路徑的配置上下文記訪問日志。 如果在請求處理期間產生了內部跳轉(參考另一篇nginx跳轉講述), 請求結束時的路徑可能不同于原始的請求路徑。

官方模塊使用說明http://nginx.org/en/docs/http/ngx_http_log_module.html

配置實例說明

在nginx.conf中相關的配置指令為:

log_format                  proxyformat "$time_iso8601 $remote_addr:$remote_port $server_addr:$server_port $upstream_addr $request_time $upstream_response_time $status $upstream_status $request_leng

th $body_bytes_sent \"$request_method $scheme://$http_host$request_uri $server_protocol\" \"$http_referer\" \"$http_user_agent\"";

access_log                  syslog:facility=local3,severity=info,server=127.0.0.1:514,tag=tengine proxyformat;

log_format gzip '$remote_addr - $remote_user [$time_local] '
                '"$request" $status $bytes_sent '
                '"$http_referer" "$http_user_agent" "$gzip_ratio"';

access_log /spool/logs/nginx-access.log gzip buffer=32k;
語法格式:access_logpath [format [buffer=size]];
access_logoff;
默認:
access_log logs/access.log combined;
配置生效空間上下文:httpserverlocationif in locationlimit_except

為訪問日志設置路徑,格式和緩沖區大小(nginx訪問日志支持緩存)。

在同一個配置層級里可以指定多個日志。

特定值off會取消當前配置層級里的所有access_log指令。

如果沒有指定日志格式則會使用預定義的combined格式。

緩沖區的大小不能超過磁盤文件原子性寫入的大小。

對于FreeBSD來說緩沖區大小是無限制的。

日志文件的路徑可以包含變量(0.7.6+), 但此類日志存在一些限制:

應該擁有在目錄里創建文件的權限。

寫緩沖無效。

每條日志寫入都會打開和關閉文件。頻繁使用的文件描述符可以存儲在緩存中, 在open_log_file_cache指令的valid參數指定的時間里,寫操作能持續寫到舊文件。

每次日志寫入的操作都會檢查請求的根目錄是否存在(即ngx root配置), 如果不存在則日志不會被創建。 在一個層級里同時指定root和access_log是個不錯的辦法:

server {
    root       /spool/vhost/data/$host;
    access_log /spool/vhost/logs/$host;
    ...
}
語法:log_formatname string ...;
默認:
log_format combined "...";
配置生效空間上下文:http

指定日志的格式。

日志格式允許包含普通變量和只在日志寫入時存在的變量:


  • $body_bytes_sent

  • 發送給客戶端的字節數,不包括響應頭的大小; 該變量與Apache模塊mod_log_config里的“%B”參數兼容。


  • $bytes_sent

  • 發送給客戶端的總字節數。


  • $connection

  • 連接的序列號。


  • $connection_requests

  • 當前通過一個連接獲得的請求數量。


  • $msec

  • 日志寫入時間。單位為秒,精度是毫秒。


  • $pipe


  • 如果請求是通過HTTP流水線(pipelined)發送,pipe值為“p”,否則為“.”。

$request_length

請求的長度(包括請求行,請求頭和請求正文)。

$request_time

請求處理時間,單位為秒,精度毫秒; 從讀入客戶端的第一個字節開始,直到把最后一個字符發送給          客戶端后進行日志寫入為止。

$status

響應狀態。

$time_iso8601

ISO8601標準格式下的本地時間。

$time_local

通用日志格式下的本地時間。



發送給客戶端的響應頭擁有"sent_http_"前綴,比如$sent_http_content_range。

配置始終包含預先定義的"combined"日志格式:

log_format combined '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';
語法:open_log_file_cachemax=N [inactive=time] [min_uses=N] [valid=time];
open_log_file_cacheoff;
默認:
open_log_file_cache off;
配置生效空間上下文:httpserverlocation

定義一個緩存,用來存儲頻繁使用的文件名中包含變量的日志文件描述符。 該指令包含以下參數:

max
設置緩存中描述符的最大數量;如果緩存被占滿,最近最少使用(LRU)的描述符將被關閉。
inactive
設置緩存文件描述符在多長時間內沒有被訪問就關閉; 默認為10秒。
min_uses
設置在inactive參數指定的時間里, 最少訪問多少次才能使文件描述符保留在緩存中;默認為1。
valid
設置一段用于檢查超時后文件是否仍以同樣名字存在的時間; 默認為60秒。
off
禁用緩存。

使用實例:

open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2;

nginx log_module源碼分析

先關注log模塊的初始化

static ngx_http_module_t  ngx_http_log_module_ctx = {

NULL,                                  /* preconfiguration */

ngx_http_log_init,               /* postconfiguration */

ngx_http_log_create_main_conf,    /* create main configuration */

NULL,                                  /* init main configuration */

NULL,                                  /* create server configuration */

NULL,                                  /* merge server configuration */

ngx_http_log_create_loc_conf,       /* create location configuration */

ngx_http_log_merge_loc_conf       /* merge location configuration */

};

static void *

ngx_http_log_create_main_conf(ngx_conf_t *cf)

{

ngx_http_log_main_conf_t  *conf;

ngx_http_log_fmt_t  *fmt;

conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_main_conf_t));

if (conf == NULL) {

return NULL;

}

// 初始化format

if (ngx_array_init(&conf->formats, cf->pool, 4, sizeof(ngx_http_log_fmt_t)) != NGX_OK)

{

return NULL;

}

return conf;

}

static ngx_int_t ngx_http_log_init(ngx_conf_t *cf)

{

// 這塊有判斷是否使用默認的combine的邏輯,在tengine中,自定義了一波,所以不care

// 將handler加入log階段

cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);

h = ngx_array_push(&cmcf->phases[NGX_HTTP_LOG_PHASE].handlers);

if (h == NULL) {

return NGX_ERROR;

}

*h = ngx_http_log_handler;

return NGX_OK;

}

而在log_format指令的處理函數中,將這個fmt給保存下來

static char * ngx_http_log_set_format(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

{

// 獲取loc_main_conf

ngx_http_log_main_conf_t *lmcf = conf;

// 初始化fmt

fmt = lmcf->formats.elts;

fmt = ngx_array_push(&lmcf->formats);

if (fmt == NULL) {

return NGX_CONF_ERROR;

}

// 賦值name

fmt->name = value[1];

// 初始化flushes和ops

fmt->flushes = ngx_array_create(cf->pool, 4, sizeof(ngx_int_t));

if (fmt->flushes == NULL) {

return NGX_CONF_ERROR;

}

fmt->ops = ngx_array_create(cf->pool, 16, sizeof(ngx_http_log_op_t));

if (fmt->ops == NULL) {

return NGX_CONF_ERROR;

}

// 最后把整個日志格式編譯

return ngx_http_log_compile_format(cf, fmt->flushes, fmt->ops, cf->args, 2);

}

static char * ngx_http_log_compile_format(ngx_conf_t *cf, ngx_array_t *flushes,ngx_array_t *ops, ngx_array_t *args, ngx_uint_t s)

{

// 遍歷所有的args

for ( /* void */ ; s < args->nelts; s++) {

// 在已有的ngx_http_log_vars中看有沒有指定的日志格式

for (v = ngx_http_log_vars; v->name.len; v++) {

if (v->name.len == var.len && ngx_strncmp(v->name.data, var.data, var.len) == 0)

{

// 將對應的方法,長度賦值給對應op,等待寫入

op->len = v->len;

op->getlen = NULL;

op->run = v->run;

op->data = 0;

goto found;

}

}

// 沒有的話則調用該函數

if (ngx_http_log_variable_compile(cf, op, &var) != NGX_OK) {

return NGX_CONF_ERROR;

}

if (len) {

op->len = len;

op->getlen = NULL;

// 如果長度小的話,就直接用data來記錄

if (len <= sizeof(uintptr_t)) {

op->run = ngx_http_log_copy_short;

op->data = 0;

// 記錄data

while (len--) {

op->data <<= 8;

op->data |= data[len];

}

// 比較長的話,記錄成指針來指向,函數也是獲取指針來進行獲取值

} else {

op->run = ngx_http_log_copy_long;

p = ngx_pnalloc(cf->pool, len);

if (p == NULL) {

return NGX_CONF_ERROR;

}

ngx_memcpy(p, data, len);

op->data = (uintptr_t) p;

}

}

}

static ngx_int_t ngx_http_log_variable_compile(ngx_conf_t *cf, ngx_http_log_op_t *op, ngx_str_t *value)

{

ngx_int_t  index;

index = ngx_http_get_variable_index(cf, value);

op->len = 0;

op->getlen = ngx_http_log_variable_getlen;

op->run = ngx_http_log_variable;

op->data = index;

}

// 而這些可以進入日志中的參數,則是在core_preconfiguration函數中的ngx_http_variables_add_core_vars函數

ngx_int_t ngx_http_variables_add_core_vars(ngx_conf_t *cf)

{

cmcf->variables_keys = ngx_pcalloc(cf->temp_pool,

sizeof(ngx_hash_keys_arrays_t));

for (cv = ngx_http_core_variables; cv->name.len; cv++) {

v = ngx_palloc(cf->pool, sizeof(ngx_http_variable_t));

if (v == NULL) {

return NGX_ERROR;

}

*v = *cv;

rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v, NGX_HASH_READONLY_KEY);

if (rc == NGX_OK) {

continue;

}

if (rc == NGX_BUSY) {

ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "conflicting variable name \"%V\"", &v->name);

}

return NGX_ERROR;

}

接下來可以看下整個的ngx_http_core_variables

static ngx_http_variable_t  ngx_http_core_variables[] = {

{ ngx_string("http_host"), NULL, ngx_http_variable_header,

offsetof(ngx_http_request_t, headers_in.host), 0, 0 },

{ ngx_string("http_user_agent"), NULL, ngx_http_variable_header,

offsetof(ngx_http_request_t, headers_in.user_agent), 0, 0 },

{ ngx_string("http_referer"), NULL, ngx_http_variable_header,

offsetof(ngx_http_request_t, headers_in.referer), 0, 0 },

#if (NGX_HTTP_GZIP)

{ ngx_string("http_via"), NULL, ngx_http_variable_header,

offsetof(ngx_http_request_t, headers_in.via), 0, 0 },

#endif

#if (NGX_HTTP_X_FORWARDED_FOR)

{ ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_headers,

offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0, 0 },

#endif

{ ngx_string("http_cookie"), NULL, ngx_http_variable_cookies,

offsetof(ngx_http_request_t, headers_in.cookies), 0, 0 },

{ ngx_string("content_length"), NULL, ngx_http_variable_content_length,

0, 0, 0 },

{ ngx_string("content_type"), NULL, ngx_http_variable_header,

offsetof(ngx_http_request_t, headers_in.content_type), 0, 0 },

{ ngx_string("host"), NULL, ngx_http_variable_host, 0, 0, 0 },

{ ngx_string("binary_remote_addr"), NULL,

ngx_http_variable_binary_remote_addr, 0, 0, 0 },

{ ngx_string("remote_addr"), NULL, ngx_http_variable_remote_addr, 0, 0, 0 },

{ ngx_string("remote_port"), NULL, ngx_http_variable_remote_port, 0, 0, 0 },

{ ngx_string("proxy_protocol_addr"), NULL,

ngx_http_variable_proxy_protocol_addr, 0, 0, 0 },

{ ngx_string("server_addr"), NULL, ngx_http_variable_server_addr, 0, 0, 0 },

{ ngx_string("server_port"), NULL, ngx_http_variable_server_port, 0, 0, 0 },

{ ngx_string("server_protocol"), NULL, ngx_http_variable_request,

offsetof(ngx_http_request_t, http_protocol), 0, 0 },

{ ngx_string("scheme"), NULL, ngx_http_variable_scheme, 0, 0, 0 },

{ ngx_string("https"), NULL, ngx_http_variable_https, 0, 0, 0 },

{ ngx_string("full_request"), NULL, ngx_http_variable_full_request,

0, 0, 0 },

{ ngx_string("normalized_request"), NULL, ngx_http_variable_normalized_request,

0, 0, 0 },

{ ngx_string("request_uri"), NULL, ngx_http_variable_request,

offsetof(ngx_http_request_t, unparsed_uri), 0, 0 },

{ ngx_string("raw_uri"), NULL, ngx_http_variable_request,

offsetof(ngx_http_request_t, raw_uri), 0, 0 },

{ ngx_string("uri"), NULL, ngx_http_variable_request,

offsetof(ngx_http_request_t, uri),

NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("document_uri"), NULL, ngx_http_variable_request,

offsetof(ngx_http_request_t, uri),

NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("request"), NULL, ngx_http_variable_request_line, 0, 0, 0 },

{ ngx_string("document_root"), NULL,

ngx_http_variable_document_root, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("realpath_root"), NULL,

ngx_http_variable_realpath_root, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("query_string"), NULL, ngx_http_variable_request,

offsetof(ngx_http_request_t, args),

NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("args"),

ngx_http_variable_set_args,

ngx_http_variable_request,

offsetof(ngx_http_request_t, args),

NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("is_args"), NULL, ngx_http_variable_is_args,

0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("request_filename"), NULL,

ngx_http_variable_request_filename, 0,

NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("server_name"), NULL, ngx_http_variable_server_name, 0, 0, 0 },

{ ngx_string("request_method"), NULL,

ngx_http_variable_request_method, 0,

NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("remote_user"), NULL, ngx_http_variable_remote_user, 0, 0, 0 },

{ ngx_string("bytes_sent"), NULL, ngx_http_variable_bytes_sent,

0, 0, 0 },

{ ngx_string("body_bytes_sent"), NULL, ngx_http_variable_body_bytes_sent,

0, 0, 0 },

{ ngx_string("pipe"), NULL, ngx_http_variable_pipe,

0, 0, 0 },

{ ngx_string("request_completion"), NULL,

ngx_http_variable_request_completion,

0, 0, 0 },

{ ngx_string("request_body"), NULL,

ngx_http_variable_request_body,

0, 0, 0 },

{ ngx_string("request_body_file"), NULL,

ngx_http_variable_request_body_file,

0, 0, 0 },

{ ngx_string("request_length"), NULL, ngx_http_variable_request_length,

0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("request_time"), NULL, ngx_http_variable_request_time,

0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("status"), NULL,

ngx_http_variable_status, 0,

NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("sent_http_content_type"), NULL,

ngx_http_variable_sent_content_type, 0, 0, 0 },

{ ngx_string("sent_http_content_length"), NULL,

ngx_http_variable_sent_content_length, 0, 0, 0 },

{ ngx_string("sent_http_location"), NULL,

ngx_http_variable_sent_location, 0, 0, 0 },

{ ngx_string("sent_http_last_modified"), NULL,

ngx_http_variable_sent_last_modified, 0, 0, 0 },

{ ngx_string("sent_http_connection"), NULL,

ngx_http_variable_sent_connection, 0, 0, 0 },

{ ngx_string("sent_http_keep_alive"), NULL,

ngx_http_variable_sent_keep_alive, 0, 0, 0 },

{ ngx_string("sent_http_transfer_encoding"), NULL,

ngx_http_variable_sent_transfer_encoding, 0, 0, 0 },

{ ngx_string("sent_http_cache_control"), NULL, ngx_http_variable_headers,

offsetof(ngx_http_request_t, headers_out.cache_control), 0, 0 },

{ ngx_string("limit_rate"), ngx_http_variable_request_set_size,

ngx_http_variable_request_get_size,

offsetof(ngx_http_request_t, limit_rate),

NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("connection"), NULL,

ngx_http_variable_connection, 0, 0, 0 },

{ ngx_string("connection_requests"), NULL,

ngx_http_variable_connection_requests, 0, 0, 0 },

{ ngx_string("nginx_version"), NULL, ngx_http_variable_nginx_version,

0, 0, 0 },

{ ngx_string("hostname"), NULL, ngx_http_variable_hostname,

0, 0, 0 },

{ ngx_string("pid"), NULL, ngx_http_variable_pid,

0, 0, 0 },

{ ngx_string("msec"), NULL, ngx_http_variable_msec,

0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("dollar"), NULL, ngx_http_variable_dollar,

0, 0, 0 },

{ ngx_string("host_comment"), NULL, ngx_http_variable_host_comment,

0, 0, 0 },

{ ngx_string("unix_time"), NULL, ngx_http_variable_unix_time,

0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("year"), NULL, ngx_http_variable_year,

0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("year2"), NULL, ngx_http_variable_year2,

0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("month"), NULL, ngx_http_variable_month,

0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("day"), NULL, ngx_http_variable_day,

0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("hour"), NULL, ngx_http_variable_hour,

0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("hour12"), NULL, ngx_http_variable_hour12,

0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("minute"), NULL, ngx_http_variable_minute,

0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("second"), NULL, ngx_http_variable_second,

0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("time_iso8601"), NULL, ngx_http_variable_time_iso8601,

0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("time_local"), NULL, ngx_http_variable_time_local,

0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("time_http"), NULL, ngx_http_variable_time_http,

0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

#if (NGX_HAVE_TCP_INFO)

{ ngx_string("tcpinfo_rtt"), NULL, ngx_http_variable_tcpinfo,

0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("tcpinfo_rttvar"), NULL, ngx_http_variable_tcpinfo,

1, NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("tcpinfo_snd_cwnd"), NULL, ngx_http_variable_tcpinfo,

2, NGX_HTTP_VAR_NOCACHEABLE, 0 },

{ ngx_string("tcpinfo_rcv_space"), NULL, ngx_http_variable_tcpinfo,

3, NGX_HTTP_VAR_NOCACHEABLE, 0 },

#endif

{ ngx_null_string, NULL, NULL, 0, 0, 0 }

};

這塊是在ngx_http_variables_init_vars中初始化

ngx_int_t ngx_http_variables_init_vars(ngx_conf_t *cf)

{

cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);

v = cmcf->variables.elts;

key = cmcf->variables_keys->keys.elts;

for (i = 0; i < cmcf->variables.nelts; i++) {

for (n = 0; n < cmcf->variables_keys->keys.nelts; n++) {

av = key[n].value;

if (v[i].name.len == key[n].key.len && ngx_strncmp(v[i].name.data, key[n].key.data, v[i].name.len) == 0)

{

// 將get_handler和data賦值過來

v[i].get_handler = av->get_handler;

v[i].data = av->data;

}

到此,相信大家對“nginx日志模塊的源碼分析”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

枣阳市| 霍城县| 绥德县| 罗平县| 漯河市| 湟中县| 连城县| 岳普湖县| 九龙城区| 大宁县| 福贡县| 周至县| 三穗县| 修文县| 东至县| 沽源县| 奇台县| 丹寨县| 岫岩| 莲花县| 宽城| 莱芜市| 安顺市| 扎兰屯市| 长葛市| 外汇| 徐州市| 宜昌市| 平潭县| 神农架林区| 南平市| 闵行区| 绥滨县| 太谷县| 江华| 宜阳县| 昆山市| 玉环县| 磴口县| 门源| 新干县|