Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get liquibase to log using slf4j?

A lot of people are unsure how to fix logging for liquibase, either to the console or file.

Is it possible to make liquibase log to slf4j?

like image 785
Benny Bottema Avatar asked Jan 02 '14 10:01

Benny Bottema


People also ask

Which Logger is used by SLF4J?

SLF4J supports popular logging frameworks, namely log4j, java. util. logging, Simple logging and NOP. The logback project supports SLF4J natively.

Does Liquibase use log4j?

This is a serious vulnerability, so our team immediately investigated if Liquibase includes this library in any code to ensure we could alert our users. We confirmed that none of our editions or tools use the log4j2 library.

What is jul to SLF4J?

Instead, jul-to-slf4j translates LogRecord objects into their SLF4J equivalent. Please note this translation process incurs the cost of constructing a LogRecord instance regardless of whether the SLF4J logger is disabled for the given level or nor.

How do you use the Loglevel flag in Liquibase?

Using the --log-level parameterThe --log-level is an optional parameter that is either set in the Liquibase properties file or specified on the command line. The --log-level specified on the command line overrides the value set in the properties file.


1 Answers

There is, but it is a little bit obscure. Quoting Fixing liquibase logging with SLF4J and Log4J:

There's The Easy Way, by dropping in a dependency:

<!-- your own standard logging dependencies --> <dependency>     <groupId>org.slf4j</groupId>     <artifactId>slf4j-api</artifactId>     <version>1.7.5</version> </dependency> <dependency>     <groupId>org.slf4j</groupId>     <artifactId>slf4j-log4j12</artifactId><!-- or log4j2 or logback or whatever-->     <version>1.7.5</version> </dependency>  <!-- special dependency to fix liquibase's logging fetish --> <dependency>     <groupId>com.mattbertolini</groupId>     <artifactId>liquibase-slf4j</artifactId>     <version>1.2.1</version> </dependency> 

Now the first two are your everyday logging frameworks (slf4j api and log4j implementation). These are in addition to your standard log4j dependency, as all they do is route to the physical logging framework. Without log4j/logback/etc. itself, they still can't route anything.

The last one however, is an interesting one, as it provides a single class in a specific package that liquibase will scan for Logger implementations. It's open source, by Matt Bertolini, so you can find it on GitHub.

If you wish to do this yourself, there's also The Hard Way:

package liquibase.ext.logging; // this is *very* important  import liquibase.changelog.ChangeSet; import liquibase.changelog.DatabaseChangeLog; import liquibase.logging.core.AbstractLogger;  import org.slf4j.Logger; import org.slf4j.LoggerFactory;  /**  * Liquibase finds this class by itself by doing a custom component scan (sl4fj wasn't generic enough).  */ public class LiquibaseLogger extends AbstractLogger {     private static final Logger LOGGER = LoggerFactory.getLogger(LiquibaseLogger.class);     private String name = "";      @Override     public void setName(String name) {         this.name = name;     }      @Override     public void severe(String message) {         LOGGER.error("{} {}", name, message);     }      @Override     public void severe(String message, Throwable e) {         LOGGER.error("{} {}", name, message, e);     }      @Override     public void warning(String message) {         LOGGER.warn("{} {}", name, message);     }      @Override     public void warning(String message, Throwable e) {         LOGGER.warn("{} {}", name, message, e);     }      @Override     public void info(String message) {         LOGGER.info("{} {}", name, message);     }      @Override     public void info(String message, Throwable e) {         LOGGER.info("{} {}", name, message, e);     }      @Override     public void debug(String message) {         LOGGER.debug("{} {}", name, message);     }      @Override     public void debug(String message, Throwable e) {         LOGGER.debug("{} {}", message, e);     }      @Override     public void setLogLevel(String logLevel, String logFile) {     }      @Override     public void setChangeLog(DatabaseChangeLog databaseChangeLog) {     }      @Override     public void setChangeSet(ChangeSet changeSet) {     }      @Override     public int getPriority() {         return Integer.MAX_VALUE;     } } 

This implementation works, but should only be used as an example. For example, I'm not using Liquibase's names to require a logging, but use this Logger class itself instead. Matt's versions does some null-checks as well, so that's probably a more mature implementation to use, plus it's open source.

like image 193
Benny Bottema Avatar answered Sep 24 '22 09:09

Benny Bottema