2011-08-19 34 views
49

Tôi muốn thêm một số câu lệnh log.debug vào một lớp mà tôi đang làm việc và tôi muốn thấy rằng trong đầu ra khi chạy thử nghiệm. Tôi muốn ghi đè lên các thuộc tính log4j trên dòng lệnh, với một cái gì đó như thế này:Làm cách nào để đặt mức log4j trên dòng lệnh?

-Dlog4j.logger.com.mypackage.Thingie=DEBUG 

Tôi thường xuyên làm điều này. Tôi đặc biệt chỉ quan tâm đến một cách để vượt qua điều này trên dòng lệnh. Tôi biết làm thế nào để làm điều đó với một tập tin cấu hình, và điều đó không phù hợp với công việc của tôi.

Trả lời

12

log4j không hỗ trợ trực tiếp điều này.

Vì bạn không muốn tệp cấu hình, rất có thể bạn sử dụng cấu hình có lập trình. Tôi sẽ đề nghị bạn xem xét việc quét tất cả các thuộc tính hệ thống và lập trình rõ ràng những gì bạn muốn dựa trên điều này.

41

Là một phần của đối số jvm của bạn, bạn có thể đặt -Dlog4j.configuration=file:"<FILE_PATH>". Trong đó FILE_PATH là đường dẫn của tệp log4j.properties của bạn. Vui lòng lưu ý rằng kể từ log4j2, biến hệ thống mới để sử dụng là log4j.configurationFile và bạn đặt đường dẫn thực tế vào tệp (ví dụ: không có tiền tố file:) và nó sẽ tự động tải nhà máy dựa trên phần mở rộng của cấu hình file:

-Dlog4j.configurationFile=/path/to/log4jconfig.{ext} 
+3

FILE_PATH thực sự được tìm kiếm trên CLASSPATH, bao gồm các tệp jar bên trong. –

+12

Bạn cần đặt "tệp:" ở phía trước đường dẫn nếu đó là tệp trên đĩa. Nói cách khác ... -Dlog4j.configuration = file: http://stackoverflow.com/questions/778933/log4j-configuration-via-jvm-arguments – crowmagnumb

+0

Điều này hoạt động như được quảng cáo; Tuy nhiên tôi đang cố gắng ghi đè lên một thiết lập của một tập tin thuộc tính trong bình, và sau này xuất hiện để có được thiết lập sau. Lời khuyên nào? –

6

Dựa trên Thorbjørn Ravn Andersens gợi ý tôi đã viết một số mã mà làm công việc này

Thêm dòng sau vào đầu trong phương thức main và nó bây giờ có thể thiết lập mức độ đăng nhập từ dòng COMAND. Điều này đã được thử nghiệm trong một dự án của tôi nhưng tôi mới đến log4j và có thể đã làm một số sai lầm. Nếu vậy, hãy sửa tôi.

Logger.getRootLogger().setLevel(Level.WARN); 
    HashMap<String,Level> logLevels=new HashMap<String,Level>(); 
    logLevels.put("ALL",Level.ALL); 
    logLevels.put("TRACE",Level.TRACE); 
    logLevels.put("DEBUG",Level.DEBUG); 
    logLevels.put("INFO",Level.INFO); 
    logLevels.put("WARN",Level.WARN); 
    logLevels.put("ERROR",Level.ERROR); 
    logLevels.put("FATAL",Level.FATAL); 
    logLevels.put("OFF",Level.OFF); 
    for(String name:System.getProperties().stringPropertyNames()){ 
     String logger="log4j.logger."; 
     if(name.startsWith(logger)){ 
      String loggerName=name.substring(logger.length()); 
      String loggerValue=System.getProperty(name); 
      if(logLevels.containsKey(loggerValue)) 
       Logger.getLogger(loggerName).setLevel(logLevels.get(loggerValue)); 
      else 
       Logger.getRootLogger().warn("unknown log4j logg level on comand line: "+loggerValue); 
     } 
    } 
2

Dựa trên @lijat, đây là cách triển khai đơn giản. Trong ứng dụng dựa trên mùa xuân của tôi, tôi chỉ cần tải nó như là một bean.

public static void configureLog4jFromSystemProperties() 
{ 
    final String LOGGER_PREFIX = "log4j.logger."; 

    for(String propertyName : System.getProperties().stringPropertyNames()) 
    { 
    if (propertyName.startsWith(LOGGER_PREFIX)) { 
     String loggerName = propertyName.substring(LOGGER_PREFIX.length()); 
     String levelName = System.getProperty(propertyName, ""); 
     Level level = Level.toLevel(levelName); // defaults to DEBUG 
     if (!"".equals(levelName) && !levelName.toUpperCase().equals(level.toString())) { 
     logger.error("Skipping unrecognized log4j log level " + levelName + ": -D" + propertyName + "=" + levelName); 
     continue; 
     } 
     logger.info("Setting " + loggerName + " => " + level.toString()); 
     Logger.getLogger(loggerName).setLevel(level); 
    } 
    } 
} 
20

Những câu trả lời này thực sự đã khiến tôi không thể thử điều đơn giản nhất có thể! Chỉ cần xác định một ngưỡng cho một appender (nói, "bàn giao") trong log4j.configuration bạn như vậy:

log4j.appender.console.threshold=${my.logging.threshold} 

Sau đó, trên dòng lệnh, bao gồm các hệ thống sở hữu -Dlog4j.info -Dmy.logging.threshold=INFO. Tôi giả định rằng bất kỳ tài sản nào khác có thể được tham số theo cách này, nhưng đây là cách dễ nhất để tăng hoặc giảm mức ghi nhật ký trên toàn cầu.

+0

Tôi chắc chắn đây là giải pháp đơn giản nhất cho câu hỏi gốc! – Droj

+0

@Droj Có lẽ vậy, nhưng OP muốn làm điều này tất cả trong mã. Chacun một đứa con trai gút. –

+0

Trong trường hợp của tôi, tôi cũng muốn thiết lập nó từ dòng lệnh, nhưng tôi đã có một cấu hình. Tôi chỉ không muốn phải chỉnh sửa các tập tin để có được đăng nhập khác nhau. Tôi đã không đọc nó như là "tất cả trong mã", nhưng có lẽ như vậy ... – Droj

7

Với Log4j2, điều này có thể đạt được bằng cách sử dụng phương thức tiện ích sau được thêm vào mã của bạn.

private static void setLogLevel() { 
    if (Boolean.getBoolean("log4j.debug")) { 
    Configurator.setLevel(System.getProperty("log4j.logger"), Level.DEBUG); 
    } 
} 

Bạn cần những hàng nhập khẩu

import org.apache.logging.log4j.Level; 
import org.apache.logging.log4j.core.config.Configurator; 

Bây giờ gọi phương thức setLogLevel trong chính bạn() hoặc bất cứ nơi nào thích hợp và thông qua dòng lệnh params -Dlog4j.logger=com.mypackage.Thingie-Dlog4j.debug=true.

+1

Điều này sẽ là câu trả lời được chấp nhận bây giờ mà các gói được cập nhật. Cảm ơn bạn đã trả lời cập nhật - Tôi đánh giá cao câu trả lời được cập nhật khi nói đến các câu hỏi lâu dài. Bạn đã tiết kiệm cho tôi một chút thất vọng. –

Các vấn đề liên quan