error_log 不记录模块加载顺序,但通过设为 info 或 debug 级别可间接观察:info 级显示关键初始化节点,debug 级精确输出 init_module 调用顺序;结合 objs/ngx_modules.c 静态验证数组顺序,并辅以功能测试确认模块正常工作。

error_log 本身不记录模块加载顺序,它只输出错误、警告或调试信息。但你可以通过配置合适的日志级别和辅助手段,间接观察模块是否按预期顺序加载并初始化成功。
启用 info 或 debug 级别日志
Nginx 在启动阶段会输出模块注册与初始化过程的关键信息,前提是 error_log 级别设为 info 或更低(如 debug)。这些日志不会直接写成“模块A在模块B之前加载”,但会体现初始化时序和依赖关系:
- info 级别:记录模块注册、配置解析完成、事件模块初始化、HTTP 框架启动等关键节点,适合确认第三方模块是否被识别
- debug 级别:详细输出每个模块的 init_module 钩子调用顺序、ctx_index 分配、filter 链插入位置,是验证加载顺序最直接的方式
- 注意:debug 日志量极大,仅用于排查阶段;生产环境建议用 info 级别配合针对性验证
检查 error.log 中的关键线索
启动 Nginx 后查看 error.log,重点关注以下几类信息:
- 出现 "module is not binary compatible" 或 "undefined symbol":说明动态模块加载失败,往往因依赖模块未先初始化(如 geoip2 依赖 ngx_http_geoip2_module,但后者未编译或顺序靠后)
- 出现 "write filter must be last" 类提示:表明 http filter 模块顺序错误,&ngx_http_write_filter_module 不在数组末尾
- 无任何模块相关日志,但功能异常(如 rewrite 规则不生效、变量为空):可能两个同类型模块冲突,后加载的覆盖了前者的 handler 注册
结合 objs/ngx_modules.c 静态验证
error_log 是运行时反馈,而真正决定顺序的是编译生成的 objs/ngx_modules.c 文件。你应:
- 打开该文件,查找
ngx_modules[]数组,确认第三方模块是否按--add-module=传入顺序排列在 HTTP 模块之后、write_filter 之前 - 核对
&ngx_http_core_module的位置是否为 ctx_index = 0,这是所有 HTTP 模块初始化的起点 - 若使用动态模块,
load_module行顺序不影响此数组,但需确保其符号依赖的静态模块已提前加载
功能验证比日志更可靠
即使 error.log 没报错,也不能代表模块按需工作。建议做轻量级功能测试:
- 启用
ngx_http_geoip2_module后,访问含$geoip2_city_name的 location,能正常输出才说明初始化成功 - 使用
nginx_upstream_check_module时,检查 upstream 块中check指令是否被识别,否则可能是它比ngx_http_upstream_module初始化晚 - 自定义 filter 模块若修改响应体,需验证最终输出是否符合预期,避免因 write_filter 位置错误导致截断


















