core/ngx_log.h头文件分析
本节我们主要讲述一下nginx中日志的相关实现。
1. 相关宏定义
上面宏定义可以分成3个部分:
1) 定义日志的打印级别
#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
对于每一个logger,只有那些高于当前所设置的打印级别的信息才会打印出来。
2) 指示debug模块
#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_STREAM 0x400
对于debug级别的日志,在进行日志打印时还会检查相应的掩码。
3) debug相应掩码总结
-
NGX_LOG_DEBUG_FIRST
: 第一个debug模块 -
```NGX_LOG_DEBUG_LAST``: 最后一个debug模块
-
NGX_LOG_DEBUG_CONNECTION
: 用于指示nginx中相应连接的debug信息的掩码 -
NGX_LOG_DEBUG_ALL
: nginx中所有debug信息的掩码
2. ngx_log_s数据结构
ngx_log_s是对日志数据结构的抽象,下面详细介绍一下各字段:
-
log_level
: 指示当前的日志打印级别 -
file
: 指示当前日志对象所关联的文件 -
connection
: 当前引用该日志对象的连接数(connection number) -
disk_full_time
: 指示日志硬盘满的时间 -
handler
: 日志信息处理器(一般是对日志进行格式化) -
data
: 一般作为日志信息处理的一个上下文对象。例如: 当前要用handler格式化一个http request信息等,此时可以用data字段来存放该上下文。(可以通过查询log->data,找到相应的用法) -
writer
: 进行日志写操作处理器 -
wdata
: 作为日志写操作处理器的一个上下文对象。例如: 当writer是写到内存中时,wdata可能关联的就是一个ngx_log_memory_buf_t
对象。 -
action
: 用于指示在写日志前,所执行的操作(比如当前正在进行SSL handshaking
,或者正在closing request
等) -
next
: 指向下一个日志对象
3. 日志打印核心函数声明
这里首先定义了NGX_MAX_ERROR_STR
为2048,即单条日志的最大长度为2048。
当前在objs/ngx_auto_config.h头文件中,我们有如下宏定义:
#ifndef NGX_HAVE_C99_VARIADIC_MACROS #define NGX_HAVE_C99_VARIADIC_MACROS 1 #endif #ifndef NGX_HAVE_GCC_VARIADIC_MACROS #define NGX_HAVE_GCC_VARIADIC_MACROS 1 #endif
我们当前同时支持C99可变参数宏定义
与gcc可变参数宏定义
。其中c99可变参数宏定义类似于如下:
#define var(dummy, ...) sprintf(__VA_ARGS__)
gcc可变参数宏定义类似于如下:
#define var(dummy, args...) sprintf(args)
上面我们定义了三个函数:
-
ngx_log_error(): 打印一般的错误日志消息(只有高于对应错误日志级别,才会打印出来)
-
ngx_log_error_core(): 打印日志的核心函数
-
ngx_log_debug_core(): 打印debug级别日志的函数
4. ngx_log_debug辅助函数
如上这些函数只是为了使用方便,针对ngx_log_debug()可变参数函数的特定参数个数时,进行定制。
当前我们并未开启NGX_DEBUG
,要想开启NGX_DEBUG
宏,请在编译时添加--with-debug
选项。
5. 相关函数声明
6. 相关静态函数定义
上述两个函数分别用于将text
输出到标准错误以及标准输出中。关于为什么ngx_write_stderr()
不能采用宏来实现,上面注释已经很清楚,不过这主要是针对MSVC上的实现,即Windows版本nginx,对于linux版本并没有此问题。
而关于为什么使用ngx_write_fd()
函数,上面的注释当前已经过于老旧。目前ngx_write_console()函数实现如下:
#define ngx_write_console ngx_write_fd
7. 相关变量声明
上面声明了两个变量:
-
ngx_errlog_module
: errlog模块相应数据结构变量 -
ngx_use_stderr
: 该变量主要用于控制是否输出到标准错误。一般在Nginx启动的时候,会将ngx_use_stderr设置为1,这时用户可以从标准错误中看到相应的启动输出信息,启动之后就会被设置为0,这时nginx以静默方式运行。
[参考]