技術(shù)員聯(lián)盟提供win764位系統(tǒng)下載,win10,win7,xp,裝機(jī)純凈版,64位旗艦版,綠色軟件,免費(fèi)軟件下載基地!

當(dāng)前位置:主頁(yè) > 教程 > 服務(wù)器類(lèi) >

Nginx的error_log和Access_log分析

來(lái)源:技術(shù)員聯(lián)盟┆發(fā)布時(shí)間:2018-05-27 06:24┆點(diǎn)擊:

  nginx配置中有關(guān)日志的配置主要是圍繞著下面兩個(gè)指令:

  1、error_log

  2、access_log:記錄訪問(wèn)日志

  首先要強(qiáng)調(diào)的一點(diǎn)是,如果access日志和error日志都是常量文件名(因?yàn)閍ccess支持變量文件名,后續(xù)會(huì)講到),那么nginx進(jìn)程會(huì)緩存文件描述符直到進(jìn)程結(jié)束。

  什么時(shí)候日志的fd會(huì)改變呢?

  1)進(jìn)程重啟

  2)收到了NGX_REOPEN_SIGNAL信號(hào),會(huì)產(chǎn)生新的日志文件

  其他情況下,日志的fd不變,所以當(dāng)進(jìn)程運(yùn)行中,刪除了日志文件的話,并不會(huì)生成新的日志文件,且日志都會(huì)丟失

  下面詳細(xì)講一下這兩個(gè)指令的來(lái)龍去脈

  一:先說(shuō)error_log:

  nginx有兩個(gè)模塊支持error_log指令:

  一個(gè)是 ngx_errlog_module ,這個(gè)模塊只有一個(gè)指令,就是error_log ,配置類(lèi)型為:NGX_MAIN_CONF,回調(diào)函數(shù)為:ngx_error_log;

  另一個(gè)是 ngx_http_core_module,這個(gè)模塊中也有指令:error_log ,配置類(lèi)型為:NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF,回調(diào)函數(shù)為:ngx_http_core_error_log。

  static ngx_command_t ngx_errlog_commands[] = {

  {ngx_string("error_log"),

  NGX_MAIN_CONF|NGX_CONF_1MORE,

  ngx_error_log,

  0,

  0,

  NULL},

  ngx_null_command

  };

  static ngx_command_t ngx_http_core_commands[] = {

  { ngx_string("error_log"),

  NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,

  ngx_http_core_error_log,

  NGX_HTTP_LOC_CONF_OFFSET,

  0,

  NULL },

  }

  這樣會(huì)產(chǎn)生幾個(gè)疑問(wèn):

  1:為什么需要兩個(gè)相同的指令實(shí)現(xiàn)相同的功能。

  2:兩個(gè)指令的類(lèi)型均支持NGX_HTTP_MAIN_CONF ,那么在main中配置的error_log到底使用的是哪一個(gè)

  3:兩者的作用關(guān)系。

  下面來(lái)解釋一下:

  nginx在進(jìn)行模塊注冊(cè)時(shí),會(huì)發(fā)現(xiàn) ngx_errlog_module 模塊是先于 ngx_http_core_module 模塊注冊(cè)的 。

  在nginx在解析配置文件的時(shí)候 ,見(jiàn)到 error_log,會(huì)按照注冊(cè)模塊的順序查找指令,這樣,會(huì)先找到ngx_errlog_module模塊,如果此時(shí),error_log是在main配置的,那么和ngx_errlog_module模塊error_log的NGX_HTTP_MAIN_CONF match,執(zhí)行ngx_error_log。

  如果error_log是在http{}配置的,也會(huì)按照注冊(cè)模塊的順序查找指令,找到ngx_errlog_module模塊的error_log,發(fā)現(xiàn)type是NGX_HTTP_MAIN_CONF,不match,繼續(xù)往下找,找到ngx_http_core_module的error_log,type是NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF ,match后執(zhí)行ngx_http_core_error_log。

  上面提到了ngx_error_log 和 ngx_http_core_error_log兩個(gè)函數(shù),這兩個(gè)函數(shù)的功能基本一致,但是因?yàn)閮蓚€(gè)配置作用域不同,所以配置存儲(chǔ)位置不同:ngx_errlog_module存儲(chǔ)在cycle->new_log,ngx_http_core_module存儲(chǔ)在http core模塊數(shù)據(jù)結(jié)構(gòu)ngx_http_core_loc_conf_s的error_log(在此簡(jiǎn)寫(xiě)成:clcf->error_log)。

  clcf->error_log是http模塊中的,其主要記錄和http請(qǐng)求相關(guān)的日志。

  cycle->new_log主要記錄如進(jìn)程啟動(dòng),event等。

  但是主進(jìn)程啟動(dòng)的時(shí)候,此時(shí)還沒(méi)有讀取配置文件,即沒(méi)有指定日志打印在哪里。nginx這時(shí)候雖然可以將一些出錯(cuò)內(nèi)容或者結(jié)果輸?shù)綐?biāo)準(zhǔn)輸出,但是如果要記錄一些系統(tǒng)初始化情況,socket監(jiān)聽(tīng)狀況,還是需要寫(xiě)到日志文件中去的。在nginx的main函數(shù)中,首先會(huì)調(diào)用ngx_log_init 函數(shù),默認(rèn)日志文件為:安裝路徑/logs/error.log,如果這個(gè)文件沒(méi)有權(quán)限訪問(wèn)的話,會(huì)直接報(bào)錯(cuò)退出。在mian函數(shù)結(jié)尾處,在ngx_master_process_cycle函數(shù)調(diào)用之前,會(huì)close掉這個(gè)日志文件。

  如果只在main配置了error_log,http{}中沒(méi)有設(shè)置,那么clcf->error_log賦值為clcf->error_log,如下:

  static char *

  ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)

  {

  ngx_http_core_loc_conf_t *prev = parent;

  ngx_http_core_loc_conf_t *conf = child;

  。。。。。。

  if (conf->error_log == NULL) {

  if (prev->error_log) {

  conf->error_log = prev->error_log;

  } else {

  conf->error_log = &cf->cycle->new_log;

  }

  }

  。。。。。。

  }

  那為什么不把兩個(gè)指令合并到一起呢。

  首先看一下模塊注冊(cè)順序:

  ngx_module_t *ngx_modules[] = {

  &ngx_core_module,

  &ngx_errlog_module,

  &ngx_conf_module,

  &ngx_events_module,

  &ngx_event_core_module,

  &ngx_rtsig_module,

  &ngx_epoll_module,

  &ngx_regex_module,

  &ngx_http_module,

  &ngx_http_core_module,

  &ngx_http_log_module,

  ......

  }

  可見(jiàn)ngx_errlog_module 和 ngx_http_core_module中間有n多模塊。這些模塊是獨(dú)立于http的,而且需要日志的打印,這些日志肯定是需要記錄的。

  則此模塊不可省,那么考慮把ngx_http_core_module的error_log合并過(guò)來(lái)呢,想想也不行,為什么呢?

  想想ngx_errlog_module將error_log信息存在哪里,想想ngx_http_core_module的error_log信息存在哪里。

  在調(diào)用ngx_error_log時(shí)候,把針對(duì)不同server或者location的error_log信息存儲(chǔ)在哪里。(模塊之間不能深度耦合)

  為了兩個(gè)模塊互不影響,這是個(gè)好辦法呀!

  二:access_log

  接下來(lái)看一下access_log,access_log指令是屬于ngx_http_log_module模塊。

  ngx_http_log_module有三個(gè)指令:

  static ngx_command_t ngx_http_log_commands[] = {

  { ngx_string("log_format"),

  NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_2MORE,

  ngx_http_log_set_format,

  NGX_HTTP_MAIN_CONF_OFFSET,

  0,

  NULL },

  { ngx_string("access_log"),

  NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF

  |NGX_HTTP_LMT_CONF|NGX_CONF_TAKE123,

  ngx_http_log_set_log,

  NGX_HTTP_LOC_CONF_OFFSET,

  0,

  NULL },

  { ngx_string("open_log_file_cache"),

  NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,

  ngx_http_log_open_file_cache,

  NGX_HTTP_LOC_CONF_OFFSET,

  0,

  NULL },

  ngx_null_command

  };