2012-07-24 46 views
100

Hibernate 3.x sử dụng để ghi nhật ký. Hibernate 4.x sử dụng . Tôi đang viết một ứng dụng độc lập sử dụng Hibernate 4 và SLF4J để ghi nhật ký.Cách bạn định cấu hình ghi nhật ký trong Hibernate 4 để sử dụng SLF4J

Làm cách nào tôi có thể định cấu hình Hibernate để đăng nhập vào SLF4J?

Nếu không thể, làm cách nào tôi có thể định cấu hình ghi nhật ký của Hibernate?

Các Hibernate 4.1 thủ công section on logging bắt đầu với cảnh báo rằng nó là ...

hoàn toàn hết hiệu lực. Hibernate sử dụng JBoss Logging bắt đầu từ 4.0. Điều này sẽ được ghi lại khi chúng tôi di chuyển nội dung này sang Hướng dẫn dành cho nhà phát triển.

... tiếp tục nói về SLF4J, và như vậy là vô dụng. Không phải getting started guide cũng không phải là developer guide nói về ghi nhật ký. Cũng không phải là migration guide.

Tôi đã tìm tài liệu về bản ghi nhật ký jboss, nhưng tôi chưa thể tìm thấy bất kỳ thứ gì. GitHub page is silent và JBoss's community projects page thậm chí không liệt kê jboss-logging. Tôi tự hỏi nếu dự án thứ bug tracker có thể có bất kỳ vấn đề liên quan đến việc cung cấp tài liệu, nhưng nó không.

Tin tốt là khi sử dụng Hibernate 4 bên trong một máy chủ ứng dụng, chẳng hạn như JBoss AS7, việc ghi nhật ký phần lớn được thực hiện cho bạn. Nhưng làm thế nào tôi có thể cấu hình nó trong một ứng dụng độc lập?

+12

+1 để làm nổi bật mà Hibernate tài liệu về khai thác gỗ hết hạn – mhnagaoka

Trả lời

-2

bạn đã thử điều này:

- slf4j-log4j12.jar trong trường hợp của Log4J. Xem tài liệu SLF4J để biết thêm chi tiết. Để sử dụng Log4j, bạn cũng sẽ cần phải đặt một tệp log4j.properties trong classpath của bạn. Một ví dụ tập tin thuộc tính được phân phối với Hibernate trong src/thư mục

chỉ cần thêm những lọ và tài sản hoặc log4j xml trong classpath

+4

Đó là một trích dẫn từ tài liệu 3.x Hibernate. Bạn có nghĩ rằng sẽ vẫn làm việc với Hibernate 4.x, mà không sử dụng SLF4J? –

+0

theo như tôi nhớ log4j là đủ –

7

Trước tiên, bạn làm nhận ra SLF4J đó không phải là một quyền thư viện khai thác gỗ, một khai thác gỗ của nó vỏ bánh. Nó tự nó không đăng nhập bất cứ điều gì, nó chỉ đơn giản là đại biểu để "phụ trợ".

Để "định cấu hình" jboss-logging, bạn chỉ cần thêm bất kỳ khung đăng nhập nào bạn muốn sử dụng trên classpath của mình (cùng với jboss-logging) và jboss-logging tìm ra phần còn lại.

Tôi tạo ra một hướng dẫn Hibernate tập trung vào để JBoss Logging config: http://docs.jboss.org/hibernate/orm/4.3/topical/html/logging/Logging.html

+1

Tôi nhận ra rằng SLF4J là một mặt tiền, có. Gửi Hibernate đăng nhập vào SLF4J có nghĩa là nó kết thúc tại bất kỳ phụ trợ tôi đã chọn cho phần còn lại của ứng dụng của tôi, đó là những gì tôi muốn. –

+10

