Tự động thay đổi cấp độ log4j


127

Các cách tiếp cận khác nhau để thay đổi cấp độ nhật ký log4j là gì, do đó tôi sẽ không phải triển khai lại ứng dụng. Những thay đổi sẽ là vĩnh viễn trong những trường hợp đó?




3
Câu hỏi cập nhật cho log4j2: stackoverflow.com/questions/23434252/ cấp
slaadvak

1
LƯU Ý rằng (hầu hết) mọi thứ trên trang này là về log4j, không phải log4j2. Toàn bộ trang này đầy sự nhầm lẫn và đánh giá sai đến mức KHÔNG HỀ. Tới stackoverflow.com/questions/23434252/... như @slaadvak khuyến cáo.
Lambart

Câu trả lời:


86

Thay đổi cấp độ nhật ký là đơn giản; Sửa đổi các phần khác của cấu hình sẽ đặt ra một cách tiếp cận sâu hơn.

LogManager.getRootLogger().setLevel(Level.DEBUG);

Những thay đổi là vĩnh viễn thông qua cuộc sống của Logger. Khi khởi tạo lại, cấu hình sẽ được đọc và sử dụng khi cài đặt mức khi chạy không duy trì thay đổi cấp.

CẬP NHẬT: Nếu bạn đang sử dụng Log4j 2, bạn nên loại bỏ các cuộc gọi setLeveltheo tài liệu vì điều này có thể đạt được thông qua các lớp thực hiện.

Các lệnh gọi tới logger.setLevel () hoặc các phương thức tương tự không được hỗ trợ trong API. Các ứng dụng nên loại bỏ những thứ này. Chức năng tương đương được cung cấp trong các lớp triển khai Log4j 2 nhưng có thể khiến ứng dụng dễ bị thay đổi trong nội bộ Log4j 2.


5
Chỉ dành cho phụ thuộc thời gian chạyLogManager.getLogger(Class.forName("org.hibernate.util.JDBCExceptionReporter")).setLevel(Level.FATAL);
CelinHC

8
Lưu ý rằng API log4j 2 không cung cấp phương thức "setLevel".
ChrisCantrell

5
Nhưng điều này chỉ thiết lập logger gốc, phải không? Nếu các cấp độ riêng lẻ được đặt cho logger dưới gốc, việc thiết lập logger gốc sẽ không có hiệu lực đối với các LOGGER đó. Chúng ta sẽ không phải làm một cái gì đó như root.getLoggerRep repository (). GetCienC chuyên (), lặp lại qua từng phiên bản của logger và đặt LEVEL cho mỗi logger? @AaronMcIver
TheMonkWhoSoldHisCode

8
@ChrisCantrell Log4j 2 cung cấp một cách để làm điều này , mặc dù nó không đơn giản như vậy.
CorayThan

2
Log4j2 có thể được cấu hình để làm mới cấu hình của nó bằng cách quét tệp log4j2.xml (hoặc tương đương) theo các khoảng thời gian nhất định. Ví dụ: <Status status = "warn" MonitorInterval = "5" name = "tryItApp" gói = "">
Kimball Robinson

89

Cơ quan giám sát hồ sơ

Log4j có thể xem log4j.xmltệp để thay đổi cấu hình. Nếu bạn thay đổi tệp log4j, log4j sẽ tự động làm mới các mức nhật ký theo các thay đổi của bạn. Xem tài liệu của org.apache.log4j.xml.DOMConfigurator.configureAndWatch(String,long) để biết chi tiết. Thời gian chờ mặc định giữa các lần kiểm tra là 60 giây. Những thay đổi này sẽ liên tục, vì bạn trực tiếp thay đổi tệp cấu hình trên hệ thống tệp. Tất cả những gì bạn cần làm là gọi DOMConfigurator.configureAndWatch () một lần.

Thận trọng: Phương thức configureAndWatch không an toàn để sử dụng trong môi trường J2EE do rò rỉ Chủ đề

JMX

Một cách khác để đặt mức ghi nhật ký (hoặc cấu hình lại nói chung) log4j là sử dụng JMX. Log4j đăng ký loggers của nó là JMX MBeans. Sử dụng các máy chủ ứng dụng bảng điều khiển MBeanServer (hoặc jconsole.exe của JDK), bạn có thể cấu hình lại từng logger riêng lẻ. Những thay đổi này không liên tục và sẽ được đặt lại về cấu hình như được đặt trong tệp cấu hình sau khi bạn khởi động lại ứng dụng (máy chủ).

Tự lập

Theo mô tả của Aaron, bạn có thể đặt cấp độ nhật ký theo chương trình. Bạn có thể thực hiện nó trong ứng dụng của bạn theo cách bạn muốn nó xảy ra. Ví dụ: bạn có thể có GUI trong đó người dùng hoặc quản trị viên thay đổi cấp độ nhật ký và sau đó gọi các setLevel()phương thức trên logger. Cho dù bạn có duy trì cài đặt ở đâu đó hay không là tùy thuộc vào bạn.


8
Một lời cảnh báo liên quan đến phương pháp theo dõi log4j: "Bởi vì configureAndWatch khởi chạy một luồng theo dõi riêng biệt và vì không có cách nào để ngăn chặn luồng này trong log4j 1.2, nên phương thức configureAndWatch không an toàn để sử dụng trong J2EE enConnironments nơi các ứng dụng được tái chế". Tham khảo: Câu hỏi thường gặp của Log4J
Somu

Nếu tôi sử dụng chức năng configureAndWatch của Log4j, tôi có thể dừng luồng giám sát đó trong phương thức @PostDestroy của EJB (đó là một chỉ báo đủ tốt khi container bị tắt) Đó là gì? Hoặc là có nhiều hơn cho nó mà tôi đang thiếu ..!
robin bajaj

xin lỗi tôi có nghĩa là phương pháp @PreDestroy
robin bajaj

" Log4j đăng ký logger của nó là JMX MBeans. ". Servlet của tôi sử dụng log4j 1.2 Tôi không thấy bất kỳ MB4 log4j nào.
Abdull

Tất cả những gì bạn cần làm là gọi DOMConfigurator.configureAndWatch () một lần. Làm thế nào tôi có thể đạt được điều này ?
gstackoverflow

5

Log4j2 có thể được cấu hình để làm mới cấu hình của nó bằng cách quét tệp log4j 2 .xml (hoặc tương đương) theo các khoảng thời gian nhất định. Chỉ cần thêm tham số " MonitorInterval " vào thẻ cấu hình của bạn. Xem dòng 2 của tệp log4j 2 .xml mẫu , thông báo cho log4j quét lại cấu hình của nó nếu hơn 5 giây đã trôi qua kể từ sự kiện nhật ký cuối cùng.

<?xml version="1.0" encoding="UTF-8" ?>
<Configuration status="warn" monitorInterval="5" name="tryItApp" packages="">

    <Appenders>
        <RollingFile name="MY_TRY_IT"
                     fileName="/var/log/tryIt.log"
                     filePattern="/var/log/tryIt-%i.log.gz">
            <Policies>
                <SizeBasedTriggeringPolicy size="25 MB"/>
            </Policies>
            ...
        </RollingFile>
    </Appenders>


    <Loggers>
        <Root level="error">
            <AppenderRef ref="MY_TRY_IT"/>
        </Root>
    </Loggers>

</Configuration>

Có thêm các bước để thực hiện công việc này nếu bạn đang triển khai đến một cá thể tomcat, bên trong IDE hoặc khi sử dụng spring boot. Điều đó có vẻ hơi ngoài phạm vi ở đây và có lẽ là một câu hỏi riêng biệt.


@vsingh, bạn đang triển khai bên trong boot mùa xuân, tomcat, hoặc một container hoặc với IDE? Đôi khi, có thể có các bước bổ sung trong các trường hợp đó (không phải lỗi của log4j2) - về cơ bản, ứng dụng không thể thấy tệp thay đổi vì nó được sao chép sang một vị trí khác bởi một khung hoặc công cụ.
Kimball Robinson

Xin chào Tôi đã thử nghiệm điều này trên Jboss6.4 và tôi đã cập nhật tệp cấu hình log4j2 dưới vị trí (bên trong tệp .war) nơi ứng dụng có thể xem tệp. Tuy nhiên nó vẫn không hoạt động. Bất kì lời đề nghị nào?
MidTierDeveloper

3

Câu trả lời này sẽ không giúp bạn thay đổi mức ghi nhật ký một cách linh hoạt, bạn cần khởi động lại dịch vụ, nếu bạn khởi động lại dịch vụ tốt, vui lòng sử dụng giải pháp bên dưới

Tôi đã làm điều này để Thay đổi cấp độ log4j và nó hoạt động với tôi, tôi chưa giới thiệu bất kỳ tài liệu nào. Tôi đã sử dụng giá trị thuộc tính hệ thống này để đặt tên logfile của mình. Tôi cũng đã sử dụng kỹ thuật tương tự để thiết lập mức ghi nhật ký và nó đã hoạt động

đã thông qua điều này dưới dạng tham số JVM (Tôi sử dụng Java 1.7)

Xin lỗi, điều này sẽ không thay đổi động mức ghi nhật ký, nó yêu cầu khởi động lại dịch vụ

java -Dlogging.level=DEBUG -cp xxxxxx.jar  xxxxx.java

trong tệp log4j.properIES, tôi đã thêm mục này

log4j.rootLogger=${logging.level},file,stdout

Tôi đã thử

 java -Dlogging.level=DEBUG -cp xxxxxx.jar  xxxxx.java
 java -Dlogging.level=INFO-cp xxxxxx.jar  xxxxx.java
 java -Dlogging.level=OFF -cp xxxxxx.jar  xxxxx.java

