Wie protokolliere ich SQL-Anweisungen in Spring Boot?

342

Ich möchte SQL-Anweisungen in einer Datei protokollieren.
Ich habe die folgenden Eigenschaften inapplication.properties

spring.datasource.url=...
spring.datasource.username=user
spring.datasource.password=1234
spring.datasource.driver-class-name=net.sourceforge.jtds.jdbc.Driver

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

security.ignored=true
security.basic.enabled=false

logging.level.org.springframework.web=INFO
logging.level.org.hibernate=INFO
logging.file=c:/temp/my-log/app.log

Wenn ich meine Anwendung ausführe

cmd>mvn spring-boot:run

Ich kann SQL-Anweisungen in der Konsole sehen, aber sie werden nicht in einer Datei app.log angezeigt. Die Datei enthält nur grundlegende Protokolle aus dem Frühjahr.

Was kann ich tun, um SQL-Anweisungen in der Protokolldatei anzuzeigen?

Oleg Pavliv
quelle

Antworten:

458

Versuchen Sie dies in Ihrer Eigenschaftendatei:

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
Paul Woods
quelle
74
Wenn Sie auch Werte protokollieren möchten:logging.level.org.hibernate.type=TRACE
Elysch
2
Dies protokolliert jedoch nur wenige Bindungswerte. Wie kann ich Werte aus der Kriterien-API protokollieren? Wenn ich Spezifikationen verwende, erhalte ich keine Ausgabe für gebundene Parameter, die mit dem CriteriaBuilder erstellt wurden.
Josh
203

Dies funktioniert auch für stdout:

spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true

So protokollieren Sie Werte:

logging.level.org.hibernate.type=trace

Fügen Sie dies einfach hinzu application.properties.

