Làm cách nào để gửi java.util.logging tới log4j?


84

Tôi có một ứng dụng hiện có thực hiện tất cả việc ghi nhật ký của nó dựa trên log4j. Chúng tôi sử dụng một số thư viện khác cũng sử dụng log4j hoặc đăng nhập chống lại Commons Logging, kết thúc bằng cách sử dụng log4j dưới các trang bìa trong môi trường của chúng tôi. Một trong những phụ thuộc của chúng tôi thậm chí còn ghi nhật ký đối với slf4j, điều này cũng hoạt động tốt vì cuối cùng nó cũng ủy quyền cho log4j.

Bây giờ, tôi muốn thêm ehcache vào ứng dụng này cho một số nhu cầu bộ nhớ đệm. Các phiên bản trước của ehcache đã sử dụng tính năng ghi nhật ký bằng commons, điều này sẽ hoạt động hoàn hảo trong trường hợp này, nhưng kể từ phiên bản 1.6-beta1, chúng đã loại bỏ sự phụ thuộc vào ghi nhật ký bằng dấu phẩy và thay thế bằng java.util.logging.

Không thực sự quen thuộc với ghi nhật ký JDK tích hợp có sẵn với java.util.logging, có một cách dễ dàng để có bất kỳ thông báo nhật ký nào được gửi đến JUL được ghi vào nhật ký dựa trên log4j, vì vậy tôi có thể sử dụng cấu hình hiện có của mình và thiết lập cho bất kỳ ghi nhật ký nào sắp tới từ ehcache?

Nhìn vào javadocs cho JUL, có vẻ như tôi có thể thiết lập một loạt các biến môi trường để thay đổi LogManagerviệc triển khai nào được sử dụng và có lẽ sử dụng nó để bọc log4j Loggers trong Loggerlớp JUL . Đây có phải là cách tiếp cận chính xác?

Thật trớ trêu khi việc sử dụng ghi nhật ký JDK tích hợp của thư viện lại gây ra một vấn đề đau đầu khi (hầu hết) phần còn lại của thế giới đang sử dụng thư viện của bên thứ ba.

Câu trả lời:


37

Một cách tiếp cận mà tôi đã sử dụng thành công là sử dụng slf4j làm API ghi nhật ký chính của tôi. Sau đó, tôi có liên kết slf4j với log4j. Các phụ thuộc của bên thứ 3 sử dụng các khung công tác khác (như JUL) có thể được bắc cầu với slf4j.


2
Liên kết tốt, nhưng tôi nghĩ ý bạn là # jul-to-slf4j
araqnid

Điều này nghe có vẻ là một cách tiếp cận tốt, ngoại trừ tôi dường như không thể làm cho nó hoạt động :(
matt b

2
Ngoài ra, tôi không thể tin rằng một thư viện phổ biến như ehcache lại chuyển sang một thứ gì đó như java.util.logging - có vẻ rất dễ hiểu
matt b

1
@matt b, JUL luôn hiện diện trong thời gian chạy Java nên nó yêu cầu ít phụ thuộc bên ngoài nhất. Tuy nhiên, trong mắt tôi, đó là một ví dụ thực sự về mã được viết bởi những người không có kinh nghiệm về cách sử dụng của mã đó. Hệ thống cấu hình khá bất tiện.
Thorbjørn Ravn Andersen

1
Vấn đề bạn gặp phải là nếu bạn nối SLF4J với JUL, hiệu suất ghi nhật ký sẽ rất kinh khủng. Cụ thể, mỗi dòng nhật ký bạn tạo kết quả trong một ngoại lệ được ném ra để xác định ngữ cảnh trình ghi nhật ký nào sẽ sử dụng. Điều đó tạo ra rất nhiều chi phí và làm chậm quá trình
Egwor

19

Chúng tôi sử dụng SLF4J trong dự án hiện tại của mình và nó hoạt động rất tốt cho chúng tôi. SLF4J được viết bởi Ceki Gülcü, người tạo ra Log4J và anh ấy đã hoàn thành một công việc thực sự tuyệt vời. Trong mã của chúng tôi, chúng tôi sử dụng trực tiếp các API ghi nhật ký SLF4J và chúng tôi định cấu hình SLF4J để các lệnh gọi từ các API Jakarta Commons Logging (JCL), java.util.logging (JUL) và Log4J đều được kết nối với các API SLF4J. Chúng tôi cần làm điều đó vì giống như bạn, chúng tôi sử dụng các thư viện của bên thứ ba (mã nguồn mở) đã chọn các API ghi nhật ký khác nhau.

Ở cuối SLF4J, bạn định cấu hình nó để sử dụng triển khai trình ghi nhật ký cụ thể. Nó đi kèm với một trình ghi nhật ký nội bộ hoặc "đơn giản" và bạn có thể ghi đè điều này bằng Log4J, JUL hoặc Logback . Việc cấu hình được thực hiện đơn giản bằng cách thả vào các tệp jar khác nhau trong classpath của bạn.

Ban đầu, chúng tôi sử dụng triển khai Logback, cũng được viết bởi Ceki Gülcü. Điều này rất mạnh mẽ. Tuy nhiên, sau đó chúng tôi quyết định triển khai ứng dụng của mình tới máy chủ ứng dụng Glassfish Java EE, máy chủ mà trình xem nhật ký mong đợi các thông báo có định dạng JUL. Vì vậy, hôm nay tôi đã chuyển từ Logback sang JUL và chỉ trong vài phút, tôi đã thay thế hai bình Logback bằng một jar SLF4J kết nối nó với triển khai JUL.

Vì vậy, giống như @overthink, tôi chân thành khuyên bạn nên sử dụng SLF4J trong thiết lập của bạn.


8
Ceki cần bao nhiêu lần để phát minh lại một khung ghi nhật ký / Fascade?
mP.

@mP: Ghi nhật ký có thể không hấp dẫn, nhưng đó là một nhu cầu thiết yếu đối với phần mềm cấp thương mại quy mô lớn. Và SLF4J giải quyết vấn đề tích hợp mã sử dụng các khung ghi nhật ký khác nhau (được Sun bầu chọn cấp bách hơn để phát triển java.utils.logging thay vì sử dụng Log4J).
Jim Ferrans

3
@mP, slf4j là cần thiết vì công việc tồi tệ mà Sun đã làm với JUL. Logback là một nhánh của log4j, không phải là một dự án mới.
Thorbjørn Ravn Andersen

3
Tôi thấy đăng nhập lại là cần thiết, nếu không có gì khác, đó không phải là Apache và nó thực sự được ghi lại.
Spencer Kormos

13

Có một giải pháp thay thế đơn giản hơn SLF4J để kết nối JUL với log4j, xem http://people.apache.org/~psmith/logging.apache.org/sandbox/jul-log4j-bridge/examples.html

Bạn chỉ cần đặt jul-log4j-bridge trên classpath và thêm một thuộc tính hệ thống:

-Djava.util.logging.manager=org.apache.logging.julbridge.JULBridgeLogManager

jul-log4j-bridge không có trong Maven Central và có thể được tìm nạp từ kho này:

<repository>
  <id>psmith</id>
  <url>http://people.apache.org/~psmith/logging.apache.org/repo</url>
  <releases>
    <enabled>false</enabled>
  </releases>
</repository>

và sau đó được sử dụng với:

<dependency>
  <groupId>org.apache.logging</groupId>
  <artifactId>apache-jul-log4j-bridge</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <scope>test</scope>
  <exclusions>
    <exclusion>
      <groupId>log4j</groupId>
      <artifactId>apache-log4j-component</artifactId>
    </exclusion>
  </exclusions>
</dependency>

Cũng có thể xây dựng lại nó từ các nguồn bằng các bước sau:

  1. svn co http://svn.apache.org/repos/asf/logging/sandbox/jul-to-log4j-bridge/
  2. chỉnh sửa pom.xml, thay thế phụ thuộc trên log4j: log4j: 1.2.15 bằng log4j: apache-log4j-extras: 1.2.17 và xóa phụ thuộc trên apache-log4j-component
  3. gói mvn

4
Tôi nghĩ nó đơn giản hơn vì nó có thể được thực hiện mà không cần thay đổi mã của bạn, bạn chỉ cần thêm một thuộc tính hệ thống. SLF4J chưa đề xuất một cơ chế tương tự, bạn có thể thay đổi mã hoặc logging.propertiestệp.
Emmanuel Bourg

1
Điều này không tồn tại trong log4j2, rất tiếc :(
BeepDog,

JulLog4jBridge.assimilate();o_0
Bastian Voigt

2
CẢNH BÁO! jul-log4j-bridgesử dụng gói không bao giờ được phát hành apache-log4j-companions(một cổng lùi từ cái bị bỏ rơi log4j 1.3). Bạn sẽ gặp khó khăn khi xây dựng nó. Đương nhiên, bản thân cây cầu cũng bị bỏ rơi trước khi phát hành.
ivan_pozdeev

@ivan_pozdeev Điểm hay, cảm ơn bạn. Tôi đã thêm hướng dẫn để xây dựng nó.
Emmanuel Bourg,

9

THÁNG 10 NĂM 2014

Vì phiên bản 2.1 của log4j tồn tại thành phần log4j-jul, cho phép chính xác điều này. Tuy nhiên, trong trường hợp bạn đang sử dụng log4j 1, bạn phải có thể nâng cấp lên log4j2 để sử dụng phương pháp này.

Bộ điều hợp ghi nhật ký JDK

Class LogManager

Di chuyển từ log4j 1.x sang log4j 2


2
Tính đến bây giờ (giữa 2018) điều này sẽ là câu trả lời được chấp nhận
rmuller

Đối với độc giả trong tương lai: Tôi xác nhận điều này đang hoạt động. Vì vậy, về cơ bản (1) thêm điều này vào pom mvnrepository.com/artifact/org.apache.logging.log4j/log4j-jul của bạn và (2) thêm thuộc tính hệ thống trong liên kết đầu tiên (ví dụ: trong tham số JVM thêm -Djava. use.logging.manager = org.apache.logging.log4j.jul.LogManager)
Hossam El-Deen

3

Trang web slf4j mà tôi tin rằng có một cầu nối để truyền các sự kiện java.util.logging qua slf4j (và do đó đến log4j).

Có, bản tải xuống SLF4J chứa jul-to-slf4j mà tôi tin rằng thực hiện đúng như vậy. Nó chứa một trình xử lý JUL để chuyển các bản ghi tới SLF4J.


2

@Yishai - Cảm ơn bạn đã đăng liên kết tới wiki của tôi. Ví dụ ở đó chuyển hướng JUL sang Log4J và tôi đã để nó chạy trong hệ thống sản xuất trong một vài năm. JBoss 5.x đã chuyển hướng JUL sang Log4J, vì vậy tôi đã gỡ bỏ nó khi chúng tôi nâng cấp. Tôi có một cái mới hơn chuyển hướng đến SLF4J, cái mà tôi sử dụng cho một số việc bây giờ. Tôi sẽ đăng nó khi tôi có cơ hội.

Tuy nhiên, SLF4J đã có nó:

http://mvnrepository.com/artifact/org.slf4j/jul-to-slf4j


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.