New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Flyway ignoring logback logging configuration #3651
Comments
Same issue here, it stopped working on 9.16.2 version, probably because of that change 8e3af28#diff-a5cc1a4d8df15413b1af4e826332b71fc715d8a654cbc020bcf3be437a9df22dR64-R67 |
I have this issue as well.
https://documentation.red-gate.com/fd/loggers-184127516.html |
Spring Boot users are hitting this problem too. I believe that @szymonprz is correct and the problem is due to a failure to detect that SLF4J is available. Here's a minimal project that reproduces the problem by calling flyway/flyway-core/src/main/java/org/flywaydb/core/internal/util/FeatureDetector.java Lines 57 to 67 in 8e3af28
Lines 65 and 66 are the root of the problem. SLF4J doesn't use the I think lines 57 - 67 could be replaced with the following: slf4jAvailable = ClassUtils.isPresent("org.slf4j.LoggerFactory", classLoader)
&& !(LoggerFactory.getILoggerFactory() instanceof NOPLoggerFactory); This is compatible with SLF4J 1.7.x and 2.0.x as |
This should be fixed by my PR #3731 |
For me, this did not fix the issue. As far as I am aware, with versions prior to 1.8, slf4j did not use the service loader to find logging implementations. Instead, it looks for With slf4j version 1.7.36 and an implementation, I get the following results: var classLoader = getClass().getClassLoader();
ClassUtils.isPresent("org.slf4j.Logger", classLoader); // true
ClassUtils.isPresent("org.slf4j.impl.StaticLoggerBinder", classLoader); // true
StreamSupport.stream(ServiceLoader.load(classOf[Logger], classLoader).spliterator, false).count(); // 0
StreamSupport.stream(ServiceLoader.load(classOf[Logger], classLoader).spliterator, false).allMatch(_.isInstanceOf[NOPLogger]); // true
ClassUtils.isImplementationPresent("org.slf4j.spi.SLF4JServiceProvider", classLoader); // false What if the current code: slf4jAvailable = ClassUtils.isPresent("org.slf4j.Logger", classLoader)
&& ClassUtils.isPresent("org.slf4j.impl.StaticLoggerBinder", classLoader)
&& !StreamSupport.stream(ServiceLoader.load(org.slf4j.Logger.class, classLoader)
.spliterator(), false).allMatch(logger -> logger instanceof org.slf4j.helpers.NOPLogger);
// Versions 1.8 and later use a ServiceLocator to bind to the implementation
slf4jAvailable |= ClassUtils.isImplementationPresent("org.slf4j.spi.SLF4JServiceProvider", classLoader); ... was changed to this: boolean slf4jIsPresent = ClassUtils.isPresent("org.slf4j.Logger", classLoader);
// Versions 1.7 and prior use a fixed class name to bind to the implementation
boolean oldImplementationIsPresent = ClassUtils.isPresent("org.slf4j.impl.StaticLoggerBinder", classLoader)
&& !(LoggerFactory.getILoggerFactory() instanceof NOPLoggerFactory);
// Versions 1.8 and later use a ServiceLocator to bind to the implementation
boolean newImplementationIsPresent = ClassUtils.isImplementationPresent("org.slf4j.spi.SLF4JServiceProvider", classLoader)
&& !StreamSupport.stream(ServiceLoader.load(org.slf4j.Logger.class, classLoader).spliterator(), false)
.allMatch(logger -> logger instanceof org.slf4j.helpers.NOPLogger);
slf4jAvailable = slf4jIsPresent && (oldImplementationIsPresent || newImplementationIsPresent); Would this work? But the idea of @wilkinsona seems simpler and I did not even test this code. |
This issue has been fixed in the latest version of Flyway, so closing this ticket. |
I am sorry to bother again, but I just tested version 10.3.0 (the latest version as far as I am aware) and still see this issue. In the FeatureDetector I still see the broken code that does and cannot work with slf4j 1.7.x. In the attachment (FlywaySlf4j.zip) you can find a small Maven project that you can use to verify it for yourself. If you use version 2.0.9 of slf4j, then the output looks as expected:
With version 1.7.36, the logging output of Flyway looks different, because it does not recognize that a slf4j logger is available and uses a different one:
Please consider what @wilkinsona wrote in April or what I wrote in October. Of course we can always force a specific logger via configuration, but it would be nice if the |
Which version and edition of Flyway are you using?
Communtiy Edition version 9.16.3
Which client are you using? (Command-line, Java API, Maven plugin, Gradle plugin)
Java API
What did you do? (Please include the content causing the issue, any relevant configuration settings, the SQL statement(s) that failed (if any), and the command you ran)
Using the Java API to run the migrate command in a project that has slf4j-api and logback-classic on the classpath and a logback.xml in the resources:
logback.xml:
What did you expect to see?
Flyway logs should use my log format as specified in logback.xml. This is the behavior up to and including 9.16.1.
What did you see instead?
Flyway logs use the default format (same as if there was no slf4j present)
The text was updated successfully, but these errors were encountered: