Change global setting for Logger instances

前端 未结 5 867
小蘑菇
小蘑菇 2020-11-30 01:54

I\'m using java.util.logging.Logger as the logging engine for my application. Each class uses it\'s own logger, i.e., each class has:

private final Logger lo         


        
相关标签:
5条回答
  • 2020-11-30 02:11

    JUL(java.util.logging) is java default logger within jvm.

    Java Logging Technology--see Overview

    So you may find that there is a default config file already in C:\Program Files\Java\jre1.8.0_221\lib\logging.properties

    I recommend that you create a new config file under your project to override the default setting, do as following:

    config file name, logging.properties, all log level can be found in Class Level

    handlers= java.util.logging.ConsoleHandler
    .level= INFO
    java.util.logging.ConsoleHandler.level = ALL
    java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
    java.util.logging.SimpleFormatter.format= [%1$tF %1$tT] [%4$-7s] %5$s %n
    
    # your specific logger level
    com.xyz.foo.level = SEVERE
    

    Then add jvm option to enable the config

    java -Djava.util.logging.config.file="logging.properties" -Duser.country=CN -Duser.language=en
    

    user.country and user.language may have an effect on log message localization

    0 讨论(0)
  • 2020-11-30 02:19

    One easy way is to use a logging properties file, by including this VM argument:

    -Djava.util.logging.config.file="logging.properties" 
    

    where "logging.properties" is the path to a file containing logging configuration. For relative paths, the working directory of the process is significant.

    In that file, include a line like this:

    .level= INFO
    

    This sets the global level, which can be overridden for specific handlers and loggers. For example, a specific logger's level can be overridden like this:

     com.xyz.foo.level = SEVERE
    

    You can get a template for a logging properties file from jre6\lib\logging.properties.

    0 讨论(0)
  • 2020-11-30 02:20

    So I don't entirely like all of the answers here, so I'm going to chime in.

    Config file use

    You're seeing a lot of answers in here telling you to use the config file because it is best practice. I want to explain better how to do this programatically, but before I do, I want to say that I can see where they are coming from, and in the mood of being objective, I will enlighten you a bit (especially because nobody says why its bad practice). I actually want to share what somebody said in a separate StackOverflow answer that is in relation to setting the logger level programatically (Why are the Level.FINE logging messages not showing?):

    This is not recommended, for it would result in overriding the global configuration. Using this throughout your code base will result in a possibly unmanageable logger configuration.

    On that note, I think Andy Thomas has a goodish answer related to not doing it non-programatically.

    Programatically setting the Level

    That being said, I want to go into a bit more detail about doing it programatically, because I think it has its uses.

    Imagine a scenario where you are writing something with a command line interface and you have an option to specify the verbosity of your execution, or even where it goes to (as in dynamic log files). I may be mistaken, but you would probably not want to do this statically in a .conf file. Especially so if you don't want to make your userbase responsible for setting these things (for whatever arbitrary reason) in the config file. This comes at the expense of the above quote, however. Here is an example of how you can do it programatically, keeping all of the existing handlers to whatever level they are at already, and only FileHandler's assume the new level:

    public static void setDebugLevel(Level newLvl) {
        Logger rootLogger = LogManager.getLogManager().getLogger("");
        Handler[] handlers = rootLogger.getHandlers();
        rootLogger.setLevel(newLvl);
        for (Handler h : handlers) {
            if(h instanceof FileHandler)
                h.setLevel(newLvl);
        }
    }
    

    I wanted to expand on this, over the accepted answer for one reason in particular. When doing it programatically, you just want to make sure that you set the level for the logger and the handler(s). The way it works, is it will check to see if the request is too low for the logger, and if it is it will discard it. Then the handler(s) have the same check, so you will want to make sure both the loggers and handlers are set to the level you want it.

    0 讨论(0)
  • 2020-11-30 02:27

    As Andy answered, in most cases you should use the property file and the VM argument, thus its independent from your code.

    But if you want to go programatically for some reason (I myself had a good reason in one case) you can access the Handlers like this too:

    Logger rootLogger = LogManager.getLogManager().getLogger("");
    rootLogger.setLevel(Level.INFO);
    for (Handler h : rootLogger.getHandlers()) {
        h.setLevel(Level.INFO);
    }
    

    EDIT I added the setLevel to the root logger as searchengine27 pointed out in in his answer.

    The Handlers are File or Console Handlers that you setup via the properties or programatically too.

    Or change filters like this:

    Logger rootLogger = LogManager.getLogManager().getLogger("");
    rootLogger.setFilter(new Filter() {
        @Override
        public boolean isLoggable(LogRecord record) {
                return "something".equals(record.getLoggerName());
        }
    });
    
    0 讨论(0)
  • 2020-11-30 02:28

    One-liner Java 8 approach to morja's answer:

    Arrays.stream(LogManager.getLogManager().getLogger("").getHandlers()).forEach(h -> h.setLevel(Level.INFO));
    
    0 讨论(0)
提交回复
热议问题