nginx日誌模塊ngx_http_log_module源碼分析

日誌相關的代碼在ngx_http_log_module.c中

在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模塊的初始化

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;

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章