миграция log4j в log4j2 с приложением-службой TeamCity - PullRequest
0 голосов
/ 15 января 2019

Мы переходим с log4j на log4j2 для нашей инфраструктуры непрерывной интеграции. Поскольку нашей кодовой базой является Java, мы используем testNg, у которого нет собственного бегуна в TeamCity, поэтому, чтобы иметь возможность аккуратно сложить установочный код, тесты и их шаги, мы добавили TeamCityLogger. Этот регистратор отвечает за добавление сообщений службы TeamCity , где это необходимо. Эти сообщения требуют другого форматирования, чем в обычных строках журнала. Мы также не хотим видеть их при локальном запуске наших тестов. Для этого у нас был следующий log4j.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/1.2/apidocs/org.apache.logging.log4j/xml/doc-files/log4j.dtd">
<log4j:configuration>
    <appender name="console" class="org.apache.logging.log4j.ConsoleAppender">
        <layout class="org.apache.logging.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%d{ABSOLUTE}][%t] %-5p %c{1}(%L) - %m%n"/>
        </layout>
        <filter class="org.apache.logging.log4j.varia.LevelRangeFilter">
            <param name="levelMin" value="INFO" />
            <param name="levelMax" value="ERROR" />
        </filter>
    </appender>
    <appender name="teamcity" class="org.apache.logging.log4j.ConsoleAppender">
        <layout class="org.apache.logging.log4j.PatternLayout">
            <param name="ConversionPattern" value="%m%n%n"/>
        </layout>
        <filter class="org.apache.logging.log4j.varia.LevelRangeFilter">
            <param name="levelMin" value="DEBUG" />
            <param name="levelMax" value="DEBUG" />
        </filter>
        <filter class="org.apache.logging.log4j.varia.StringMatchFilter">
            <param name="StringToMatch" value="##teamcity" />
            <param name="AcceptOnMatch" value="true" />
        </filter>

        <filter class="org.apache.logging.log4j.varia.DenyAllFilter"/>
    </appender>
    <appender name="file" class="org.apache.logging.log4j.FileAppender">
        <param name="File" value="log4j.log"/>
        <param name="Append" value="false"/>
        <param name="ImmediateFlush" value="true"/>
        <layout class="org.apache.logging.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%d{ABSOLUTE}] %m%n"/>
        </layout>
    </appender>
    <root>
        <priority value ="debug" />
        <appender-ref ref="console" />
        <appender-ref ref="teamcity" />
        <appender-ref ref="file" />
    </root>
</log4j:configuration>

Наш TeamCityLogger довольно прост:

public class TeamcityLogger {
    public static Logger _logger = LogManager.getLogger("TeamcityLogger");

    public static void tc_openBlock(String blockLabel){
        String escapedLabel = tc_escaped(blockLabel);
        _logger.debug(String.format("##teamcity[blockOpened name='<%s>']", escapedLabel));
    }

    public static void tc_closeBlock(String blockLabel){
        String escapedLabel = tc_escaped(blockLabel);
        _logger.debug(String.format("##teamcity[blockClosed name='<%s>']", escapedLabel));
    }
}

где tc_escaped выполняет простое экранирование предоставленной строки в соответствии с рекомендациями JetBrains.

Вокруг кода, который мы хотели бы сложить, мы добавляем сообщения blockOpen и blockClose TeamCity, очень похожие на:

public class SomeClass {
    private static Logger _logger = LogManager.getLogger(SomeClass.class.getSimpleName());

    public void MethodToFold(){
        TeamcityLogger.tc_openBlock("FoldMe");
        _logger.info("I'm doing something");
        _logger.info("I'm doing something else");
        TeamcityLogger.tc_closeBlock("FoldMe");
    }
}

Это создаст хороший консольный журнал

[12:56:55,977][main] INFO  SomeClass(17) - I'm doing something
[12:56:55,995][main] INFO  SomeClass(18) - I'm doing something else

При запуске в TeamCity журнал сборки будет выглядеть так:

[19:51:04] :     [Step 3/3] <FoldMe>
[19:51:04] :         [<FoldMe>] 
[19:51:04] :         [<FoldMe>] [12:56:55,977][main] INFO  SomeClass(17) - I'm doing something
[19:51:04] :         [<FoldMe>] [12:56:55,995][main] INFO  SomeClass(18) - I'm doing something else
[19:51:05] :     [Step 3/3]

Наш новый log4j2.xml выглядит так:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Appenders>
        <Console name="console">
            <PatternLayout pattern="[%d{ABSOLUTE}][%t] %-5level %c{1}(%L) - %highlight{%m%n}"/>
        </Console>
        <Console name="teamcity">
            <PatternLayout pattern="%m%n%n"/>
            <Filters>
                <RegexFilter regex="##teamcity" onMatch="ACCEPT" onMismatch="DENY"/>
                <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY" />
            </Filters>
        </Console>
        <File name="file" immediateFlush="true" fileName="log4j.log" append="false">
            <PatternLayout pattern="[%d{ABSOLUTE}] %m%n"/>
        </File>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="console"/>
            <AppenderRef ref="teamcity"/>
            <AppenderRef ref="file"/>
        </Root>
    </Loggers>
</Configuration>

Что хорошо выглядит на консоли, но в TeamCity загруженный журнал сборки выглядит как

[13:06:04] :     [Step 3/3] [13:06:04,089][main] INFO  SomeClass(17) -  [32mI'm doing something
[13:06:04] :     [Step 3/3]  [m[13:06:04,178][main] INFO  SomeClass(18) -  [32mI'm doing something else

Это означает, что у нас больше нет складывания.

Изменение конфигурации с дополнительной ссылкой на регистратор как

<Loggers>
    <Logger name="TeamcityLogger">
        <AppenderRef ref="teamcity"/>
    </Logger>
    <Root level="info">
        <AppenderRef ref="console"/>
        <AppenderRef ref="teamcity"/>
        <AppenderRef ref="file"/>
    </Root>
</Loggers>

Добавляет дополнительную строку журнала:

[13:19:12,281][main] DEBUG TeamcityLogger(17) -

В журнал TeamCity. Я также попытался настроить уровень корневого журнала для отладки и добавить <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" /> в консоль appender, но это снова удалило мое сворачивание.

Любые предложения о том, как должен выглядеть xml, чтобы это работало?

...