Tất cả đều hoạt động. hi vọng điêu nay co ich!

Tôi có các phụ thuộc sau trong tệp pom.xml của mình

<dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
</dependency>

<dependency>
    <groupId>log4j</groupId>
    <artifactId>apache-log4j-extras</artifactId>
    <version>1.2.17</version>
</dependency>

2
Bất cứ điều gì bạn đề cập có vẻ ổn, nhưng câu hỏi là về việc thay đổi động mức ghi nhật ký.
Azim

Để làm điều này, bạn cần khởi động lại dịch vụ. Điều này không thay đổi mức ghi nhật ký một cách linh hoạt.
kk.

2

Với log4j 1.x tôi thấy cách tốt nhất là sử dụng DOMConfigurator để gửi một trong các cấu hình nhật ký XML được xác định trước (giả sử, một để sử dụng bình thường và một để gỡ lỗi).

Sử dụng những thứ này có thể được thực hiện với một cái gì đó như thế này:

  public static void reconfigurePredefined(String newLoggerConfigName) {
    String name = newLoggerConfigName.toLowerCase();
    if ("default".equals(name)) {
      name = "log4j.xml";
    } else {
      name = "log4j-" + name + ".xml";
    }

    if (Log4jReconfigurator.class.getResource("/" + name) != null) {
      String logConfigPath = Log4jReconfigurator.class.getResource("/" + name).getPath();
      logger.warn("Using log4j configuration: " + logConfigPath);
      try (InputStream defaultIs = Log4jReconfigurator.class.getResourceAsStream("/" + name)) {
        new DOMConfigurator().doConfigure(defaultIs, LogManager.getLoggerRepository());
      } catch (IOException e) {
        logger.error("Failed to reconfigure log4j configuration, could not find file " + logConfigPath + " on the classpath", e);
      } catch (FactoryConfigurationError e) {
        logger.error("Failed to reconfigure log4j configuration, could not load file " + logConfigPath, e);
      }
    } else {
      logger.error("Could not find log4j configuration file " + name + ".xml on classpath");
    }
  }

Chỉ cần gọi tên này với tên cấu hình phù hợp và đảm bảo rằng bạn đặt các mẫu trên đường dẫn lớp.


điểm kích hoạt của phương pháp này là gì? Làm thế nào để biết phương thức này phải được gọi bất cứ khi nào có thay đổi trong cấu hình log4j?
vào

Tôi vẫn không hiểu ý bạn là "theo yêu cầu". Bạn có thể vui lòng hiển thị một đoạn mà bạn nối phương thức này không?
asg

2
Ở đây bạn đi: Đây là một đoạn từ Bộ điều khiển nơi chúng tôi sử dụng nó. Chúng tôi có một trang quản trị với một số liên kết để tự động cấu hình lại ghi nhật ký, sau đó tạo một GET cho liên kết / admin / setLogLevel? Level = Error và sau đó chúng tôi bắt gặp điều này trong trình điều khiển như @RequestMapping (value = "setLogLevel", method = RequestMethod.GET) công khai ModelAndView setLogLevel (@RequestParam (value = "level", required = true) Chuỗi mức) {Log4jReconfigurator.reconfigureEx hiện (level);
ISparkes

Vì vậy, "theo yêu cầu" có nghĩa là "khi người dùng nhấp vào nút" trong trường hợp của tôi
ISparkes

À, có bạn Vì vậy, bảng điều khiển quản trị của bạn phải đưa ra yêu cầu gọi phương thức này.
vào

0

Tôi đã sử dụng phương pháp này thành công để giảm mức độ chi tiết của nhật ký "org.apache.http":

ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger("org.apache.http");
logger.setLevel(Level.TRACE);
logger.setAdditive(false);

0

Đối với API log4j 2, bạn có thể sử dụng

Logger logger = LogManager.getRootLogger();
Configurator.setAllLevels(logger.getName(), Level.getLevel(level));

-1

Nếu bạn muốn thay đổi mức ghi nhật ký của tất cả các logger, hãy sử dụng phương pháp dưới đây. Điều này sẽ liệt kê trên tất cả các logger và thay đổi cấp độ đăng nhập thành cấp độ nhất định. Vui lòng đảm bảo rằng bạn KHÔNG có thuộc log4j.appender.loggerName.Threshold=DEBUGtính được đặt trong log4j.propertiestệp của mình .

public static void changeLogLevel(Level level) {
    Enumeration<?> loggers = LogManager.getCurrentLoggers();
    while(loggers.hasMoreElements()) {
        Logger logger = (Logger) loggers.nextElement();
        logger.setLevel(level);
    }
}

-3

Bạn có thể sử dụng đoạn mã sau

((ch.qos.logback.classic.Logger)LoggerFactory.getLogger(packageName)).setLevel(ch.qos.logback.classic.Level.toLevel(logLevel));

Tôi phải thử nó.
dùng2045474
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.