I see that logging levels using jdk logging are localized, running this example:
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
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)LoggerFactory.getLogger
function of SLF4J which is the one I'm using to obtain the loggers)Based on some testing, it doesn't seem possible to do this with JDK logging.
The resource bundle name passed to Logger
doesn't influence the Level
object that creates the localized name. Instead, it uses a default resource bundle ( sun.util.logging.resources.logging
) to obtain a text version of the level.
My test comprised of a file named logmessages.properties
containing:
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. Frustrating, eh?
In java.util.logging
, you can define your own levels using a different bundle name or none at all. The way to do that is subclassing java.util.logging.Level
and adding your own constants. 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.
EDIT: I got the idea from https://docs.oracle.com/javase/8/docs/api/java/util/logging/Level.html#Level-java.lang.String-int-
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.