Nginx的error_log和Access_log分析 nginx access log( 三 )


typedef struct {
ngx_array_t *lengths;
ngx_array_t *values;
} ngx_http_log_script_t;
4、不管是error_log还是access_log,nginx都是通过保存文件句柄来进行快速写日志文件的 。但是因为access_log支持根据变量指令路径,如果按照request或者ip来分隔不同的access日志,那么可想而至,若还按照保存文件句柄的方式来写日志文件,会造成系统fd的大量占用 。nginx在此进行了优化:
1)如果用常量指定acess日志路径:
access_log logs/access.log main;
那么和error_log一样,将文件路径名称放到cycle->open_files中去,这是个list,在路径加入这个list的时候会进行除重操作的 。在所有的模块初始化完毕,会依次打开这些文件路径,获取到fd,以备打印日志使用 。
打印日志的时候调用函数:ngx_write_fd
2)如果用变量指定acess日志路径:
使用script标记日志文件为变量文件名的 。
打印日志的时候调用函数:ngx_http_log_script_write
在这个函数里,体现出了对缓存fd的管理 。这些和指令open_file_log_cache的配置是息息相关的(后面会详细介绍) 。
打日志的函数:
static void
ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log, u_char *buf,
size_t len)
{
u_char *name;
time_t now;
ssize_t n;
ngx_err_t err;
if (log->script == NULL) {
name = log->file->name.data;
n = ngx_write_fd(log->file->fd, buf, len);
} else {
name = NULL;
n = ngx_http_log_script_write(r, log->script, &name, buf, len);
}
......
}
5、说到缓存文件描述符,nginx有两个指令是管理缓存文件描述符的
一个就是本文中说到的ngx_http_log_module模块的open_file_log_cache;
一个是ngx_http_core_module模块的 open_file_cache;
前者是只用来管理access变量日志文件 。
后者用来管理的就多了,包括:static,index,tryfiles,gzip,mp4,flv,看到了没,都是静态文件哦!
这两个指令的handler都调用了函数 ngx_open_file_cache_init ,这就是用来管理缓存文件描述符的第一步:初始化
ngx_open_file_cache_t *
ngx_open_file_cache_init(ngx_pool_t *pool, ngx_uint_t max, time_t inactive)
{
ngx_pool_cleanup_t *cln;
ngx_open_file_cache_t *cache;
cache = ngx_palloc(pool, sizeof(ngx_open_file_cache_t));
if (cache == NULL) {
return NULL;
}
ngx_rbtree_init(&cache->rbtree, &cache->sentinel,
ngx_open_file_cache_rbtree_insert_value);
ngx_queue_init(&cache->expire_queue);
cache->current = 0;
cache->max = max;
cache->inactive = inactive;
cln = ngx_pool_cleanup_add(pool, 0);
if (cln == NULL) {
return NULL;
}
cln->handler = ngx_open_file_cache_cleanup;
cln->data = http://www.ljsggw.cn/internet/cache;
return cache;
}
可以看到nginx管理缓存文件描述符,使用了红黑树和队列,这个后续还是作为一篇文章来叙述吧,涉及的内容有点多,本文还是以分析日志模块为主 。
6、说一下指令 open_file_log_cache
1)nginx下默认这个指令的配置是:open_file_log_cache off;
也就是说不对access变量日志文件的fd做缓存,每写一个文件就打开,然后写日志 。那么这个文件fd什么时候关闭呢 。
这就涉及到nginx内存管理的cleanup了,cleanup可以注册,在内存池被销毁的时候,调用cleanup链表中各个cleanup的handler(详细可以去翻阅nginx内存池管理)
而此时的文件fd就是在request完毕后,销毁内存池的时候,关闭fd 。
配置open_log_file_cache off; 时的运行
这是获取access变量文件fd的函数,返回值应该是access日志的fd 。

推荐阅读