Как правильно создать тесты производительности для настраиваемого решения для ведения журнала? - PullRequest
1 голос
/ 01 ноября 2019

На работе я взял на себя инициативу создать с нуля библиотеку журналов, которая будет использоваться во внутренних службах и проектах.

На сегодняшний день я создал доказательство концепции с помощью пользовательского класса, extendsPatternLayout и запутывает определенные поля в выходных записях журнала.

Теперь основная задача состоит в том, чтобы утверждать, что производительность приемлема, и мое решение может обрабатывать миллионы записей журнала без пропущенных сообщений.

Я решил написать тесты производительности для своего пользовательского обратного входа, макета обратного входа по умолчанию и 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\"}}");
    }

}

. Тесты запущены, и в выводе я вижу много результатов, но не знаю, какие значения нужно сравнить и как я могу это сделать. утверждать, что если у меня хорошие результаты производительности, это не потому, что сообщения были удалены?

Не могли бы вы дать мне подсказку, как подготовить действительный тест производительности?

1 Ответ

2 голосов
/ 01 ноября 2019

У вас есть асинхронный AsyncAppender appender, который потенциально может отбрасывать сообщения в очереди. Между тем, в тесте JMH ожидается, что код в аннотированном методе @Benchmark выполняется синхронно, чтобы вычислить, сколько времени это займет. Это не сработает.

IMO, вы пытаетесь протестировать слишком много вещей одновременно, например, весь стек Logback. Если вы разработали собственный класс макета LoggingRulesApplicator, начните с написания bechmark JMH именно для этого класса.

Взгляните на существующие тесты log4j2 JMH . Настройка там упрощается благодаря использованию NOOP-приложения, которое вам, вероятно, также понадобится.

...