You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jersey LoggingFeature无法记录完整响应体问题求助

Jersey LoggingFeature响应体截断问题排查与解决

问题描述

我正在构建一个调用外部API的端点,需要把所有请求体记录到终端,但遇到Jersey的LoggingFeature无法完整记录响应体的问题——日志里的响应体在中间被截断了。我试过调整日志级别、Verbosity参数,把maxEntitySize设成很大的值,也尝试过把日志输出到文件,但问题依然存在。我刚接触Kotlin/Java技术栈,可能漏了关键配置,求解决方案。

日志示例

INFO  [2022-10-06 13:54:04,261] se.bla.bla.bla.clients.BlaClientImpl: 1 * Sending client request on thread dw-18 - GET /api/bla/log/98014384
1 > GET https://url.com/2574339575
1 > Accept: application/json
1 > Authorization: Bearer tokenstuff

INFO  [2022-10-06 13:54:04,475] se.bla.bla.bla.clients.BlaClientImpl: 1 * Client response received on thread dw-18 - GET /api/bla/log/98014384
1 < 200
1 < Cache-Control: no-cache
1 < Content-Type: application/json; charset=utf-8
1 < Date: Thu, 06 Oct 2022 13:54:04 GMT
1 < Etag: Yee
1 < Server-Response-Time: 169.44395400000002
1 < Transfer-Encoding: chunked
1 < Vary: Origin
1 < X-Request-Id: Woo
1 < X-Runtime: 0.169337
{example1: "2134123123",example2: "2134123123",example3: "2134123123",example4: "2134123123",example5: "2134123123",example6: "2134123123",example7: "2134123123",example8: "2134123123",example9: "2134123123",example10: "2134123123",example11: "2134123123",example12: "2134123123",example13: "2134123123",example14: "2134123123",example15: "2134123123",example16: "2134123123",example17: "2134123123",example18: "21341

当前Logger注册代码

val restlog = getLogger(BlaClientImpl::class.java.name)
restlog.addHandler(FileHandler("rest.log", 83886080, 1))
val requestBuilder =
    client
        .register(
            LoggingFeature(
                restlog,
                Level.INFO,
                LoggingFeature.Verbosity.PAYLOAD_ANY,
                83886080
            )
        )

解决方案

1. 调整FileHandler的日志格式化规则

默认的FileHandler可能存在单条日志长度限制,即使LoggingFeature的maxEntitySize设得足够大,也会被日志处理器截断。可以自定义格式化器,避免单行截断:

val customFormatter = object : SimpleFormatter() {
    override fun format(lr: LogRecord): String {
        val sb = StringBuilder()
        sb.append(String.format("%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS %1$Tp ", lr.millis))
        sb.append(String.format("%s%n", lr.loggerName))
        sb.append(String.format("%s: %s%n", lr.level.localizedName, lr.message))
        lr.thrown?.let {
            val sw = StringWriter()
            it.printStackTrace(PrintWriter(sw))
            sb.append(sw.toString())
        }
        return sb.toString()
    }
}
val fileHandler = FileHandler("rest.log", 83886080, 1)
fileHandler.formatter = customFormatter
restlog.addHandler(fileHandler)

2. 自定义拦截器处理分块响应

日志显示响应采用Transfer-Encoding: chunked,Jersey原生LoggingFeature处理分块流时可能因流提前关闭导致截断。可以注册自定义WriterInterceptor完整记录响应:

class FullLoggingInterceptor(private val logger: Logger) : WriterInterceptor {
    override fun aroundWriteContext(context: WriterInterceptorContext) {
        val loggingStream = LoggingOutputStream(context.outputStream, logger)
        context.outputStream = loggingStream
        try {
            context.proceed()
        } finally {
            loggingStream.flush()
        }
    }

    private inner class LoggingOutputStream(
        private val delegate: OutputStream,
        private val logger: Logger
    ) : OutputStream() {
        private val buffer = ByteArrayOutputStream()

        override fun write(b: Int) {
            buffer.write(b)
            delegate.write(b)
        }

        override fun flush() {
            logger.info(buffer.toString(StandardCharsets.UTF_8.name()))
            buffer.reset()
            delegate.flush()
        }

        override fun close() {
            flush()
            delegate.close()
        }
    }
}

注册该拦截器:

client.register(FullLoggingInterceptor(restlog))

3. 检查日志框架全局限制

如果使用SLF4J+Logback等日志框架,全局配置可能限制了单条日志长度。比如修改logback.xml中的encoder配置,取消或调大长度限制:

<encoder>
    <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    <maxLength>1000000</maxLength> <!-- 设置足够大的值 -->
</encoder>

内容的提问来源于stack exchange,提问作者Menyten

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 13:50:26