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

如何配置Quarkus使所有日志(含启动/运行时)输出至文件及控制台?

解决Quarkus日志双输出(控制台+文件)缺失问题

问题描述

我们有多台配置了控制台及文件日志的Quarkus应用,存在以下日志异常:

  • 部分Quarkus产生的错误既未输出至控制台也未写入文件
  • 部分错误仅输出至控制台但未写入文件
    由于应用通常以Linux服务方式启动,控制台日志难以查看,因此需要配置Quarkus,使**所有日志(包括启动时和运行时的错误)**无论以何种方式启动(控制台/服务),都能同时输出至文件和控制台。

当前日志配置

log:
  level: INFO
  handler:
    console:
      "CONSOLE":
        async: false
        enable: true
        format: '%K{level}%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p (%t) [%c.%M()] %s%e%n'
    file:
      "FILE":
        async: false
        enable: true
        format: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p (%t) [%c.%M()] %s%e%n'
        #level: INFO
        path: '/opt/remote-server/logs/remote-server.log'
        rotation:
          file-suffix: .yyyy-MM-dd
          max-backup-index: 999
          max-file-size: 40000000
          rotate-on-boot: true
      "AUDIT":
        async: false
        enable: true
        format: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p (%t) [%c.%M()] %s%e%n'
        #level: INFO
        path: '/opt/remote-server/logs/remote-server-audit.log'
        rotation:
          file-suffix: .yyyy-MM-dd
          max-backup-index: 999
          max-file-size: 40000000
          rotate-on-boot: true
      "DATAAUDIT":
        async: false
        enable: true
        format: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p (%t) [%c.%M()] %s%e%n'
        #level: INFO
        path: '/opt/remote-server/logs/remote-server-dataaudit.log'
        rotation:
          file-suffix: .yyyy-MM-dd
          max-backup-index: 999
          max-file-size: 40000000
          rotate-on-boot: true
  category:
    "com.bs.util.accumulator.AccumulatorLogger":
      level: INFO
      use-parent-handlers: false
      handlers: DATAAUDIT
    "com.bs.audit.Auditor":
      level: INFO
      handlers: AUDIT
    "org.hibernate.sql":
      level: ERROR
      handlers: FILE
    "org.hibernate.type.descriptor.sql":
      level: ERROR
      handlers: FILE
    "io.quarkus.http.access-log":
      level: ERROR
      handlers: FILE
    "com.bs.sdl.async":
      level: ERROR
      handlers: FILE
    "com.bs.sdl.service":
      level: ERROR
      handlers: FILE
    "com.bs":
      level: INFO
      handlers: FILE

未写入文件的错误示例

2023-07-14 20:34:52,659 ERROR [io.qua.ver.htt.run.QuarkusErrorHandler] (executor-thread-2) HTTP Request to /datasync/orchestration/remote failed, error id: bbe963ab-803c-4af1-a1b8-52beccf3287e-1: org.jboss.resteasy.spi.UnhandledException: com.bs.aws.exception.client.KmsClientCreateException: Unable to create an KmsClient after employing the following strategies, [EC2InstanceProfileCredentialsProvider]
	at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:368)
	at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:218)
	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:519)
	at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:261)
	at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:161)
	at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
	at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:164)
	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:247)
	at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:82)
	at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:147)
	at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler$1.run(VertxRequestHandler.java:93)
	at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:576)
	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452)
	at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
	at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: com.bs.aws.exception.client.KmsClientCreateException: Unable to create an KmsClient after employing the following strategies, [EC2InstanceProfileCredentialsProvider]
	at com.bs.aws.factory.EC2InstanceProfileCredentialsProviderStrategyAwsClientFactory.getAwsKmsClient(EC2InstanceProfileCredentialsProviderStrategyAwsClientFactory.java:234)
	at com.bs.aws.api.impl.AwsKmsApi.<init>(AwsKmsApi.java:92)
	at com.bs.aws.api.impl.AwsKmsApi.<init>(AwsKmsApi.java:83)
	at com.bs.aws.api.impl.AwsKmsApi_Bean.create(Unknown Source)
	at com.bs.aws.api.impl.AwsKmsApi_Bean.create(Unknown Source)
	at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:113)
	at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:37)
	at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:34)
	at io.quarkus.arc.impl.LazyValue.get(LazyValue.java:26)
	at io.quarkus.arc.impl.ComputingCache.computeIfAbsent(ComputingCache.java:69)
	at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:34)
	at com.bs.aws.api.impl.AwsKmsApi_Bean.get(Unknown Source)
	at com.bs.aws.api.impl.AwsKmsApi_Bean.get(Unknown Source)
	at com.bs.remote.server.rest.EnterpriseDataSyncOrchestrationREST_Bean.create(Unknown Source)
	at com.bs.remote.server.rest.EnterpriseDataSyncOrchestrationREST_Bean.create(Unknown Source)
	at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:113)
	at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:37)
	at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:34)
	at io.quarkus.arc.impl.LazyValue.get(LazyValue.java:26)
	at io.quarkus.arc.impl.ComputingCache.computeIfAbsent(ComputingCache.java:69)
	at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:34)
	at io.quarkus.arc.impl.ClientProxies.getApplicationScopedDelegate(ClientProxies.java:21)
	at com.bs.remote.server.rest.EnterpriseDataSyncOrchestrationREST_ClientProxy.arc$delegate(Unknown Source)
	at com.bs.remote.server.rest.EnterpriseDataSyncOrchestrationREST_ClientProxy.arc_contextualInstance(Unknown Source)
	at io.quarkus.arc.ClientProxy.unwrap(ClientProxy.java:52)
	at io.quarkus.arc.runtime.ClientProxyUnwrapper.apply(ClientProxyUnwrapper.java:15)
	at io.quarkus.resteasy.common.runtime.QuarkusInjectorFactory$UnwrappingPropertyInjector.inject(QuarkusInjectorFactory.java:74)
	at org.jboss.resteasy.plugins.server.resourcefactory.POJOResourceFactory.createResource(POJOResourceFactory.java:80)
	at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:401)
	at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:69)
	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:492)
	... 15 more

