Làm thế nào để ngăn chặn logback xuất ra trạng thái của chính nó khi bắt đầu mỗi bản ghi?


145

Đây có vẻ là một lỗi bất cẩn, nhưng tôi dường như không thể tìm ra nguyên nhân. Đăng nhập bằng logback / slf4j (phiên bản mới nhất slf4j-api-1.6.1, lõi logback / classic 0.9.24). Cấu hình nhật ký đơn giản nhất để thử nghiệm là:

<configuration>
 <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
  <layout class="ch.qos.logback.classic.PatternLayout">
   <!-- DONT USE THIS FORMATTER FOR LIVE LOGGING THE %L LINE NUMBER OUTPUTTER IS SLOW -->
   <pattern>%le %-1r [%c{1}:%L] %m%n</pattern>
  </layout>
 </appender>
 <root level="DEBUG">
  <appender-ref ref="stdout" />
 </root>
</configuration>

Mỗi thiết lập nhật ký bắt đầu với các dòng trạng thái nội bộ của logback:

11:21:27,825 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
11:21:27,826 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback-test.xml] at [file:.../logback-test.xml]
11:21:28,116 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
11:21:28,124 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
11:21:28,129 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [stdout]
11:21:28,180 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Pushing component [layout] on top of the object stack.
11:21:28,206 |-WARN in ch.qos.logback.core.ConsoleAppender[stdout] - This appender no longer admits a layout as a sub-component, set an encoder instead.
11:21:28,206 |-WARN in ch.qos.logback.core.ConsoleAppender[stdout] - To ensure compatibility, wrapping your layout in LayoutWrappingEncoder.
11:21:28,206 |-WARN in ch.qos.logback.core.ConsoleAppender[stdout] - See also http://logback.qos.ch/codes.html#layoutInsteadOfEncoder for details
11:21:28,207 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to DEBUG
11:21:28,207 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [stdout] to Logger[ROOT]

theo tài liệu, logback định dạng sử dụng cho mặc định. Sau đó, nó kết thúc việc đọc cấu hình (được thiết lập để xuất ra một định dạng khác) và tiếp tục với đầu ra được định dạng đúng. Có một tham số cấu hình <configuration debug="false">không ảnh hưởng đến điều này.

Bất cứ ai biết làm thế nào để tắt điều này?


Các phiên bản gần đây của logback nhanh hơn nhiều khi tính% L.
Thorbjørn Ravn Andersen

@ ThorbjørnRavnAndersen các tài liệu nói "L / line: Tạo thông tin số dòng không đặc biệt nhanh. Vì vậy, nên tránh sử dụng nó trừ khi tốc độ thực thi không phải là vấn đề." FWIW: logback.qos.ch/manual/layouts.html (vì vậy có thể nhanh hơn nhưng vẫn không siêu nhanh hoặc một cái gì đó ...)
rogerdpack 23/12/19

@rogerdpack có. Nó được tìm thấy bằng cách phân tích dấu vết ngăn xếp của một ngoại lệ. Điều đó đã trở nên nhanh hơn.
Thorbjørn Ravn Andersen

Câu trả lời:


249

Nếu bạn đặt debugthuộc tính của configurationphần tử thành true, bạn sẽ nhận được tất cả thông tin trạng thái cho bảng điều khiển. Nếu đây là vấn đề của bạn, chỉ cần đặt thành sai hoặc xóa nó.

Nếu bạn có bất kỳ vấn đề cấu hình nào về cấp độ WARNtrở lên, bạn cũng sẽ nhận được tất cả thông tin trạng thái được ghi vào bảng điều khiển (bao gồm cả thông báo về cấp độ INFO). Giải pháp tốt nhất cho vấn đề này là khắc phục sự cố (trong trường hợp của bạn thay thế <layout>phần tử bằng một <encoder>phần tử).

Nếu bạn vì một số lý do không thể khắc phục sự cố, nhưng muốn xóa thông tin trạng thái khỏi bảng điều khiển, thay vào đó bạn có thể định cấu hình thay thế StatusListener. Sử dụng NopStatusListenerđể loại bỏ hoàn toàn thông tin trạng thái:

<configuration>
  <statusListener class="ch.qos.logback.core.status.NopStatusListener" />
  <!-- etc -->
</configuration>

9
Đây là câu trả lời đúng, nó nên được nâng cao hơn nữa, cảm ơn bạn. (logback 1.0.11)
Jakub Kulhan

3
Điều này đã làm việc. Tôi không hoàn toàn rõ ràng rằng các INFOthông điệp tường trình cũng sẽ biến mất, nhưng thực tế chúng cũng vậy. Tôi biết câu trả lời nói lên điều này, nhưng vì một số lý do, nó không rõ ràng với tôi. Rất rõ ràng: khắc phục sự cố bộ mã hóa / bố cục và không chỉ các thông báo cảnh báo sẽ biến mất mà các thông tin thông tin cũng sẽ biến mất, mặc dù chúng không liên quan đến vấn đề.
Jason

3
Không hoạt động với thuộc tính gỡ lỗi, nhưng hoạt động hoàn hảo với trình nghe trạng thái.
Ameba Spugnosa

Cảm ơn - người nghe trạng thái cần thiết.
Ezekiel Victor

2
Cẩn thận sử dụng phương pháp này, nó có vẻ hoạt động nhưng nó che giấu sự thật rằng bạn có lỗi cấu hình trong tệp của mình. Vấn đề thực sự là các bản ghi WARN, các vấn đề này cần được sửa trong cấu hình, sau đó tất cả các bản ghi inc. THÔNG TIN đi xa.
teknopaul

45

Như được mô tả trong tài liệu , nếu cảnh báo hoặc lỗi xảy ra trong quá trình phân tích tệp cấu hình, logback sẽ tự động in dữ liệu trạng thái trên bàn điều khiển.

Theo dõi http://logback.qos.ch/codes.html#layoutInsteadOfEncoder tức là liên kết được đề cập bởi logback trong thông điệp cảnh báo của nó. Khi bạn thực hiện theo các bước được đề cập trong đó, nghĩa là, nếu bạn thay thế phần tử <layout> bằng <encoder>, logback sẽ dừng in thông báo trên bảng điều khiển.


4
Sắp xếp đúng, mặc dù bạn đã chỉ cho tôi đi đúng hướng. Tôi đã thay đổi cú pháp bộ mã hóa mà không có hiệu lực, mặc dù hóa ra việc loại bỏ một dòng khác trong logback.xml đang gây ra cảnh báo đã lừa. Điều lừa đảo ở đây là đầu ra dường như xuất ra các quyết định được đưa ra trước khi nó thực sự phân tích tệp logback của bạn, (1> KHÔNG thể tìm thấy tài nguyên [logback.groovy], 2> Tài nguyên được tìm thấy [logback-test.xml]). Thật khó hiểu khi sửa lỗi trong bài kiểm tra logback để ẩn các thông báo trạng thái cho những gì xảy ra trước khi nó được phân tích cú pháp. Nhưng cảm ơn cho con trỏ.
Steve B.

5
Tôi nghĩ điều Steve B. muốn nói là nó phản trực giác (hoặc ít nhất là không theo quy tắc) rằng Logback nên triệt tiêu tất cả các thông báo trạng thái, bao gồm (và đặc biệt) những thông báo trước khi tải tệp cấu hình, trừ khi nó gặp lỗi sau khi cấu hình. Khi bạn không quen với quy tắc này và lần đầu tiên nhìn thấy các thông báo trạng thái này (ngụ ý cảnh báo hoặc lỗi cấu hình), hầu hết người dùng sẽ mong đợi rằng một khi lỗi được khắc phục, Logback sẽ không in các thông báo lỗi liên quan nữa, nhưng tiếp tục in các thông báo lỗi khác thông điệp trạng thái.
Derek Mahar

6
FWIW, tôi cũng thấy hành vi này khá khó hiểu. Việc phát ra các thông báo cấp INFO thực hiện công việc khá tốt là ẩn các thông báo LRI cho tôi biết những gì tôi thực sự cần sửa. Việc thiếu một DTD, hoặc bất kỳ đặc điểm kỹ thuật nào khác về cú pháp của tệp cấu hình, khiến nó trở thành một bản dùng thử để gỡ lỗi ngay cả khi tôi phát hiện ra thông báo.
Tom Anderson

4
@Ceki: Cuối cùng tôi đã tìm ra nó: Cách thứ 2 để kích hoạt các tin nhắn này là có debug="true"thuộc tính trong configurationphần tử của logback.xml. Hãy đề cập đến điều này vì lợi ích của những người khác rơi vào lỗ hổng này!
Carl Smotricz

6
Có lẽ trước câu lệnh INFO đầu tiên cần có 'Cảnh báo được phát hiện, xuất ra tất cả thông tin trạng thái trong quá khứ. Để dừng thông báo này, hãy sửa các cảnh báo / lỗi của bạn '
David Roussel

7

Câu trả lời của Ceki là đúng:

(...) Nếu cảnh báo hoặc lỗi xảy ra trong quá trình phân tích tệp cấu hình, logback sẽ tự động in dữ liệu trạng thái trên bàn điều khiển.

Khi bạn hiểu đúng, sẽ không có bất kỳ ô nhiễm nào trong các dòng đầu tiên của nhật ký của bạn nữa.

Kể từ tháng 3 năm 2015, trong Logback 1.1.2 , bạn cần sử dụng <encoder>thành phần phụ - <layout>hiện không được chấp nhận và nếu sử dụng nó, thông báo lỗi sẽ xuất hiện. Bạn không thể kiểm soát điều này, nó hành vi mặc định Logback .

Một số lớp nội bộ cũng đã được đổi tên và thậm chí các ví dụ trong trang hướng dẫn của họ đã lỗi thời!

