ngx_log_error
声明在 src\core\ngx_log.h 中:
但是通过检索找到了 3 个结果
#if (NGX_HAVE_C99_VARIADIC_MACROS) #define NGX_HAVE_VARIADIC_MACROS 1 #define ngx_log_error(level, log, ...) \ if ((log)->log_level >= level) ngx_log_error_core(level, log, __VA_ARGS__) void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, const char *fmt, ...); #define ngx_log_debug(level, log, ...) \ if ((log)->log_level & level) \ ngx_log_error_core(NGX_LOG_DEBUG, log, __VA_ARGS__) /*********************************/ #elif (NGX_HAVE_GCC_VARIADIC_MACROS) #define NGX_HAVE_VARIADIC_MACROS 1 #define ngx_log_error(level, log, args...) \ if ((log)->log_level >= level) ngx_log_error_core(level, log, args) void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, const char *fmt, ...); #define ngx_log_debug(level, log, args...) \ if ((log)->log_level & level) \ ngx_log_error_core(NGX_LOG_DEBUG, log, args) /*********************************/ #else /* no variadic macros */ #define NGX_HAVE_VARIADIC_MACROS 0 void ngx_cdecl ngx_log_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, const char *fmt, ...); void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, const char *fmt, va_list args); void ngx_cdecl ngx_log_debug_core(ngx_log_t *log, ngx_err_t err, const char *fmt, ...); #endif /* variadic macros */
通过 gcc -E 先来看一下结果:
gcc -E src/event/ngx_event_openssl.c \ -I src/core \ -I src/event \ -I src/event/modules \ -I src/os/unix \ -I objs \ > ngx_event_openssl_preprocessed.c
在输出文件 ngx_event_openssl_preprocessed.c 中查找 ngx_ssl_error
void ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...) { int flags; u_long n; va_list args; u_char *p, *last; u_char errstr[1024]; const char *data; last = errstr + 1024; # 3623 "src/event/ngx_event_openssl.c" 3 4 __builtin_va_start( # 3623 "src/event/ngx_event_openssl.c" args # 3623 "src/event/ngx_event_openssl.c" 3 4 , # 3623 "src/event/ngx_event_openssl.c" fmt # 3623 "src/event/ngx_event_openssl.c" 3 4 ) # 3623 "src/event/ngx_event_openssl.c" ; p = ngx_vslprintf(errstr, last - 1, fmt, args); # 3625 "src/event/ngx_event_openssl.c" 3 4 __builtin_va_end( # 3625 "src/event/ngx_event_openssl.c" args # 3625 "src/event/ngx_event_openssl.c" 3 4 ) # 3625 "src/event/ngx_event_openssl.c" ; if (ERR_peek_error()) { p = ngx_cpystrn(p, (u_char *) " (SSL:", last - p); for ( ;; ) { n = ERR_peek_error_data(&data, &flags); if (n == 0) { break; } if (p >= last - 1) { goto next; } *p++ = ' '; ERR_error_string_n(n, (char *) p, last - p); while (p < last && *p) { p++; } if (p < last && *data && (flags & # 3652 "src/event/ngx_event_openssl.c" 3 4 0x02 # 3652 "src/event/ngx_event_openssl.c" )) { *p++ = ':'; p = ngx_cpystrn(p, (u_char *) data, last - p); } next: (void) ERR_get_error(); } if (p < last) { *p++ = ')'; } } if ((log)->log_level >= level) ngx_log_error_core(level, log, err, "%*s", p - errstr, errstr); }
原本
ngx_log_error(level, log, err, "%*s", p - errstr, errstr);
对应的地方现在是:
if ((log)->log_level >= level) ngx_log_error_core(level, log, err, "%*s", p - errstr, errstr);
再回到 src\core\ngx_log.h 中
成立的是这部分
#define ngx_log_error(level, log, ...) \ if ((log)->log_level >= level) ngx_log_error_core(level, log, __VA_ARGS__)
NGX_HAVE_C99_VARIADIC_MACROS
NGX_HAVE_GCC_VARIADIC_MACROS
定义在 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
NGX_HAVE_C99_VARIADIC_MACROS
和NGX_HAVE_GCC_VARIADIC_MACROS
是 Nginx 源码中用于检测编译器是否支持 **可变参数宏(Variadic Macros)**的两个宏。它们的作用是帮助 Nginx 在不同编译器和标准下选择合适的实现方式,以确保代码的兼容性和正确性。
什么是可变参数宏?
在 C 语言中,可变参数宏 是一种允许宏定义接受可变数量参数的功能。它的语法类似于函数的可变参数(
...
),但用于预处理器宏。
C99 标准中的可变参数宏
C99 标准引入了对可变参数宏的支持,语法如下:
#define LOG_ERROR(fmt, ...) printf(fmt, ##__VA_ARGS__)
__VA_ARGS__
: 表示宏调用时传递的所有额外参数
##__VA_ARGS__
: 在某些编译器中(如 GCC),可以用来处理空参数的情况,避免多余的逗号
GCC 扩展中的可变参数宏
在 C99 标准之前,GCC 编译器已经通过扩展支持了可变参数宏,语法与 C99 类似,但在某些细节上可能有所不同。
GCC 风格的可变参数宏使用
args...
来表示可变参数部分,而不是 C99 标准中的__VA_ARGS__
其基本语法如下:
#define MACRO_NAME(fixed_args, args...) implementation_using_args
fixed_args
: 宏的固定参数。args...
: 表示可变参数部分,类似于函数中的...
。##args
: 在 GCC 扩展中,可以使用##
来处理空参数的情况,避免多余的逗号。
NGX_HAVE_C99_VARIADIC_MACROS
- 含义 : 表示当前编译环境是否支持 C99 标准的可变参数宏。
- 检测方式: 通常通过检查编译器是否支持 C99 标准来定义该宏。
- 用途: 如果定义了该宏,Nginx 可以使用 C99 风格的可变参数宏。
NGX_HAVE_GCC_VARIADIC_MACROS
- 含义 : 表示当前编译环境是否支持 GCC 扩展的可变参数宏。
- 检测方式: 通常通过检查编译器是否为 GCC 或兼容 GCC 的编译器来定义该宏。
- 用途: 如果定义了该宏,Nginx 可以使用 GCC 风格的可变参数宏。
- 如果支持 C99 标准,则使用
__VA_ARGS__
- 如果仅支持 GCC 扩展,则使用
args...
回到 ngx_log_error 的定义中来:
#define ngx_log_error(level, log, ...) \ if ((log)->log_level >= level) ngx_log_error_core(level, log, __VA_ARGS__)
(log)->log_level
表示当前日志对象允许记录的最低日志级别
level
指定当前日志消息的级别
(log)->log_level >= level
比较当前日志对象的配置级别和日志消息的级别
- 如果
log->log_level
大于或等于level
,表示当前日志消息的严重程度足够高,应该被记录。- 否则,跳过日志记录,避免不必要的性能开销
ngx_log_error_core(level, log, __VA_ARGS__)
调用核心日志函数,实际执行日志记录操作
level
: 当前日志消息的级别。log
: 日志对象,包含日志的输出目标(如文件、标准错误等)。__VA_ARGS__
: 可变参数,表示格式化字符串及其参数(类似于printf
的参数)
下面的 问题是
ngx_log_error_core
声明在 src\core\ngx_log.h 中:
void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, const char *fmt, ...);
Ubuntu 下 nginx-1.24.0 源码分析 - ngx_log_error 函数
若云止水2025-02-17 10:18
相关推荐
枫叶落雨2221 小时前
08-Elasticsearch爆更小小刘2 小时前
Linux下基本指令(4)我码玄黄2 小时前
解决本地模拟IP的DHCP冲突问题若云止水2 小时前
Ubuntu 下 nginx-1.24.0 源码分析 - ngx_os_init 函数Self-Discipline3 小时前
Linux arm64 IOMMU总结我言秋日胜春朝★3 小时前
【Linux】命名管道------Linux进程间通信的桥梁Dontla3 小时前
华为昇腾服务器(固件版本查询、驱动版本查询、CANN版本查询)wenchun0013 小时前
【并发压测】高并发下Linux流量监控从后端到QT3 小时前
ubuntu磁盘清理垃圾文件m0_512744643 小时前
Nginx(详解以及如何使用)