简体   繁体   English

使用 jdk logging/slf4j 更改日志级别本地化名称

[英]Changing logging levels localized name with jdk logging/slf4j

I see that logging levels using jdk logging are localized, running this example:我看到使用 jdk 日志记录的日志记录级别已本地化,运行此示例:

package com.stackoverflow.tests.logging;

import java.util.Locale;
import java.util.logging.Logger;

public class TestLogging
{

    public static void doLog(Locale l)
    {
        Locale.setDefault(l);

        Logger logger = Logger.getLogger(TestLogging.class.getName());

        final String msg = "Hello logging world";
        logger.severe(msg);
        logger.info(msg);
        logger.config(msg);
        logger.fine(msg);
        logger.finer(msg);
        logger.finest(msg);

    }

    public static void main(String args[])
    {

        doLog(Locale.ITALY);

    //  doLog(Locale.UK);

    //  doLog(Locale.FRANCE);

    }
}

Ouput for italian (using default logger configuration hence only severe and info levels are logged)意大利语的输出(使用默认记录器配置,因此只记录严重和信息级别)

dic 15, 2014 10:48:43 AM com.stackoverflow.tests.logging.TestLogging doLog
Grave: Hello logging world
dic 15, 2014 10:48:43 AM com.stackoverflow.tests.logging.TestLogging doLog
Informazioni: Hello logging world

I would like to set up custom localized message for logging levels instead of the one provided by default.我想为日志级别设置自定义本地化消息,而不是默认提供的消息。

How can I do that我怎样才能做到这一点

  1. Using JDK logging directly (I see Logger.getLogger can take a ResourceBundle but I did not manage to make it work, and also I dont know what is expected to be in this file)直接使用 JDK 日志记录(我看到Logger.getLogger可以使用 ResourceBundle 但我没有设法使其工作,而且我不知道该文件中的预期内容)
  2. Using SLF4 facade (I guess that would imply tweaking LoggerFactory.getLogger function of SLF4J which is the one I'm using to obtain the loggers)使用 SLF4 外观(我想这意味着调整 SLF4J 的LoggerFactory.getLogger函数,这是我用来获取记录器的函数)

Based on some testing, it doesn't seem possible to do this with JDK logging.根据一些测试,JDK 日志记录似乎无法做到这一点。

The resource bundle name passed to Logger doesn't influence the Level object that creates the localized name.传递给Logger的资源包名称不会影响创建本地化名称的Level对象。 Instead, it uses a default resource bundle ( sun.util.logging.resources.logging ) to obtain a text version of the level.相反,它使用默认资源包 ( sun.util.logging.resources.logging ) 来获取关卡的文本版本。

My test comprised of a file named logmessages.properties containing:我的测试包含一个名为logmessages.properties的文件,其中包含:

INFO="NEWINFO"
testmessage="fooballs"

and a simple class:和一个简单的类:

import java.util.logging.Logger;

public class LocaleLoggingTest {

  public static void main(String[] args) throws Exception {
    Logger logger = Logger.getLogger("name", "logmessages");
    logger.info("testmessage");
  }
}

Output:输出:

Dec 15, 2014 10:23:39 AM LocaleLoggingTest main
INFO: "fooballs"

If you debug, by the time you get to java.util.logging.SimpleFormatter.format(LogRecord) , the log record has a Level object with a default resource bundle.如果您调试,当您到达java.util.logging.SimpleFormatter.format(LogRecord)时,日志记录有一个带有默认资源包的Level对象。 Frustrating, eh?令人沮丧,嗯?

In java.util.logging , you can define your own levels using a different bundle name or none at all.java.util.logging ,您可以使用不同的包名称或根本不定义自己的级别。 The way to do that is subclassing java.util.logging.Level and adding your own constants.这样做的方法是继承java.util.logging.Level并添加您自己的常量。 For example, if you want non-localized names, you can create your levels as follows:例如,如果您想要非本地化名称,您可以按如下方式创建关卡:

public class Level extends java.util.logging.Level {
    private static final long serialVersionUID = -1283674772992561191L;

    public static final Level OFF = new Level("OFF", Integer.MAX_VALUE);
    public static final Level SEVERE = new Level("SEVERE", 1000);
    public static final Level WARNING = new Level("WARNING", 900);
    public static final Level INFO = new Level("INFO", 800);
    public static final Level CONFIG = new Level("CONFIG", 700);
    public static final Level FINE = new Level("FINE", 500);
    public static final Level FINER = new Level("FINER", 400);
    public static final Level FINEST = new Level("FINEST", 300);
    public static final Level ALL = new Level("ALL", Integer.MIN_VALUE);

    protected Level(String name, int value) {
        super(name, value);
    }
}

If you want to use another bundle name, do the following:如果要使用其他捆绑包名称,请执行以下操作:

public class Level extends java.util.logging.Level {
    private static final long serialVersionUID = -1283674772992561191L;

    static final String my_bundle_name = "my.bundle.name";

    public static final Level OFF = new Level("OFF", Integer.MAX_VALUE, my_bundle_name);
    public static final Level SEVERE = new Level("SEVERE", 1000, my_bundle_name);
    public static final Level WARNING = new Level("WARNING", 900, my_bundle_name);
    public static final Level INFO = new Level("INFO", 800, my_bundle_name);
    public static final Level CONFIG = new Level("CONFIG", 700, my_bundle_name);
    public static final Level FINE = new Level("FINE", 500, my_bundle_name);
    public static final Level FINER = new Level("FINER", 400, my_bundle_name);
    public static final Level FINEST = new Level("FINEST", 300, my_bundle_name);
    public static final Level ALL = new Level("ALL", Integer.MIN_VALUE, my_bundle_name);

    protected Level(String name, int value, String resourceBundleName) {
        super(name, value, resourceBundleName);
    }
}

Of course, you must use your custom levels instead of the default ones, so you must use calls like Logger.log(Level level, String msg) , where you specify the level explicitly, instead of Logger.info(String msg) , that always uses the default level.当然,您必须使用自定义级别而不是默认级别,因此您必须使用像Logger.log(Level level, String msg)这样的调用,在其中明确指定级别,而不是Logger.info(String msg) ,即始终使用默认级别。

EDIT: I got the idea from https://docs.oracle.com/javase/8/docs/api/java/util/logging/Level.html#Level-java.lang.String-int-编辑:我从https://docs.oracle.com/javase/8/docs/api/java/util/logging/Level.html#Level-java.lang.String-int-得到这个想法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM