Wie schalte ich die Ausgabe von Shutdown-Hooks in Gradle-Boot-Tests aus?


13

Sie können ein Projekt von start.spring.io zu diesem Problem unter https://start.spring.io/starter.zip?type=gradle-project&language=java&bootVersion=2.2.5.RELEASE&baseDir=demo&groupId=com.example&artifactId=demo&name generieren = demo & description = Demo% 20project% 20for% 20Spring% 20Boot & packageName = com.example.demo & package = jar & javaVersion = 1.8 & dependencies = h2, data-jpa, web

Ich habe eine SpringBoot-Anwendung mit mehreren Modulen, die mit Gradle erstellt wurde. Es gibt eine Reihe von SpringBoot-Integrationstests. Wenn ich einen Build mache, erhalte ich eine Ausgabe vom Herunterfahren von SpringBoot auf die Konsole, wie unten gezeigt. Wie schalte ich diesen Ausgang aus?

± |master 1 {1} S:3 U:10 ✗|  ./gradlew build

> Task :core:test
2020-02-01 11:20:33.529  INFO 24114 --- [extShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2020-02-01 11:20:33.531  INFO 24114 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2020-02-01 11:20:33.538  INFO 24114 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.

> Task :email:test
2020-02-01 11:20:43.820  INFO 24150 --- [extShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2020-02-01 11:20:43.820  INFO 24150 --- [extShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2020-02-01 11:20:43.822  INFO 24150 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-2 - Shutdown initiated...
2020-02-01 11:20:43.822  INFO 24150 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2020-02-01 11:20:43.830  INFO 24150 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
2020-02-01 11:20:43.830  INFO 24150 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-2 - Shutdown completed.

> Task :security:test
2020-02-01 11:20:54.941  INFO 24188 --- [extShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2020-02-01 11:20:54.944  INFO 24188 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2020-02-01 11:20:54.952  INFO 24188 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.1.1/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 46s
57 actionable tasks: 54 executed, 3 up-to-date

Als Referenz erzeugt eine aus start.spring.io mit gradle erstellte Anwendung keine Ausgabe auf dem Bildschirm

./gradlew build

BUILD SUCCESSFUL in 779ms
5 actionable tasks: 5 up-to-date

Stattdessen wird die Ausgabe in platziert build/reports/

In meinem Fall habe ich KEINE Änderungen an der Protokollierungskonfiguration vorgenommen, die mit dem Start geliefert wird. Es gibt keine logback.xml oder Änderungen an der application.yml für die Protokollierungsstufen. Ich erwarte, dass Gradle das System und den Systemfehler erfasst und an das System sendet, build/reports/aber einige Ausgänge scheinen dem System zu entgehen.


2
Anpassen der Protokollierungsstufe für diese Pakete oder Klassen auf unten INFO(oder vollständiges Entfernen).
Kayaman

2
Das sind INFOebene Protokollzeilen. Wie Sie sehen, stammen sie aus den Shutdown-Hooks und landen dort, wo die Protokollierung konfiguriert ist. Theoretisch könnten die Nachrichten an einem anderen Ort als beabsichtigt landen, da sich die Protokollierungskonfiguration ändert und die Hooks anschließend asynchron ausgeführt werden. Daher werden diese Zeilen standardmäßig an die Konsole gesendet, da die vorherige Konfiguration entladen wurde. Könnte sein.
Kayaman

1
Können Sie bitte Ihre Testklasse und auch Ihre Hauptanwendungsklasse hinzufügen? Und irgendwelche relevanten application.properties/yml, die mit der Datenquellenkonfiguration verknüpft sind?
Darren Forsythe

3
Es kann sein, dass die Shutdown-Hooks auftreten, wenn die Gradle-Test-Worker-Prozesse nach dem Abreißen ihrer Ausgabeumleitung heruntergefahren werden. Das könnte eine Gradle / Gradle-Ausgabe wert sein, um die Diskussion zu eröffnen.
Eskatos

2
Idealerweise wird der Federstiefel in Ihren Tests heruntergefahren, ohne sich auf JVM-Abschalthaken verlassen zu müssen. Dies wäre ein Federproblem.
Eskatos

Antworten:


4

@eskatos ist richtig. Der Protokollierungsmanager wird heruntergefahren, nachdem der Testfall ausgeführt wurde, bevor der Arbeitsprozess heruntergefahren wird. Alle Shutdown-Hooks werden ausgeführt, wenn der Worker-Prozess heruntergefahren wird, und werden zurück zur Konsole umgeleitet.

Da diese Nachrichten durch Spring Boot generiert werden, ist es am besten, die Shutdown-Nachrichten mithilfe der XML-Konfiguration für den Logback-Test zu filtern.

So etwas wie logback-test.xml in src / test / resources

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
            <evaluator> <!-- defaults to type ch.qos.logback.classic.boolex.JaninoEventEvaluator -->
                <expression>return event.getThreadName().contains("ShutdownHook");</expression>
            </evaluator>
            <OnMismatch>NEUTRAL</OnMismatch>
            <OnMatch>DENY</OnMatch>
        </filter>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

build.gradle

testCompile 'org.codehaus.janino:janino'

1
IMO die bisher beste Antwort auf diese Frage.
Steffen Harbich

3

Man kann die Ausgabe mit deaktivieren oder entscheiden, was von einer Aufgabe protokolliert werden soll, um das stdout / stderr der Test-JVM zu steuern:TestLoggingContainer testLogging.showStandardStreams = false onOutputTest

apply plugin: 'java'

test {

    // show standard out and standard error of the test JVM on the console
    // can be used to disable the console output:
    testLogging.showStandardStreams = true

    // listen to standard out and standard error of the test JVM
    // can be used to make the logging optional:
    onOutput { descriptor, event ->
        logger.lifecycle("Test: " + descriptor + " produced standard out/err: " + event.message)
    }
}

Diese Streams sind TestLogEvent STANDARD_OUT& STANDARD_ERROR, die von der JVM kommen. Wenn man einen event.messageGehalt bestimmen kann extShutdownHook, kann man die Protokollierung überspringen.


sehen Sie können ein Projekt von start.spring.io zu diesem Thema von erzeugen start.spring.io/... das Problem zu reproduzieren
ams

Dies ist wahrscheinlich kein Problem, da dies INFOdie Standardprotokollierungsstufe für Spring ist. man kann andere Log-Level einstellen, z. logging.level.org.springframework=TRACEals Umgebungsvariable.
Martin Zeitler

1
Ich glaube, dass Shutdown-Hook-Protokolle außerhalb der Testaufgabe generiert werden. Könnten Sie Ihre Antwort aktualisieren, um zu zeigen, wie Shutdown-Hook-Nachrichten gefiltert werden können? Ich denke, der beste Ort, um diese Nachrichten zu filtern, ist dort, wo sie generiert werden, also sowieso im Frühjahr.
Sagar Veeram

3

Ich könnte die federdatenspezifische Testprotokollierung (basierend auf diesem Federstarter ) ausblenden application.properties, indem ich src / test / resources Folgendes hinzufüge :

logging.level.root=ERROR

logging.level.org.springframeworkhat keine Auswirkung auf zB com.zaxxer.hikariLogger, aber Sie haben hier flexible Optionen .

( root=ERRORist wie der "Vorschlaghammer Ansatz").

( src/main/resourcesist auch möglich, wirkt sich aber nicht nur beim Test, sondern auch zur Laufzeit der Anwendung aus) ( application.propertiesist nur einer von vielen möglichen "Speicherorten" für diese Eigenschaft ... siehe auch: https://docs.spring.io/spring-boot/ docs / current / reference / html / appendix-application-properties.html )

Damit bekomme ich eine "stille" Gradle-Ausgabe, auch auf einem clean build:

$ ./gradlew clean build

BUILD SUCCESSFUL in 10s
7 actionable tasks: 7 executed

0

Gradle hat einen leisen Modus.

./gradlew build -q

Sie benötigen jedoch noch Informationen zu den Tests. Sie können Jacoco und Sonarqube verwenden. Es hat bei mir hier und hier funktioniert .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.