logging-log4j2 icon indicating copy to clipboard operation
logging-log4j2 copied to clipboard

Liquibase 4.x Compatibility

Open nvoxland opened this issue 3 years ago • 7 comments

Overview

Liquibase 3.6 as well as 4.0 introduced API compatibility issues with the current log4j-liquibase codebase. See liquibase/liquibase#1777

This updates the code to be compatible with 4.0+ while still supporting 3.5 and 3.6+ users.

nvoxland avatar Jun 02 '21 20:06 nvoxland

With the new Log4j2Logger implementation, the messages coming through in the test class look like liquibase.ext.logging.log4j2.Log4j2LoggerTest liquibase.logging.core.AbstractLogger FATAL Severe message and I'm not sure where that "AbractLogger" part is coming from.

I think I'm setting up the ExtendedLogger the same as it was in the old code, but that extra piece is not showing up there.

Any ideas why?

nvoxland avatar Jun 02 '21 20:06 nvoxland

Hey @nvoxland, thanks for the contribution. I have my concerns if Log4j should have a Liquibase-specific module in the first place. Let me elaborate on that a bit.

Certain libraries, which is Liquibase in this particular case, create their own logging API rather than choosing one available in the market, e.g., slf4j-api, log4j-api. Consequently, they contribute to logging backends (Logback, Log4j, etc.) with implementations of their custom logging API. This, IMHO, contradicts with the motives of those logging backends shipping a separate API in the first place. I would rather prefer Liquibase logging against, say, the Log4j API and let users pick a backend. For instance, users then can either employ any backend supporting Log4j API (e.g., Log4j itself) or use a bridge to port it to another API of their preference (e.g., using log4j-to-slf4j bridge in combination with Logback).

In your profile, I see that you are member of the Liquibase organization. Would you mind telling us why can't Liquibase simply use Log4j API instead? Are there any technical limitations I miss here?

vy avatar Jun 08 '21 20:06 vy

From Liquibase's standpoint, as a library we try hard not to introduce dependencies on external libraries such as log4j. Therefore, we build off the java.util.Logger but do have a lightweight extension point where 3rd parties can plug in alternatives instead.

This code is really just plugging into that liquibase extension point to bypass JUL and go directly to log4j. An alternative is certainly to use the log4j-jul adapter as well. I didn't write this extension in the code here, just fixing it :)

If you are against continuing to have this extension as part of log4j, we could look at bringing it into the liquibase codebase directly as well. I don't think we could have it automatically enabled if log4j is found, since many users end up with log4j in their classpath even though it's not their "real" logging system. But, have some configuration settings we could support.

nvoxland avatar Jun 09 '21 17:06 nvoxland

I perfectly understand your conservative attitude for adding dependencies to your project and share them. This said, dependencies increase re-usability and independent evolution. Hence, I ~strongly~ kindly advice you to consider adopting log4j-api, if possible.

Even though I am a PMC member, I cannot speak for the rest of the board. I will raise this issue in the dev mailing list. If we decide to exclude log4j-liquibase from 3.x onward, I see two possible paths:

  1. Liquibase adopting log4j-api (recommended)
  2. Introducing liquibase-log4j module (I already see a org.liquibase.ext:liquibase-javalogger module)

For the records, would you mind sharing this with the rest of Liquibase crew and let us know what do you think, please? Is adopting log4j-api really a no-go for you?

vy avatar Jun 10 '21 12:06 vy

Yes, I will keep the rest of the team up on this discussion.

I think that making log4j-api a required part of our API or standard logging implementation is a no-go. It would mean having to change a stable API, and impacts users embedding liquibase but not wanting to introduce log4j-api as a dependency into their software.

But, there are ways we can include it in liquibase so log4j isn't required but still would work when people already have it as a dependency.

nvoxland avatar Jun 10 '21 14:06 nvoxland

I don't necessarily object to Log4j providing integrations with third party components. But if something like liquibase chooses to provide its own logging API then it should also supply the bindings to the various implementations its users want to use. That binding could certainly be hosted inside the Log4j project, but it really shouldn't be part of the main Log4j release. We can't possibly support every such integration in that way.

rgoers avatar Jun 10 '21 15:06 rgoers

For anyone looking for a workaround I was able to resolve this by adding a dependency on log4j-jul https://github.com/metabase/metabase/pull/20611/files#diff-551f87f7577a57c2f4f74b35056d5c7985331f7a38976810fd2bbc213bfe7bb5R87 and installing the bridge at runtime

https://github.com/metabase/metabase/pull/20611/files#diff-7b84b53f388126bbf994fbdb5b705a6eefeaf0999da00dc45a40a6559f85ac30R23-R28

camsaul avatar Mar 11 '22 17:03 camsaul

I close this, since Liquibase will publish their own plugin (cf. #1193).

@nvoxland, thank You for your contribution.

ppkarwasz avatar Jan 16 '23 05:01 ppkarwasz