APISIX自定义Lua插件:Rewrite阶段如何实现文件滚动日志写入?
APISIX自定义Lua插件日志问题解决方案
问题根源分析
- 路径与权限限制:Rewrite阶段使用lualogging时,若指定相对路径,会基于Nginx工作目录而非APISIX安装目录,且APISIX worker进程(通常是
nginx用户)可能无该路径的写入权限,导致日志无法落地。 - lualogging与Nginx事件循环冲突:lualogging的同步文件写入操作,在Nginx非阻塞事件循环的早期阶段(Rewrite)可能被机制限制,无法正常执行。
- ngx.log级别不匹配:
ngx.log打印的日志级别若高于Nginx配置的error_log级别(比如默认是error级,你用了ngx.info),则不会写入error.log;而access.log仅自动记录请求元数据,自定义日志未通过配置注入的话,不会自动写入。
可行解决方案
方案1:适配APISIX环境调整lualogging使用
- 使用绝对路径:指定lualogging的日志文件为绝对路径(如
/var/log/apisix/custom_token_auth.log),并给nginx用户赋予该目录的写入权限:mkdir -p /var/log/apisix chown nginx:nginx /var/log/apisix - 全局初始化日志器:不在每个请求的Rewrite阶段重复初始化,而是在插件的
_init_worker方法中全局初始化一次,避免多worker冲突:local logger = require "logging.rolling_file" local rolling_logger function _M._init_worker() -- 单个日志文件10M,保留10个备份文件 rolling_logger = logger.new("/var/log/apisix/custom_token_auth.log", 10*1024*1024, 10) end function _M.rewrite(conf, ctx) -- Token认证逻辑 local auth_result = "token validation passed" -- 写入滚动日志 rolling_logger:info(auth_result) -- 设置请求头逻辑 ngx.req.set_header("X-Auth-Status", "valid") end
方案2:复用Nginx日志系统实现滚动(更适配APISIX)
无需依赖lualogging,直接用Nginx原生日志+logrotate实现滚动:
- 添加Nginx日志配置:在APISIX的Nginx模板文件(如
conf/nginx.conf或conf/apisix/http.conf)中添加自定义日志格式和路径:log_format token_auth_log '$remote_addr [$time_local] "$request" ' 'auth_status:$custom_auth_status token:$custom_token'; access_log /var/log/apisix/token_auth.log token_auth_log buffer=32k flush=5s; - 插件中注入日志变量:在Rewrite阶段通过
ngx.var设置自定义变量,让Nginx自动记录日志:function _M.rewrite(conf, ctx) -- Token认证逻辑 local token = ngx.req.get_headers()["Authorization"] local auth_status = "valid" -- 注入自定义变量到Nginx上下文 ngx.var.custom_auth_status = auth_status ngx.var.custom_token = token or "null" -- 设置请求头 ngx.req.set_header("X-Auth-Status", auth_status) end - 配置logrotate实现滚动:创建
/etc/logrotate.d/apisix_token_auth文件:/var/log/apisix/token_auth.log { daily missingok rotate 10 compress delaycompress notifempty create 0640 nginx nginx postrotate kill -USR1 `cat /var/run/apisix/nginx.pid` endscript }
方案3:修复ngx.log不进默认日志的问题
- 调整APISIX配置文件
conf/config.yaml中的日志级别,确保error_log_level足够低(如info):nginx_log: error_log_level: info error_log_path: logs/error.log access_log_path: logs/access.log - 若要让自定义日志进入access.log,需将日志内容注入到access_log的格式中,或使用
ngx.log(ngx.NOTICE)(但更推荐用自定义日志文件区分业务日志)。
内容的提问来源于stack exchange,提问作者Vivek Singh
相关产品推荐
相关产品推荐