配置调整方案

问题根源分析

  1. 根日志未明确指定同时输出到CONSOLE和FILE处理器,导致未配置category的日志可能只走默认输出
  2. 部分日志类别(如io.quarkus开头的组件)未配置处理器,仅依赖父处理器,但父处理器可能未关联双输出
  3. 启动阶段的日志未配置文件输出,导致早期启动错误无法写入文件
  4. 部分category配置了use-parent-handlers: false且仅指定了专属处理器,阻断了双输出

调整后的完整配置

log:
  level: INFO
  # 根日志同时关联控制台和文件处理器,确保默认所有日志双输出
  handlers: CONSOLE, FILE
  handler:
    console:
      "CONSOLE":
        async: false
        enable: true
        format: '%K{level}%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p (%t) [%c.%M()] %s%e%n'
    file:
      "FILE":
        async: false
        enable: true
        # 开启启动阶段文件日志输出
        enable-at-boot: true
        format: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p (%t) [%c.%M()] %s%e%n'
        path: '/opt/remote-server/logs/remote-server.log'
        rotation:
          file-suffix: .yyyy-MM-dd
          max-backup-index: 999
          max-file-size: 40000000
          rotate-on-boot: true
      "AUDIT":
        async: false
        enable: true
        format: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p (%t) [%c.%M()] %s%e%n'
        path: '/opt/remote-server/logs/remote-server-audit.log'
        rotation:
          file-suffix: .yyyy-MM-dd
          max-backup-index: 999
          max-file-size: 40000000
          rotate-on-boot: true
      "DATAAUDIT":
        async: false
        enable: true
        format: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p (%t) [%c.%M()] %s%e%n'
        path: '/opt/remote-server/logs/remote-server-dataaudit.log'
        rotation:
          file-suffix: .yyyy-MM-dd
          max-backup-index: 999
          max-file-size: 40000000
          rotate-on-boot: true
  category:
    "com.bs.util.accumulator.AccumulatorLogger":
      level: INFO
      use-parent-handlers: true
      handlers: DATAAUDIT, CONSOLE, FILE
    "com.bs.audit.Auditor":
      level: INFO
      handlers: AUDIT, CONSOLE, FILE
    "org.hibernate.sql":
      level: ERROR
      handlers: FILE, CONSOLE
    "org.hibernate.type.descriptor.sql":
      level: ERROR
      handlers: FILE, CONSOLE
    "io.quarkus.http.access-log":
      level: ERROR
      handlers: FILE, CONSOLE
    "com.bs.sdl.async":
      level: ERROR
      handlers: FILE, CONSOLE
    "com.bs.sdl.service":
      level: ERROR
      handlers: FILE, CONSOLE
    "com.bs":
      level: INFO
      handlers: FILE, CONSOLE
    # 新增Quarkus核心组件日志配置,确保错误双输出
    "io.quarkus":
      level: INFO
      handlers: FILE, CONSOLE
    "io.qua.ver.htt.run.QuarkusErrorHandler":
      level: ERROR
      handlers: FILE, CONSOLE

关键调整说明

  1. 根日志添加handlers配置:指定CONSOLE, FILE,确保所有未单独配置的日志默认同时输出到控制台和文件
  2. 开启启动阶段文件日志:为FILE处理器添加enable-at-boot: true,解决启动时错误无法写入文件的问题
  3. 全类别补充双输出处理器:所有自定义category的handlers都添加CONSOLE和FILE,确保专属日志也能双输出
  4. 修复use-parent-handlers设置:将com.bs.util.accumulator.AccumulatorLogger的use-parent-handlers改为true,避免阻断父处理器的双输出逻辑
  5. 新增Quarkus核心组件配置:为io.quarkus及具体错误处理类添加双输出配置,解决示例中QuarkusErrorHandler日志仅输出控制台的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 01:58:10