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

如何在Quarkus中通过Slf4j+Splunk HEC发送无包装结构化日志?

解决方案:直接输出结构化JSON日志到Splunk

你遇到的问题是Quarkus默认日志格式会把JSON内容包装在message字段里,这个需求完全可以实现,有两种可行方向:从应用端(Quarkus)调整日志输出格式,或者在Splunk端解析嵌套的JSON内容。

一、从Quarkus端直接输出纯JSON日志(推荐)

这是从源头解决的方式,让应用直接输出你需要的结构化JSON,无需Splunk额外处理,日志结构更清晰、处理效率更高。

1. 方式一:利用日志框架的JSON编码器(以Logback为例)

Quarkus默认集成Logback,你可以通过配置自定义日志输出结构:

  • 首先添加Logstash Logback编码器依赖(Maven):
<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
</dependency>
  • 在src/main/resources下创建logback.xml,配置只输出你需要的JSON字段:
<configuration>
    <!-- 替换为你实际发送到Splunk的Appender,比如Socket/HTTP Appender -->
    <appender name="SPLUNK" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
            <providers>
                <pattern>
                    <pattern>
                        {
                            "provider": "%X{provider}",
                            "price": "%X{price}"
                        }
                    </pattern>
                </pattern>
            </providers>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="SPLUNK"/>
    </root>
</configuration>
  • 在代码中通过MDC传递字段值:
@Slf4j
public class PriceService {
    public void logTransaction(String provider, String price) {
        // 将字段放入MDC,日志编码器会自动读取并生成JSON
        MDC.put("provider", provider);
        MDC.put("price", price);
        // 日志内容可留空,因为我们靠MDC生成字段
        log.info("");
        // 清理MDC,避免线程复用导致数据污染
        MDC.clear();
    }
}

2. 方式二:简化日志格式,直接输出JSON字符串

如果不想引入额外依赖,可以修改Quarkus日志配置,让它只输出日志消息内容:

  • 在application.properties中添加:
# 让日志只输出message部分,不附加severity、时间等包装字段
quarkus.log.console.format=%m%n
# 如果用的是其他Appender(比如Splunk HTTP Appender),对应调整其format
  • 在代码中将对象序列化为JSON字符串后直接打印:
@Slf4j
public class PriceService {
    private final ObjectMapper objectMapper = new ObjectMapper();

    public void logTransaction(String provider, String price) throws JsonProcessingException {
        // 构造日志对象
        TransactionLog logObj = new TransactionLog(provider, price);
        // 序列化为JSON字符串
        String jsonLog = objectMapper.writeValueAsString(logObj);
        // 直接输出JSON
        log.info(jsonLog);
    }

    // 定义日志实体类
    static class TransactionLog {
        public String provider;
        public String price;

        public TransactionLog(String provider, String price) {
            this.provider = provider;
            this.price = price;
        }
    }
}

二、在Splunk端解析嵌套JSON

如果不想修改应用代码,可以配置Splunk自动解析message字段中的JSON内容,将嵌套字段提升为顶层字段:

  1. 找到你的Splunk数据输入对应的源类型(Source Type)
  2. 在Splunk的$SPLUNK_HOME/etc/system/local/目录下创建/修改props.conf:
[你的源类型名称]
# 开启JSON索引提取
INDEXED_EXTRACTIONS = json
# 关闭默认的键值对提取,避免冲突
KV_MODE = none
# 禁用二进制检查
NO_BINARY_CHECK = true
# 关闭行合并,每条日志单独处理
SHOULD_LINEMERGE = false
  1. 重启Splunk服务,之后搜索时就能直接用provider=XX、price=12.02这样的条件查询,也能基于这些字段计算KPI。

这种方式不会去除原始的包装结构,但能满足你搜索和计算KPI的需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 19:30:55