Vì vậy, những gì bạn đang nói về cấu hình là không có cấu hình (đó là tốt đẹp!), Nhưng jboss-logging bằng cách nào đó phát hiện và chọn một phụ trợ? Ah, bây giờ tôi dành thời gian để thực sự nhìn vào mã, tôi thấy đó là [chính xác những gì sẽ xảy ra] (https://github.com/jboss-logging/jboss-logging/blob/master/src/main/java/ org/jboss/logging/LoggerProviders.java # L37). Cụ thể, jboss-logging cố gắng, theo thứ tự, JBoss LogManager, log4j, Logback thông qua SLF4J và ghi nhật ký JDK. Nhưng điều này * có thể * được ghi đè bằng thuộc tính hệ thống 'org.jboss.logging.provider'. –

+2

Nhiều người trong số chúng tôi đã bị đốt cháy bởi những người đăng nhập tìm kiếm những thứ cho bạn, vì vậy biết chính xác cách hoạt động của jboss-logging rất quan trọng để có thể hỗ trợ nó trong thế giới thực khi những điều bất ngờ xảy ra. – ams

2

tôi sử dụng maven và bổ sung phụ thuộc sau:

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

Sau đó, tôi đã tạo ra một log4j.properties file trong /src/main/resources:

# direct log messages to stdout 
log4j.appender.stdout=org.apache.log4j.ConsoleAppender 
log4j.appender.stdout.Target=System.out 
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n 
# set log levels 
log4j.rootLogger=warn 

Điều này sẽ đặt nó ở gốc của số .jar. Nó hoạt động giống như một sự quyến rũ ...

+1

Cấu hình này sử dụng log4j. OP không muốn sử dụng log4j; họ muốn sử dụng slf4j. – Raedwald

3

Tôi đang sử dụng lõi Hibernate 4.1.7.Thêm cộng với Spring 3.1.2.RELEASE trong một ứng dụng độc lập. Tôi đã thêm Log4j 1.2.17 để phụ thuộc của tôi và có vẻ như, như JBoss Đăng nhập nhật ký trực tiếp để log4j nếu có sẵn và mùa xuân sử dụng Commons Logging, phù thủy cũng sử dụng Log4j nếu có, tất cả Logging có thể được cấu hình thông qua Log4J.

Dưới đây là danh sách của tôi phụ thuộc có liên quan:

<dependency> 
    <groupId>log4j</groupId> 
    <artifactId>log4j</artifactId> 
    <version>1.2.17</version> 
</dependency> 
<dependency> 
    <groupId>org.hibernate</groupId> 
    <artifactId>hibernate-core</artifactId> 
    <version>4.1.7.Final</version> 
</dependency> 
<dependency> 
    <groupId>org.springframework</groupId> 
    <artifactId>spring-context</artifactId> 
    <version>3.1.2.RELEASE</version> 
</dependency> 
<dependency> 
    <groupId>org.springframework</groupId> 
    <artifactId>spring-orm</artifactId> 
    <version>3.1.2.RELEASE</version> 
</dependency> 
11

Lấy cảm hứng từ Leif's Hypoport post, đây là cách tôi "cong" Hibernate 4 trở lại slf4j:

Giả sử bạn đang sử dụng Maven.

  • Thêm org.slf4j:log4j-over-slf4j như một phụ thuộc vào bạn pom.xml
  • Sử dụng lệnh mvn dependency:tree, hãy chắc chắn none của vật bạn đang sử dụng depende trên slf4j:slf4j (để được chính xác, không có tạo tác có trách nhiệm một biên dịch phụ thuộc phạm vi hoặc thời gian chạy phụ thuộc phạm vi trên slf4j:slf4j)

Nền: Hibernate 4. x có sự phụ thuộc vào tạo phẩm org.jboss.logging:jboss-logging. Quá mức, tạo phẩm này có một phụ kiện được cung cấp phụ thuộc vào phần tạo tác slf4j:slf4j.

Như chúng ta đã thêm các tạo tác org.slf4j:log4j-over-slf4j, org.slf4j:log4j-over-slf4j bắt chước các tạo tác slf4j:slf4j. Do đó mọi thứ mà JBoss Logging nhật ký giờ sẽ thực sự đi qua slf4j.

Giả sử bạn đang sử dụng Đăng nhập làm phụ trợ ghi nhật ký của mình. Đây là một mẫu pom.xml

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    .... 
    <properties> 
     .... 
     <slf4j-api-version>1.7.2</slf4j-api-version> 
     <log4j-over-slf4j-version>1.7.2</log4j-over-slf4j-version> 
     <jcl-over-slf4j-version>1.7.2</jcl-over-slf4j-version> <!-- no problem to have yet another slf4j bridge --> 
     <logback-core-version>1.0.7</logback-core-version> 
     <logback-classic-version>1.0.7</logback-classic-version> 
     <hibernate-entitymanager-version>4.1.7.Final</hibernate-entitymanager-version> <!-- our logging problem child --> 
    </properties> 

    <dependencies> 
      <!-- begin: logging-related artifacts .... --> 
      <dependency> 
       <groupId>org.slf4j</groupId> 
       <artifactId>slf4j-api</artifactId> 
       <version>${slf4j-api-version}</version> 
      </dependency> 
      <dependency> 
       <groupId>org.slf4j</groupId> 
       <artifactId>jcl-over-slf4j</artifactId> 
       <version>${jcl-over-slf4j-version}</version> 
      </dependency> 
      <dependency> 
       <groupId>org.slf4j</groupId> 
       <artifactId>log4j-over-slf4j</artifactId> 
       <version>${log4j-over-slf4j-version}</version> 
      </dependency> 
      <dependency> 
       <groupId>ch.qos.logback</groupId> 
       <artifactId>logback-core</artifactId> 
       <version>${logback-core-version}</version> 
      </dependency> 
      <dependency> 
       <groupId>ch.qos.logback</groupId> 
       <artifactId>logback-classic</artifactId> 
       <version>${logback-classic-version}</version> 
      </dependency> 
      <!-- end: logging-related artifacts .... --> 

      <!-- begin: some artifact with direct dependency on log4j:log4j .... --> 
      <dependency> 
      <groupId>org.foo</groupId> 
       <artifactId>some-artifact-with-compile-or-runtime-scope-dependency-on-log4j:log4j</artifactId> 
       <version>${bla}</version> 
       <exclusions> 
        <exclusion> 
         <groupId>log4j</groupId> 
         <artifactId>log4j</artifactId> 
        </exclusion> 
       </exclusions> 
      </dependency> 
      <!-- begin: some artifact with direct dependency on log4j:log4j .... --> 

      <!-- begin: a hibernate 4.x problem child........... --> 
      <dependency> 
       <groupId>org.hibernate</groupId> 
       <artifactId>hibernate-entitymanager</artifactId> 
       <version>${hibernate-entitymanager-version}</version> 
      </dependencies> 
      <!-- end: a hibernate 4.x problem child........... --> 
    .... 
</project> 

On classpath của bạn, có một logback.xml, như thế này nằm ở src/main/java:

<!-- begin: logback.xml --> 
<configuration> 
<appender name="console" class="ch.qos.logback.core.ConsoleAppender"> 
    <encoder> 
     <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> 
    </encoder> 
</appender> 

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

<root level="info"> 
    <appender-ref ref="console"/> 
</root> 

</configuration> 
<!-- end: logback.xml --> 

Một số thành phần có thể muốn có quyền truy cập vào logback.xml tại JVM thời gian khởi động để ghi nhật ký thích hợp, ví dụ như Plugin Jetty Maven. Trong trường hợp đó, hãy thêm một hệ thống Java logback.configurationFile=./path/to/logback.xml vào lệnh của bạn (ví dụ: mvn -Dlogback.configurationFile=./target/classes/logback.xml jetty:run).

Trong trường hợp bạn vẫn nhận được kết quả đầu ra Hibernate "stdout" (như Hibernate: select ...), thì có thể áp dụng câu hỏi Chồng tràn "Turn off hibernate logging to console".

+1

Hãy chắc chắn rằng không có thư viện nào khác làm mất log4j, hoặc điều này sẽ không hoạt động. Ví dụ: activemq-all.jar chứa log4j. Gợi ý: Mở IDE của bạn và tìm log4j dễ dàng trong mã của bạn. –

+0

Tôi đã có vấn đề này với JBoss Hibernate4 và một máy chủ cũ (quá). Bài đăng này, bao gồm 1 dòng trong application.properties đã làm các trick cho tôi. Vậy TNX !!! Và dòng cuối cùng trong thuộc tính của tôi được viết bằng một câu trả lời khác ở đây: 'org.jboss.logging.provider = slf4j' –

24

Để SLF4J hoạt động với JBoss Đăng nhập mà không cần Logback làm phụ trợ yêu cầu sử dụng thuộc tính hệ thống org.jboss.logging.provider=slf4j. Chiến thuật log4j-over-slf4j dường như không hoạt động trong trường hợp này vì quá trình ghi nhật ký sẽ quay trở lại JDK nếu cả Logback lẫn log4j không thực sự có mặt trong classpath. Đây là một chút phiền toái và để có được tự động làm việc bạn đã thấy rằng trình nạp lớp chứa ít nhất ch.qos.logback.classic.Logger từ logback-classic hoặc org.apache.log4j.Hierarchy từ log4j để lừa JBoss Logging không rơi trở lại JDK logging.

Sự kỳ diệu được giải thích tại org.jboss.logging.LoggerProviders

UPDATE: Dịch vụ hỗ trợ loader đã được thêm vào để có thể tránh các vấn đề hiện tự động bằng cách tuyên bố META-INF/services/org.jboss.logging.LoggerProvider (với org.jboss.logging.Slf4jLoggerProvider như một giá trị). Dường như cũng có thêm hỗ trợ log4j2.

+1

Tôi đặt thuộc tính hệ thống này ở đâu? – jhegedus

+0

Phụ thuộc vào thiết lập của bạn, nhưng thông thường, công tắc dòng lệnh '-Dorg.jboss.logging.provider = slf4j' là đủ. [LoggingProviders.java] (https://github.com/jboss-logging/jboss-logging/blob/master/src/main/java/org/jboss/logging/LoggerProviders.java) cung cấp cho bạn thông tin chi tiết hơn về những gì hiện tại các giá trị được chấp nhận và những gì được dự kiến ​​sẽ có mặt trong classpath. –

+2

Tôi không nghĩ rằng phương pháp trình tải dịch vụ hoạt động vì 'Slf4jLoggerProvider' không phải là một lớp' public'? – holmis83

2

vì vậy, hãy làm việc đó trong dự án của tôi. hibernate 4, slf4j, logback. dự án của tôi là gradle, nhưng nên giống nhau cho maven.

Về cơ bản Abdull là đúng. Nơi anh ta không đúng, là bạn DONT phải loại bỏ slf4j từ phụ thuộc.

  1. bao gồm phạm vi biên dịch:

    org.slf4j: slf4j-api

    org.slf4j: log4j-over-slf4j

    ví dụ cho logback (ch.qos.logback: logback-cổ điển, ch.qos.logback: logback lõi: 1.0.12)

  2. hoàn toàn loại trừ libs log4j từ phụ thuộc

kết quả: ngủ đông log qua slf4j để logback. tất nhiên bạn sẽ có thể sử dụng triển khai nhật ký khác với logback

để đảm bảo rằng không có log4j, kiểm tra libs của bạn trên classpath hoặc web-inf/lib cho các tệp chiến tranh.

tất nhiên bạn đã đặt nhật ký trong logback.xml, ví dụ: :

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

49

Look để https://github.com/jboss-logging/jboss-logging/blob/master/src/main/java/org/jboss/logging/LoggerProviders.java:

static final String LOGGING_PROVIDER_KEY = "org.jboss.logging.provider"; 

private static LoggerProvider findProvider() { 
    // Since the impl classes refer to the back-end frameworks directly, if this classloader can't find the target 
    // log classes, then it doesn't really matter if they're possibly available from the TCCL because we won't be 
    // able to find it anyway 
    final ClassLoader cl = LoggerProviders.class.getClassLoader(); 
    try { 
     // Check the system property 
     final String loggerProvider = AccessController.doPrivileged(new PrivilegedAction<String>() { 
      public String run() { 
       return System.getProperty(LOGGING_PROVIDER_KEY); 
      } 
     }); 
     if (loggerProvider != null) { 
      if ("jboss".equalsIgnoreCase(loggerProvider)) { 
       return tryJBossLogManager(cl); 
      } else if ("jdk".equalsIgnoreCase(loggerProvider)) { 
       return tryJDK(); 
      } else if ("log4j".equalsIgnoreCase(loggerProvider)) { 
       return tryLog4j(cl); 
      } else if ("slf4j".equalsIgnoreCase(loggerProvider)) { 
       return trySlf4j(); 
      } 
     } 
    } catch (Throwable t) { 
    } 
    try { 
     return tryJBossLogManager(cl); 
    } catch (Throwable t) { 
     // nope... 
    } 
    try { 
     return tryLog4j(cl); 
    } catch (Throwable t) { 
     // nope... 
    } 
    try { 
     // only use slf4j if Logback is in use 
     Class.forName("ch.qos.logback.classic.Logger", false, cl); 
     return trySlf4j(); 
    } catch (Throwable t) { 
     // nope... 
    } 
    return tryJDK(); 
} 

giá trị Vì vậy, có thể cho org.jboss.logging.provider là: jboss, jdk, log4j, slf4j.

Nếu bạn không đặt org.jboss.logging.provider, nó sẽ thử jboss, sau đó log4j, sau đó slf4j (chỉ khi logback được sử dụng) và dự phòng thành jdk.

tôi sử dụng slf4j với logback-classic:

<dependency> 
     <groupId>ch.qos.logback</groupId> 
     <artifactId>logback-classic</artifactId> 
     <version>1.0.13</version> 
     <scope>${logging.scope}</scope> 
    </dependency> 

và tất cả làm việc tốt!

CẬP NHẬT Một số người dùng sử dụng trong App.java rất chính:

static { //runs when the main class is loaded. 
    System.setProperty("org.jboss.logging.provider", "slf4j"); 
} 

nhưng đối với các giải pháp chứa dựa này không được làm việc.

CẬP NHẬT 2 Những người nghĩ rằng họ quản lý Log4j với SLF4J cho jboss-logging nó không chính xác như vậy. jboss-logging sử dụng trực tiếp Log4j mà không cần SLF4J!

+1

Nơi đặt 'org.jboss.logging.provider'? –

+1

@SuzanCioc Theo 'System.getProperty (LOGGING_PROVIDER_KEY);' bạn cần thiết lập thuộc tính hệ thống. Thông qua 'java -D ... = ...' hoặc kiểm tra tài liệu cho vùng chứa của bạn. – gavenkoa

+0

Cập nhật thứ hai của bạn về việc không thể sử dụng log4j thông qua slf4j là hữu ích. Đặt org.jboss.logging.provider thành slf4j khiến tôi nghĩ rằng sự ủng hộ của log4j của tôi sẽ khởi động. Tôi phải đặt trực tiếp vào log4j để làm việc đó. Odd. Điểm slf4j là một tùy chọn cho cấu hình này thì sao? –

3

Hibernate 4.3 có some documentation về cách kiểm soát org.jboss.logging:

  • Nó tìm kiếm các đẳng cấp con đường cho một nhà cung cấp khai thác gỗ. Nó tìm kiếm slf4j sau khi tìm kiếm log4j. Vì vậy, về mặt lý thuyết, đảm bảo rằng classpath của bạn (WAR) không bao gồm log4j và không bao gồm API slf4j và back-end sẽ hoạt động.

  • Như một phương sách cuối cùng, bạn có thể đặt thuộc tính hệ thống org.jboss.logging.provider thành slf4j.


Mặc dù những tuyên bố của các tài liệu, org.jboss.logging khăng khăng cố gắng sử dụng log4j, mặc dù log4j là vắng mặt và SLF4J có mặt, dẫn đến việc thông báo sau trong tập tin log Tomcat của tôi (/var/log/tomcat/catalina.out):

log4j:WARN No appenders could be found for logger (org.jboss.logging). 
log4j:WARN Please initialize the log4j system properly. 
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info. 

Tôi phải tuân theo đề xuất câu trả lời theo số dasAnderl ausMinga và bao gồm cầu log4j-over-slf4j.

1

Tôi gặp sự cố khi tạo công việc ghi nhật ký 4 chế độ ngủ đông với weblogic 12c và log4j. Giải pháp là đưa những điều sau đây vào weblogic-application.xml của bạn:

<prefer-application-packages> 
    <package-name>org.apache.log4j.*</package-name> 
    <package-name>org.jboss.logging.*</package-name> 
</prefer-application-packages> 
0

Cho bất kỳ ai có thể gặp phải cùng một vấn đề tôi gặp phải. Trong trường hợp bạn đã thử tất cả các giải pháp khác được giải thích ở đây và vẫn không thấy đăng nhập hibernate làm việc với slf4j của bạn, nó có thể là do bạn đang sử dụng một container có trong thư viện thư mục của mình là jboss-logging.jar. Điều này có nghĩa là được tải trước trước khi bạn thậm chí có thể đặt bất kỳ cấu hình nào để tác động đến nó. Để tránh sự cố này trong weblogic bạn có thể chỉ định trong tệp weblogic-application.xml trong tai/META-INF để thích thư viện được tải từ ứng dụng. nên có một cơ chế tương tự cho các thùng chứa máy chủ khác. Trong trường hợp của tôi, tôi đã có thêm:

<?xml version="1.0" encoding="UTF-8"?> 
<wls:weblogic-application xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-application" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/javaee_5.xsd http://xmlns.oracle.com/weblogic/weblogic-application http://xmlns.oracle.com/weblogic/weblogic-application/1.5/weblogic-application.xsd"> 
    <wls:prefer-application-packages>  
     <!-- logging --> 
     <wls:package-name>org.slf4j.*</wls:package-name> 
     <wls:package-name>org.jboss.logging.*</wls:package-name>    
    </wls:prefer-application-packages> 
    <wls:prefer-application-resources> 
     <wls:resource-name>org/slf4j/impl/StaticLoggerBinder.class</wls:resource-name> 
    </wls:prefer-application-resources>  
</wls:weblogic-application> 
Các vấn đề liên quan