Nginx源代码分析 - 日志处理
发布日期:2021-06-30 19:22:29
浏览次数:2
分类:技术文章
本文共 4151 字,大约阅读时间需要 13 分钟。
我看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()两个函数
转载地址:https://linuxstyle.blog.csdn.net/article/details/6573948 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
网站不错 人气很旺了 加油
[***.192.178.218]2024年04月14日 21时14分40秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
UVA-11401 Triangle Counting(数学优化)
2019-04-30
Codeforces Round #369 (Div. 2)
2019-04-30
UVA 11426 GCD - Extreme (II)(欧拉函数)
2019-04-30
HDU-2838 Cow Sorting(树状数组)
2019-04-30
POJ-2299 Ultra-QuickSort(树状数组)(离散化)
2019-04-30
基于SSM的兼职论坛系统的设计与实现
2019-04-30
基于java的图书管理系统的设计与实现
2019-04-30
基于java的SSM框架理财管理系统的设计与实现
2019-04-30
基于java的ssm框架就业信息管理系统的设计
2019-04-30
基于java的ssm框架的旅游网站设计与实现
2019-04-30
基于java的SSM框架的流浪猫救助网站的设计与实现
2019-04-30
基于java的SSM框架的教务关系系统的设计与实现
2019-04-30
别再问我什么是A/B测试了!
2019-04-30
如何用同期群分析模型提升留存?(Tableau实战)
2019-04-30
爱了,吹爆这个高颜值的流程图工具!
2019-04-30
一个数据项目
2019-04-30
基于JAVA_JSP电子书下载系统
2019-04-30
基于java出租车计价器设计与实现
2019-04-30
基于java的B2C的网上拍卖系统
2019-04-30