如何自定义Apache NiFi 2.4.0 API日志并添加logType自定义属性
Apache NiFi 2.4.0 自定义HTTP请求日志扩展方案
需求概述
使用Apache NiFi 2.4.0,扩展默认HTTP请求日志(nifi-request.log),添加自定义属性logType,取值包括DATA_ACCESS、DATA_EXPORT、INVALID_OBJECT,具体值由API端点或请求参数决定,生成包含额外审计细节的独立日志文件,用于API交互的审计与监控。
示例场景
调用GET /nifi-api/processors/{id}时:
- 处理器ID无效(不存在或格式错误):日志
logType设为invalid_object,记录错误相关属性; - 成功获取处理器信息:日志
logType设为DATA_ACCESS,记录数据访问审计相关属性。
已尝试方案
- 修改
logback.xml添加自定义appender,但无法动态提取请求信息进行分类; - 考虑自定义Jetty过滤器,但不确定如何与NiFi的Jetty服务器及Logback集成;
- 尝试
SiteToSiteBulletinReportingTask,但无法覆盖HTTP请求细节,不支持logType自定义属性。
问题解答
1. 实现自定义Jetty过滤器并记录带logType的API请求日志
NiFi的Jetty服务器支持通过扩展AbstractNiFiFilter实现自定义过滤器,步骤如下:
- 编写自定义过滤器:
继承org.apache.nifi.web.filter.AbstractNiFiFilter,在doFilter方法中完成请求解析、logType赋值、日志记录:@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; String path = httpRequest.getRequestURI(); String logType = "UNKNOWN"; // 匹配处理器端点 if (path.matches("/nifi-api/processors/.*")) { chain.doFilter(request, response); // 根据响应状态设置logType if (httpResponse.getStatus() == HttpServletResponse.SC_NOT_FOUND || httpResponse.getStatus() == HttpServletResponse.SC_BAD_REQUEST) { logType = "INVALID_OBJECT"; } else if (httpResponse.getStatus() == HttpServletResponse.SC_OK) { logType = "DATA_ACCESS"; } } else if (path.startsWith("/nifi-api/flowfile-queues/export")) { logType = "DATA_EXPORT"; chain.doFilter(request, response); } else { chain.doFilter(request, response); } // 将logType放入MDC供Logback捕获 MDC.put("logType", logType); getLogger().info("{} {} | logType={}", httpRequest.getMethod(), path, logType); // 清理MDC避免内存泄漏 MDC.remove("logType"); } - 注册过滤器:
将编译后的JAR包放入NiFi的lib目录,修改conf/nifi.properties添加过滤器配置:
如需调整过滤器优先级,可通过nifi.web.filter.custom=com.your.package.YourCustomFilternifi.web.filter.order参数配置。
2. 配置logback.xml捕获自定义日志到独立文件
修改conf/logback.xml,添加自定义appender和关联logger:
- 添加自定义appender:
复制默认nifi-requestappender配置,调整文件名和日志格式,加入%X{logType}捕获MDC中的自定义属性:<appender name="CUSTOM_REQUEST" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${nifi.log.dir}/nifi-custom-request.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${nifi.log.dir}/nifi-custom-request.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> <maxFileSize>100MB</maxFileSize> <maxHistory>30</maxHistory> <totalSizeCap>1GB</totalSizeCap> </rollingPolicy> <encoder> <pattern>%date %level [%thread] %logger{40} %msg | logType=%X{logType}%n</pattern> </encoder> </appender> - 添加logger关联过滤器:
针对自定义过滤器的包路径配置logger,指定使用上述appender:<logger name="com.your.package.YourCustomFilter" level="INFO" additivity="false"> <appender-ref ref="CUSTOM_REQUEST"/> </logger>
3. NiFi OOB功能实现方案
NiFi原生没有直接支持自定义HTTP请求日志属性的OOB功能,仅能通过以下间接方式实现简单需求:
- Jetty访问日志配置:在
conf/nifi.properties中开启nifi.web.jetty.access.log.enabled=true,通过nifi.web.jetty.access.log.format自定义日志格式,可添加请求路径、响应状态码等元数据,但无法基于业务逻辑(如处理器ID有效性)设置logType,仅能做简单的路径/状态映射。 - 原生报告任务:所有原生报告任务(如
MetricsReportingTask)仅监控系统指标,不捕获HTTP请求的业务细节,无法满足需求。
最优方案建议
优先选择自定义Jetty过滤器 + Logback MDC的方案,优势如下:
- 灵活性高:可根据任意请求/响应细节(端点、参数、业务逻辑结果)动态设置
logType; - 集成性好:基于NiFi官方过滤器扩展机制,完美适配Jetty服务器,通过MDC与Logback无缝集成;
- 独立性强:自定义日志文件不干扰原有
nifi-request.log,便于审计与监控。
若不想编写自定义代码,可通过增强Jetty访问日志格式,结合日志解析工具(如ELK)对日志进行事后分类,通过路径、响应状态码映射到logType,但这种方式无法处理复杂业务逻辑判断,仅适用于简单场景。
内容的提问来源于stack exchange,提问作者vigneshwar reddy
相关产品推荐
相关产品推荐

