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

Quarkus中JVM构建与Native构建的CloudWatch指标日志行为差异问题

Quarkus中JVM构建与Native构建的CloudWatch指标日志行为差异问题

看起来你遇到的是Quarkus Native模式下AWS Embedded Metrics SDK无法正确输出指标日志的问题,我来帮你梳理下可能的原因和解决思路:

先明确你的问题场景

  • 在dev环境和JVM构建的Lambda镜像中,CloudWatch指标日志输出完全正常
  • 但Native构建的镜像运行时,指标日志总是输出空对象{}
  • 已经尝试将MetricsService设置为运行时初始化,但没有效果

你的核心代码和构建配置如下:

MetricsService核心代码

public class MetricsService {
    MetricsLogger metricsLogger;

    public MetricsService() {
        var namespace = ConfigProvider.getConfig()
                .getOptionalValue("aws.emf.namespace", String.class)
                .orElse("OceanAnalytics");
        this.metricsLogger = new MetricsLogger().setNamespace(namespace);
    }
}

构建命令

JVM构建:

./mvnw clean package

Native构建:

./mvnw clean package -Dnative=true

完整pom.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <properties>
        <compiler-plugin.version>3.13.0</compiler-plugin.version>
        <maven.compiler.release>17</maven.compiler.release>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
        <quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
        <quarkus.platform.version>3.18.3</quarkus.platform.version>
        <aws.sdk.version>2.29.45</aws.sdk.version>
        <embedded.metrics.version>4.2.0</embedded.metrics.version>
        <lombok.version>1.18.34</lombok.version>
        <surefire-plugin.version>3.5.2</surefire-plugin.version>
        <skipITs>true</skipITs>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>${quarkus.platform.group-id}</groupId>
                <artifactId>${quarkus.platform.artifact-id}</artifactId>
                <version>${quarkus.platform.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>${aws.sdk.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-rest</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-amazon-lambda-rest</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-jackson</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-rest-jackson</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-hibernate-reactive-panache</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-reactive-pg-client</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-arc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>secretsmanager</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>software.amazon.awssdk</groupId>
                    <artifactId>apache-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>url-connection-client</artifactId>
        </dependency>
        <dependency>
            <groupId>software.amazon.cloudwatchlogs</groupId>
            <artifactId>aws-embedded-metrics</artifactId>
            <version>${embedded.metrics.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>${quarkus.platform.group-id}</groupId>
                <artifactId>quarkus-maven-plugin</artifactId>
                <version>${quarkus.platform.version}</version>
                <extensions>true</extensions>
                <executions>
                    <execution>
                        <goals>
                            <goal>build</goal>
                            <goal>generate-code</goal>
                            <goal>generate-code-tests</goal>
                            <goal>native-image-agent</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${compiler-plugin.version}</version>
                <configuration>
                    <parameters>true</parameters>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${surefire-plugin.version}</version>
                <configuration>
                    <systemPropertyVariables>
                        <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                        <maven.home>${maven.home}</maven.home>
                    </systemPropertyVariables>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>${surefire-plugin.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <systemPropertyVariables>
                        <native.image.path>${project.build.directory}/${project.build.finalName}-runner
                        </native.image.path>
                        <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                        <maven.home>${maven.home}</maven.home>
                    </systemPropertyVariables>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.diffplug.spotless</groupId>
                <artifactId>spotless-maven-plugin</artifactId>
                <version>2.43.0</version>
                <configuration>
                    <java>
                        <palantirJavaFormat>
                            <version>2.39.0</version>
                            <style>PALANTIR</style>
                        </palantirJavaFormat>
                    </java>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <id>native</id>
            <activation>
                <property>
                    <name>native</name>
                </property>
            </activation>
            <properties>
                <skipITs>false</skipITs>
            </properties>
        </profile>
    </profiles>
</project>

可能的原因和解决思路

1. 原生镜像元数据缺失(最可能的原因)

AWS Embedded Metrics SDK内部大量使用反射和动态序列化来构建指标对象,而Quarkus Native构建时会做静态分析,把未被显式引用的类、反射调用等都裁剪掉。你只延迟初始化了自己的MetricsService,但SDK内部的很多类(比如指标实体类、序列化器)可能没被正确包含。

解决方案:用Native Image Agent自动生成元数据
这是Quarkus推荐的解决Native模式下反射/序列化问题的标准方法:

# 1. 启动带Agent的开发模式,Agent会自动捕获所有反射、序列化操作
./mvnw quarkus:dev -Dquarkus.native-agent.enabled=true
# 2. 调用你的Lambda接口,触发MetricsLogger输出指标的逻辑(比如调用一个产生指标的API)
# 3. 停止dev服务,Agent会在target/native-image-agent-output目录生成配置文件
# 4. 复制配置文件到Native构建读取的目录
cp -r target/native-image-agent-output/* src/main/resources/META-INF/native-image/
# 5. 重新构建Native镜像
./mvnw clean package -Dnative=true

2. Jackson序列化的Native兼容问题

Quarkus的Jackson在Native模式下需要额外配置才能正确序列化动态对象,而AWS Embedded Metrics依赖Jackson生成指标JSON。

解决方案:配置Jackson的Native支持
在src/main/resources/application.properties中添加:

# 让Jackson自动注册Native模式下的序列化/反序列化器
quarkus.jackson.native.add-serializers=true
quarkus.jackson.native.add-deserializers=true
# 确保序列化时包含所有字段
quarkus.jackson.serialization.include=ALWAYS

3. 扩展延迟初始化的范围

可能不止你的MetricsService,AWS Embedded Metrics的整个包都需要延迟初始化,因为它的很多类是动态加载的。

解决方案:修改Native构建参数
在pom.xml的native profile中添加:

<profile>
    <id>native</id>
    <activation>
        <property>
            <name>native</name>
        </property>
    </activation>
    <properties>
        <skipITs>false</skipITs>
        <quarkus.native.initialize-at-run-time>my.package.MetricsService,software.amazon.cloudwatchlogs.awsembeddedmetrics</quarkus.native.initialize-at-run-time>
    </properties>
</profile>

4. 版本兼容性检查

确认你的Quarkus版本、AWS SDK版本和AWS Embedded Metrics版本之间有没有已知的Native模式兼容问题。如果上面的方法都无效,可以尝试升级AWS Embedded Metrics到最新稳定版,或者调整Quarkus版本到匹配的兼容版本。


备注:内容来源于stack exchange,提问作者Karan Ahlawat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 20:17:57