【问题标题】:How to correctly create performance tests for a custom logging solution?如何为自定义日志记录解决方案正确创建性能测试?
【发布时间】:2023-03-18 20:35:02
【问题描述】:

在工作中,我主动从头创建了一个日志库,以供内部服务和项目使用。

迄今为止,我已经使用自定义类创建了一个概念证明,该类extends PatternLayout 并混淆了输出日志条目中的某些字段。

现在的主要任务是断言性能是可以接受的,并且我的解决方案可以处理数百万个日志条目而不会丢失消息。

我决定为我的自定义 logback、默认 logback 布局和 Log4j2 编写性能测试,以便比较输出结果。 我已经使用jmh 进行了单元测试。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <appender name="FILE_APPLY_RULES" class="ch.qos.logback.core.FileAppender">
        <file>logs\log.txt</file>
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="com.ingenico.epayments.logging.rule.LoggingRulesApplicator">
                <pattern>%msg%n</pattern>
                <applyRules>true</applyRules>
                <loggingRules>src/test/resources/logging-rules.json</loggingRules>
            </layout>
        </encoder>
    </appender>

    <appender name="ASYNC_FILE_APPLY_RULES" class="ch.qos.logback.classic.AsyncAppender">
        <discardingThreshold>0</discardingThreshold>
        <appender-ref ref="FILE_APPLY_RULES" />
        <queueSize>256</queueSize>
        <includeCallerData>false</includeCallerData>
        <neverBlock>true</neverBlock>
    </appender>

    <root level="INFO">
        <appender-ref ref="ASYNC_FILE_APPLY_RULES" />
    </root>

</configuration>

@Slf4j
public class LogbackTest {

    @Test
    public void launchBenchmark() throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(this.getClass().getName() + ".*")
                .timeUnit(TimeUnit.MICROSECONDS)
                .warmupTime(TimeValue.seconds(1))
                .warmupIterations(2)
                .measurementTime(TimeValue.seconds(1))
                .measurementIterations(2)
                .threads(2)
                .forks(1)
                .shouldFailOnError(true)
                .shouldDoGC(true)
                .addProfiler(StackProfiler.class)
                .addProfiler(HotspotRuntimeProfiler.class)
                .build();
        new Runner(opt).run();
    }

    @BenchmarkMode(Mode.All)
    @Measurement(iterations = 200, time = 200, timeUnit = MILLISECONDS)
    @Benchmark
    public void logBenchmark() {
        log.info("{\"id\":\"12345\",\"cardData\":{\"bar\":\"bar\",\"foo\":\"foo\",\"number\":\"number\"}}");
    }

}

测试已运行,在输出中,我看到了很多结果数字,但我不知道应该比较哪些值以及如何断言如果我有良好的性能结果,这不是因为消息已被丢弃?

您能否告诉我如何准备有效的性能测试?

【问题讨论】:

    标签: java logging performance-testing benchmarking jmh


    【解决方案1】:

    您有一个异步 AsyncAppender 附加程序,它可能会丢弃队列中的消息。同时,JMH 基准测试期望@Benchmark 注释方法中的代码同步执行以计算需要多长时间。这行不通。

    IMO 您试图一次测试太多东西,例如整个 Logback 堆栈。如果您开发了一个自定义布局类LoggingRulesApplicator,首先为这个类编写一个 JMH 基准测试。

    看看existing log4j2 JMH benchmarks。使用 NOOP appender 简化了那里的设置,您可能也应该拥有它。

    【讨论】:

    • 嗨,卡罗尔,谢谢,我更新了我的问题。我知道我无法摆脱掉线,但我怎么能断言良好的性能结果不是因为掉线。我也相信一定有办法以某种方式比较日志记录
    • 感觉就像您正在尝试编写端到端基准测试来证明您的解决方案可以达到理想的 SLA 水平。为您的代码片段编写微基准测试,例如只是布局,或者在目标服务器上启用日志记录,对您的应用程序执行完整的端到端性能测试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多