Nginx源代码分析 - 日志处理
我看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()两个函数
Nginx源代码分析 - 日志处理相关推荐
- 新秀nginx源代码分析数据结构篇(四)红黑树ngx_rbtree_t
新秀nginx源代码分析数据结构篇(四)红黑树ngx_rbtree_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csd ...
- nginx 关闭access日志_可视化实时Web日志分析工具,堪称神器!
说到web服务器就不得不说Nginx,目前已成为企业建站的首选.但由于种种历史原因,Nginx日志分析工具相较于传统的apache.lighthttp等还是少很多. 今天就和大家分享一个非常强大的实时 ...
- nginx 带宽_Nginx日志如何分析 GoAccess
" 如何进行Nginx日志的分析呢?如获得topN 来源IP.URL,以及PV.UV等. " 认识下GoAccess GoAccess[1]支持对所有Web日志格式实现快速实时的分 ...
- Nginx 訪问日志增长暴增出现尖刀的具体分析
前言: Nginx日志里面Mobileweb_access.log增长特别大.一天上百兆.将近100W的訪问记录.依照我们眼下的规模,热点用户才500个左右.就算人人用手机app訪问 ...
- FFmpeg源代码简单分析 日志输出系统(av log 等)
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! ==== ...
- awstats linux日志分析,日志分析:用AWStats分析Nginx的访问日志,它可以统计您站点的如...
日志分析:用AWStats分析Nginx的访问日志,它可以统计您站点的如 Awstats是一个免费非常简洁而且强大有个性的统计工具.它可以统计您站点的如下信息: 一:访问量,访问次数,页面浏览量,点击 ...
- nginx服务器access_log日志分析及配置详解
本博客转载于:http://www.pythontab.com/html/2013/linuxkaiyuan_0104/96.html nginx的log日志分为access log 和 error ...
- nginx服务器查看日志文件,nginx服务器中access_log日志分析与配置详解
前言 nginx的log日志分为:access log 和 error log 其中access log 记录了哪些用户,哪些页面以及用户浏览器.ip和其他的访问信息 error log 则是记录服务 ...
- HBase源代码分析之MemStore的flush发起时机、推断条件等详情(二)
在<HBase源代码分析之MemStore的flush发起时机.推断条件等详情>一文中,我们具体介绍了MemStore flush的发起时机.推断条件等详情.主要是两类操作.一是会引起Me ...
最新文章
- 中科院基因组所高远组诚聘生物信息学方向助理/副研及博士
- Response 和 Request
- SendMessage 和 PostMessage
- 如何实现字符串的翻转,不用php库函数翻转字符串
- C#LeetCode刷题之#707-设计链表(Design Linked List)
- 职务作品的著作权归属情况分析
- pycharm导出依赖包_使用pycharm导出虚拟环境依赖包
- Django开发教程 第一节 HelloWorld
- C语言左移右移操作符详解
- INVECAS发布全球首创的HDMI(R)2.1,搭载HDCP2.3芯片和IP解决方案,适用于电视、AVR、条形音响和机顶盒
- Steve Jobs Said
- 数据库 “投毒”修复方案
- 【DDNS更新】--公云的DDNS自动更新
- CentOS7 ECS使用(慕课网付费课笔记)
- 商品评论信息与评论信息分类
- 天才小毒妃 第961章 她不后悔就够了
- 彩色星球与阿里云签署合作备忘录;京东科技和软通动力达成战略合作 | 全球TMT...
- hdu2097 Sky数
- GIS在线学堂开课招生了
- 使用阿里云接口实现全国天气查询
热门文章
- 学精算的计算机知识,精算学专业学什么 附学习科目和课程
- mysql 导出中间 数据_MYSQL数据库之间的数据导出与导入
- 1数字图像获取:1.1图像数字化
- Pcl:Normal的定义结构及输出
- 力扣(LeetCode)刷题,简单题(第21期)
- OpenCV(项目)二维码识别(二维码、条形码)
- 【opencv】(3) 图像滤波:均值、方框、中值、高斯
- sqlserver mysql 乱码_SQLServer数据库如何解决中文乱码问题?方法有哪些?
- java快速查找算法_Java实现的快速查找算法示例
- popwindow下拉筛选 二级联动_职场人必备!一分钟搞定Excel二级联动下拉菜单