Đây là đoạn mã từ trang Trợ giúp Mã lỗi của họ , có cách chính xác để định cấu hình bộ ghi. Điều này đã khắc phục vấn đề hoàn toàn trong dự án của tôi. http://logback.qos.ch/codes.html#layoutInsteadOfEncoder

<appender name="FILE" class="ch.qos.logback.core.FileAppender">
  <file>testFile.log</file>
  ...
  <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
    <pattern>%msg%n</pattern>
  </encoder>
</appender>

4

Tôi nhận ra Steve đã tìm thấy bản sửa lỗi nhưng anh ta đã không đề cập đến nó trên luồng. Trong trường hợp nếu bất kỳ người nào khác gặp vấn đề tương tự ở đây là sửa chữa.

Thay thế các phần tử "<layout>" bằng "<encoder> .. </ encoder>"

Thủ phạm là: <layout class = "ch.qos.logback. Classic.PotypeLayout">


1
Nếu bạn muốn xóa hoàn toàn các tin nhắn đó, hãy sử dụng NopStatusListener như Rasmus đã mô tả. Cách tiếp cận bộ mã hóa và bố cục không ngăn chặn các thông báo, chẳng hạn như 'logback.groovy không tìm thấy'. Tôi đang sử dụng logback-classic 1.1.3 (Tháng 3 năm 2015)
Cristian Botiza

3

Bản thân tôi đã gặp khó khăn với vấn đề tương tự, có một loạt các dòng được ghi lại ngay từ đầu không liên quan đến mã của tôi. Đây là cách tôi sửa nó.

<configuration debug="false">

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

<root level="error">
    <appender-ref ref="STDOUT" />
</root>

<logger name="fun.n.games" level="DEBUG" />

Điều này đang chạy với mục sau trong pom.xml

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

2

Điều này dường như được cố định trong 0.9,29. Chỉ cần thực hiện một số thử nghiệm. Không có tin tức Joran nữa. Tôi đoán đây là cam kết sửa chữa.


2

Tôi đã có cùng một vấn đề tôi đã thêm dòng này

        <!-- Stop output INFO at start -->
        <statusListener class="ch.qos.logback.core.status.NopStatusListener" />

trong logback và nó hoạt động tốt


Điều này hoạt động, tuy nhiên nó cũng ngăn chặn đầu ra thông báo ERROR - không có đầu ra nào được tạo ra khi xảy ra sự cố cấu hình logback nghiêm trọng.
Honza

0

Tôi đã thử mọi thứ và không có gì làm việc cho tôi. Vấn đề của tôi là do nhiều tệp logback.xml trong đường dẫn lớp của tôi. Đây là trường hợp phổ biến trong các dự án đa mô-đun. Khi chỉ có một tệp logback.xml trong đường dẫn lớp, không có sự mơ hồ và vấn đề được giải quyết.


sản lượng nào nó đã cung cấp cho bạn?
rogerdpack 23/12/19

0

Sử dụng logback.groovy:statusListener(NopStatusListener) (trong src/test/resources/logback.groovy) hoạt động.

(Một trường hợp sử dụng hợp lệ là ví dụ nếu làm việc với ANT trong Eclipse, sử dụng logback logging, các lớp học groovy và kiểm tra đơn vị nơi đơn vị xét nghiệm lấy src/test/resources/logback.groovy, nhưng cũng sẽ thấy src/main/resources/logback.groovy(hoặc tương tự), bạn không thể loại trừ (nếu classpath ANT đang nói đến việc sử dụng các classpath dự án).)


0

Tôi thích sử dụng trình lắng nghe trạng thái để tắt nhật ký đăng nhập riêng:

<configuration>
  <statusListener class="ch.qos.logback.core.status.NopStatusListener" />
  ...
</configuration>

Nhưng như đã đề cập, NopStatusListener cũng ngăn hiển thị cảnh báo và lỗi. Vì vậy, bạn có thể viết trình nghe trạng thái tùy chỉnh của mình và thay đổi cấp độ nhật ký cho thủ công:

package com.your.package;

import ch.qos.logback.core.status.OnConsoleStatusListener;
import ch.qos.logback.core.status.Status;

import java.util.List;

public class PrintOnlyWarningLogbackStatusListener extends OnConsoleStatusListener {

    private static final int LOG_LEVEL = Status.WARN;

    @Override
    public void addStatusEvent(Status status) {
        if (status.getLevel() == LOG_LEVEL) {
            super.addStatusEvent(status);
        }
    }

    @Override
    public void start() {
        final List<Status> statuses = context.getStatusManager().getCopyOfStatusList();
        for (Status status : statuses) {
            if (status.getLevel() == LOG_LEVEL) {
                super.start();
            }
        }
    }

}    

Sau đó sử dụng nó trong tệp logback.xml của bạn:

<configuration>
  <statusListener class="com.your.package.PrintOnlyWarningLogbackStatusListener" />
  ...
</configuration>
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.