v.ladynev
quelle
11
Wenn Sie auch Werte protokollieren möchten:spring.jpa.properties.hibernate.type=trace
Elysch
1
Dies schreibt nicht in die Protokolldatei, dies schreibt in STDOUT
Muhammad Hewedy
4
Ich sehe immer noch nur ?anstelle der Parameter. Sollte diese Lösung sie mir zeigen?
Adeynack
1
spring.jpa.properties.hibernate.type = trace wirkt sich nicht auf meine Protokolldatei aus; (
gstackoverflow
1
Die "type = trace" ist keine Spring-Eigenschaft, daher funktioniert sie nicht. Die unten unter stackoverflow.com/a/41594913/5107365 angegebene Lösung ist dafür die richtige.
Raj
96

Das funktioniert bei mir (YAML):

spring:
  jpa:
    properties:
      hibernate:
        show_sql: true
        format_sql: true
logging:
  level:
    org:
      hibernate:
        type: trace
Michel
quelle
18

Benutzen Sie bitte:

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE
spring.jpa.show-sql=true
rahulnikhare
quelle
4
logging.level.org.hibernate.SQL=DEBUGmachte es für mich arbeiten und fehlte für andere Antworten. Vielen Dank!
Vic
18

Wenn Sie eine logback-spring.xml oder ähnliches haben, fügen Sie den folgenden Code hinzu

<logger name="org.hibernate.SQL" level="trace" additivity="false">
    <appender-ref ref="file" />
</logger>

funktioniert bei mir.

So erhalten Sie auch Bindungsvariablen:

<logger name="org.hibernate.type.descriptor.sql" level="trace">
    <appender-ref ref="file" />
</logger>
Edye Chan
quelle
1
Mit Spring Boot müssen Sie verwenden<appender-ref ref="FILE" />
Ortomala Lokni
appender ref ist der Name des Appenders, den Sie in der Logback-XML definiert haben. Es ist nur eine Variable
Raja Anbazhagan
17

Da dies eine sehr häufige Frage ist, habe ich diesen Artikel geschrieben , auf dem diese Antwort basiert.

Zu vermeidende Einstellungen

Sie sollten diese Einstellung nicht verwenden:

spring.jpa.show-sql=true 

Das Problem dabei show-sqlist, dass die SQL-Anweisungen in der Konsole gedruckt werden, sodass es keine Möglichkeit gibt, sie zu filtern, wie Sie es normalerweise mit einem Protokollierungsframework tun würden.

Verwenden der Protokollierung im Ruhezustand

Wenn Sie in Ihrer Protokollkonfigurationsdatei den folgenden Protokollierer hinzufügen:

<logger name="org.hibernate.SQL" level="debug"/>

Anschließend druckt Hibernate die SQL-Anweisungen, wenn der JDBC PreparedStatementerstellt wird. Aus diesem Grund wird die Anweisung mithilfe von Parameterplatzhaltern protokolliert:

INSERT INTO post (title, version, id) VALUES (?, ?, ?)

Wenn Sie die Bindungsparameterwerte protokollieren möchten, fügen Sie einfach den folgenden Logger hinzu:

<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="trace"/>

Sobald Sie den BasicBinderLogger eingestellt haben, sehen Sie, dass auch die Bindungsparameterwerte protokolliert werden:

DEBUG [main]: o.h.SQL - insert into post (title, version, id) values (?, ?, ?)
TRACE [main]: o.h.t.d.s.BasicBinder - binding parameter [1] as [VARCHAR] - [High-Performance Java Persistence, part 1]
TRACE [main]: o.h.t.d.s.BasicBinder - binding parameter [2] as [INTEGER] - [0]
TRACE [main]: o.h.t.d.s.BasicBinder - binding parameter [3] as [BIGINT] - [1]

Datenquellen-Proxy verwenden

Mit dem Datenquellen-Proxy können Sie den tatsächlichen JDBC DataSourceals Proxy verwenden , wie in der folgenden Abbildung dargestellt:

DataSource-Proxy

Sie können die dataSourceBean, die von Hibernate verwendet wird, wie folgt definieren:

@Bean
public DataSource dataSource(DataSource actualDataSource) {
    SLF4JQueryLoggingListener loggingListener = new SLF4JQueryLoggingListener();
    loggingListener.setQueryLogEntryCreator(new InlineQueryLogEntryCreator());
    return ProxyDataSourceBuilder
        .create(actualDataSource)
        .name(DATA_SOURCE_PROXY_NAME)
        .listener(loggingListener)
        .build();
}

Beachten Sie, dass die actualDataSourcemuss die werden DataSourcedurch die definierte Verbindungspool Sie sind in Ihrer Anwendung verwenden.

Nach dem Aktivieren datasource-proxywird die SQl-Anweisung wie folgt protokolliert:

Name:DATA_SOURCE_PROXY, Time:6, Success:True,
Type:Prepared, Batch:True, QuerySize:1, BatchSize:3,
Query:["insert into post (title, version, id) values (?, ?, ?)"],
Params:[(Post no. 0, 0, 0), (Post no. 1, 0, 1), (Post no. 2, 0, 2)]
Vlad Mihalcea
quelle
11

Für den MS-SQL Server-Treiber (Microsoft SQL Server JDBC-Treiber).

versuchen Sie es mit:

logging.level.com.microsoft.sqlserver.jdbc=debug

in Ihrer application.properties-Datei.

Meine persönliche Präferenz ist es, Folgendes festzulegen:

logging.level.com.microsoft.sqlserver.jdbc=info
logging.level.com.microsoft.sqlserver.jdbc.internals=debug

Sie können diese Links als Referenz ansehen:

Javier Z.
quelle
8

Laut Dokumentation ist es:

spring.jpa.show-sql=true # Enable logging of SQL statements.
Max Farsikov
quelle
Ich habe ein umgekehrtes Problem, indem ich dies auf false setze und org.hibernate auf Level ERROR setze und immer noch drucke drop / create / insert / select
Kalpesh Soni
5

Die übersetzte akzeptierte Antwort auf YAML funktioniert für mich

logging:
  level:
    org:
      hibernate:
        SQL:
          TRACE
        type:
          descriptor:
            sql:
              BasicBinder:
                TRACE
Robert.Li
quelle
3
Sie können in YAML auch flache Eigenschaften verwenden, wenn Sie nicht für Requisiten zum einmaligen Gebrauch verschachteln möchten, z. B.: logging.level.org.hibernate.SQL: TRACE logging.level.org.hibernate.type.descriptor.sql.BasicBinder: TRACE
MarcinJ
4

Wir können eine davon in der Datei application.properties verwenden:

spring.jpa.show-sql=true 

example :
//Hibernate: select country0_.id as id1_0_, country0_.name as name2_0_ from country country0_

oder

logging.level.org.hibernate.SQL=debug 

example :
2018-11-23 12:28:02.990 DEBUG 12972 --- [nio-8086-exec-2] org.hibernate.SQL   : select country0_.id as id1_0_, country0_.name as name2_0_ from country country0_
Lova Chittumuri
quelle
3

Wenn Sie die tatsächlichen Parameter anzeigen möchten, die zum Abfragen verwendet werden, können Sie diese verwenden

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql=TRACE

Beachten Sie dann, dass der tatsächliche Parameterwert als angezeigt wird binding parameter......

   2018-08-07 14:14:36.079 DEBUG 44804 --- [           main] org.hibernate.SQL                        : select employee0_.id as id1_0_, employee0_.department as departme2_0_, employee0_.joining_date as joining_3_0_, employee0_.name as name4_0_ from employee employee0_ where employee0_.joining_date=?
    2018-08-07 14:14:36.079 TRACE 44804 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [TIMESTAMP] - [Tue Aug 07 00:00:00 SGT 2018]
Udara SS Liyanage
quelle
3

Melden Sie sich bei der Standardausgabe an

Hinzufügen application.properties

### to enable
spring.jpa.show-sql=true
### to make the printing SQL beautify
spring.jpa.properties.hibernate.format_sql=true

Dies ist der einfachste Weg, um die SQL-Abfragen zu drucken, obwohl die Parameter der vorbereiteten Anweisungen nicht protokolliert werden. Und es wird nicht empfohlen, da es kein optimiertes Protokollierungsframework ist.

Verwenden des Protokollierungsframeworks

Hinzufügen application.properties

### logs the SQL queries
logging.level.org.hibernate.SQL=DEBUG
### logs the prepared statement parameters
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
### to make the printing SQL beautify
spring.jpa.properties.hibernate.format_sql=true

Durch Angabe der obigen Eigenschaften werden Protokolleinträge an den konfigurierten Protokoll-Appender gesendet, z. B. "Zurückmelden" oder "Protokoll4j".

Saveendra Ekanayake
quelle
0

Wenn Sie Probleme mit dieser Einstellung haben und sie manchmal und nicht zu anderen Zeiten zu funktionieren scheint, prüfen Sie, ob die Zeiten, in denen sie nicht funktioniert, bei Komponententests liegen.

Viele Benutzer deklarieren benutzerdefinierte Testzeit-Eigenschaften über die @TestPropertySourcesAnmerkung, die irgendwo in Ihrer Testvererbungshierarchie deklariert ist. Dadurch wird alles außer Kraft gesetzt, was Sie in Ihre application.propertiesoder andere Einstellungen für die Produktionseigenschaften eingegeben haben, sodass die von Ihnen festgelegten Werte zur Testzeit effektiv ignoriert werden.

Geschoren
quelle
0

Das Einfügen spring.jpa.properties.hibernate.show_sql=truevon application.properties hat nicht immer geholfen.

Sie können versuchen, properties.put("hibernate.show_sql", "true");die Eigenschaften der Datenbankkonfiguration zu erweitern.

public class DbConfig {

    @Primary
    @Bean(name = "entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean
    entityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("dataSource") DataSource dataSource
    ) {
        Map<String, Object> properties = new HashMap();
        properties.put("hibernate.hbm2ddl.auto", "validate");
        properties.put("hibernate.show_sql", "true");

        return builder
                .dataSource(dataSource)
                .packages("com.test.dbsource.domain")
                .persistenceUnit("dbsource").properties(properties)
                .build();
    }
SJX
quelle