web-dev-qa-db-fra.com

Comment obliger liquibase à se connecter avec slf4j?

Beaucoup de personnes ne sont pas certains comment à fix se connecte pour liquibase, que ce soit dans la console ou dans le fichier.

Est-il possible de faire un journal liquibase en slf4j?

27
Benny Bottema

Il y en a un, mais c'est un peu obscur. Citant Correction de la journalisation Liquibase avec SLF4J et Log4J :

Il y a La solution de facilité , en déposant une dépendance:

<!-- 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>

Maintenant, les deux premiers sont vos cadres de journalisation quotidiens (implémentation de slf4j api et log4j). Celles-ci s'ajoutent à votre dépendance log4j standard, car elles ne font que se connecter à l'infrastructure de journalisation physique. Sans log4j/logback/etc. elle-même, ils ne peuvent toujours rien acheminer.

Ce dernier est toutefois intéressant, car il fournit une classe unique dans un package spécifique que liquibase recherchera pour les implémentations Logger. Il est open source, par Matt Bertolini, donc vous pouvez le trouver sur GitHub .

Si vous souhaitez le faire vous-même, il y a aussi 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;
    }
}

Cette implémentation fonctionne, mais ne doit être utilisée qu'à titre d'exemple. Par exemple, je n'utilise pas les noms de Liquibase pour exiger une journalisation, mais j'utilise plutôt cette classe Logger. Les versions de Matt font également quelques vérifications null -, ce qui en fait probablement une implémentation plus mature à utiliser, en plus de son open source.

42
Benny Bottema

Je ne suis pas très sûr de vos besoins, mais ce que je comprends, c’est que vous souhaitiez consigner tous les journaux liquibase à l’aide de l’API SLF4J. Si j'ai raison, alors je suppose que vous pouvez le faire.

Ajoutez d’abord la dépendance suivante dans votre fichier pom.xml:

<dependency>
    <groupId>com.mattbertolini</groupId>
    <artifactId>liquibase-slf4j</artifactId>
    <version>1.2.1</version>
</dependency>

<dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.6.6</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>log4j-over-slf4j</artifactId>
        <version>1.6.6</version>
    </dependency>

    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
        <version>1.0.7</version>
    </dependency>

    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.0.7</version>
    </dependency>

et dans votre fichier logback.xml, ajoutez un enregistreur pour liquibase et définissez NIVEAU selon vos besoins.

  <logger name="liquibase" level="DEBUG" />
4
Waheed

Voici ma recette pour que liquibase 3.5.3 se connecte dans un fichier sous Windows lors de l'exécution en ligne de commande. Il n'utilise pas exactement 'slf4j' mais résout le problème d'obtention des fichiers journaux des mises à jour de la base de données, en rendant liquibase. utilisez Java.util.logging.

1) obtenir le liquidibase-javalogger-3.0.jar à partir d’ici https://github.com/liquibase/liquibase-javalogger/releases/

2) placez-le dans le répertoire% LIQUIBASE_HOME%/lib

3) créer un fichier logger.properties avec le contenu suivant:

handlers=Java.util.logging.FileHandler, Java.util.logging.ConsoleHandler
.level=FINEST
Java.util.logging.ConsoleHandler.formatter=Java.util.logging.SimpleFormatter
Java.util.logging.FileHandler.pattern=liquibase.log
Java.util.logging.FileHandler.formatter=Java.util.logging.SimpleFormatter
Java.util.logging.FileHandler.append=true
#2018-04-28 17:29:44 INFO Example logging record
Java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS %4$s %5$s%6$s%n

4) ajoutez l’option Java à liquibase (par exemple via set Java_OPTS = ...):

-Djava.util.logging.config.file=logger.properties

Exemple de fichier de commandes de mon wrapper liquibase:

set username=%USER%
set password="%PASSWORD%"

set URL="jdbc:db2://mydbserver:50000/MYDB"

set Java_OPTS=-Djava.util.logging.config.file=db2/logger.properties

call liquibase.bat ^
    --driver="com.ibm.db2.jcc.DB2Driver" ^
    --defaultSchemaName=MYSCHEMA ^
    --liquibaseSchemaName=MYSCHEMA ^
    --changeLogFile=db2/changelog.xml ^
    --url=%URL% ^
    --username=%USER% ^
    --password="%PASSWORD%" ^
    --logLevel=debug

METTRE À JOUR:

Je suis passé à la nouvelle version de liquibase qui utilise logback par défaut. Sous liquibase 3.6.2, utilisez la configuration suivante pour exécuter la ligne de commande Windows:

1) Assurez-vous que slfj est accessible dans un chemin de classe Java. Placez le fichier slf4j-api-1.7.25.jar dans le dossier liquibase/lib. Le fichier jar se trouve dans le package de distribution officiel de slfj: https://www.slf4j.org/download.html

2) Définissez le paramètre de chemin du fichier de configuration logback: 

Java_OPTS=-Dlogback.configurationFile=logback.xml

3) Ajoutez le fichier de configuration logback.xml. Voici l'exemple: https://www.mkyong.com/logging/logback-xml-example/

2
vrogach

J'ai essayé la même chose dans mon application et semble que cela fonctionne bien. Je peux voir le journal liquibase dans mon fichier journal. 

2014-01-08 11:16:21,452 [main] DEBUG liquibase - Computed checksum for addColumn:[
    columns=[
        column:[
            name="IS_NEW"
            type="BIT"
        ]
    ]
    tableName="TENANT"
] as e2eb1f5cb8dcfca7d064223044d06de9
2014-01-08 11:16:21,452 [main] DEBUG liquibase - Computed checksum for 3:e2eb1f5cb8dcfca7d064223044d06de9: as 549852ffb531de4929ae433ff0be2742
2014-01-08 11:16:21,455 [main] DEBUG liquibase - Release Database Lock
2014-01-08 11:16:21,456 [main] DEBUG liquibase - Executing UPDATE database command: UPDATE `DATABASECHANGELOGLOCK` SET `LOCKED` = 0, `LOCKEDBY` = NULL, `LOCKGRANTED` = NULL WHERE `ID` = 1
2014-01-08 11:16:21,518 [main] INFO  liquibase - Successfully released change log lock
0
Waheed