JUL默认的配置文件 在我们没有手动配置的情况下读取的都是JDK的配置文件
我们目前有两种方式给logger进行相应的配置:
1.通过代码进行配置
2.读取配置文件:
a. 如果没有指明配置文件 则默认按jdk的配置文件去配置
b. 手动添加logging.properties配置文件
怎么样让logger去读指明的配置文件呢?
首先先把jdk的logging.properties配置文件复制一份到我们的项目里
放在resources中
public void testProperties() throws Exception {
// 读取自定义配置文件
InputStream in =
JULTest.class.getClassLoader().getResourceAsStream("logging.properties");
// 获取日志管理器对象
LogManager logManager = LogManager.getLogManager();
// 通过日志管理器加载配置文件
logManager.readConfiguration(in);
Logger logger = Logger.getLogger("com.ydlclass.log.JULTest");
logger.severe("severe");
logger.warning("warning");
logger.info("info");
logger.config("config");
logger.fine("fine");
logger.finer("finer");
logger.finest("finest");
}
// 读取自定义配置文件 读取properties文件的留
InputStream in =
JULTest.class.getClassLoader().getResourceAsStream("logging.properties");
// 获取日志管理器对象
LogManager logManager = LogManager.getLogManager();
// 通过日志管理器加载配置文件 将流文件传进去
logManager.readConfiguration(in);
从这行下面的代码 只要获取logger的代码都会默认从我们的配置文件去读取配置
记得更改输出方式ConsoleHandler和FileHandler
然后还要进一步配置流, 文件存储位置
//查看FileHandler发现是已占位符的形式存储
//进一步可以设置 输出文件 和 输出的格式
———————————————————————————————————————
我们不妨看看一个文件处理器的源码是怎么读配置项的:
private void configure() {
LogManager manager = LogManager.getLogManager();
String cname = getClass().getName();
pattern = manager.getStringProperty(cname + ".pattern", "%h/java%u.log");
limit = manager.getLongProperty(cname + ".limit", 0);
if (limit < 0) {
limit = 0;
}
count = manager.getIntProperty(cname + ".count", 1);
if (count <= 0) {
count = 1;
}
append = manager.getBooleanProperty(cname + ".append", false);
setLevel(manager.getLevelProperty(cname + ".level", Level.ALL));
setFilter(manager.getFilterProperty(cname + ".filter", null));
setFormatter(manager.getFormatterProperty(cname + ".formatter", new XMLFormatter()));
// Initialize maxLocks from the logging.properties file.
// If invalid/no property is provided 100 will be used as a default value.
maxLocks = manager.getIntProperty(cname + ".maxLocks", MAX_LOCKS);
if(maxLocks <= 0) {
maxLocks = MAX_LOCKS;
}
try {
setEncoding(manager.getStringProperty(cname +".encoding", null));
} catch (Exception ex) {
try {
setEncoding(null);
} catch (Exception ex2) {
// doing a setEncoding with null should always work.
// assert false;
}
}
}
可以从以下源码中看到配置项:
public class FileHandler extends StreamHandler {
private MeteredStream meter;
private boolean append;
// 限制文件大小
private long limit; // zero => no limit.
// 控制日志文件的数量
private int count;
// 日志文件的格式化方式
private String pattern;
private String lockFileName;
private FileChannel lockFileChannel;
private File files[];
private static final int MAX_LOCKS = 100;
// 可以理解为同时可以有多少个线程打开文件,源码中有介绍
private int maxLocks = MAX_LOCKS;
private static final Set<String> locks = new HashSet<>();
}
我们已经知道系统默认的配置文件的位置,那我们能不能自定义呢?当然可以了,我们从jdk中赋值一个配置文件过来:
.level= INFO
# default file output is in user's home directory.
java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
# Default number of locks FileHandler can obtain synchronously.
# This specifies maximum number of attempts to obtain lock file by FileHandler
# implemented by incrementing the unique field %u as per FileHandler API documentation.
java.util.logging.FileHandler.maxLocks = 100
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
# Limit the message that are printed on the console to INFO and above.
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
# java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n
pattern = manager.getStringProperty(cname + ".pattern", "%h/java%u.log");
static File generate(String pat, int count, int generation, int unique)
throws IOException
{
Path path = Paths.get(pat);
Path result = null;
boolean sawg = false;
boolean sawu = false;
StringBuilder word = new StringBuilder();
Path prev = null;
for (Path elem : path) {
if (prev != null) {
prev = prev.resolveSibling(word.toString());
result = result == null ? prev : result.resolve(prev);
}
String pattern = elem.toString();
int ix = 0;
word.setLength(0);
while (ix < pattern.length()) {
char ch = pattern.charAt(ix);
ix++;
char ch2 = 0;
if (ix < pattern.length()) {
ch2 = Character.toLowerCase(pattern.charAt(ix));
}
if (ch == '%') {
if (ch2 == 't') {
String tmpDir = System.getProperty("java.io.tmpdir");
if (tmpDir == null) {
tmpDir = System.getProperty("user.home");
}
result = Paths.get(tmpDir);
ix++;
word.setLength(0);
continue;
} else if (ch2 == 'h') {
result = Paths.get(System.getProperty("user.home"));
if (jdk.internal.misc.VM.isSetUID()) {
// Ok, we are in a set UID program. For safety's sake
// we disallow attempts to open files relative to %h.
throw new IOException("can't use %h in set UID program");
}
ix++;
word.setLength(0);
continue;
} else if (ch2 == 'g') {
word = word.append(generation);
sawg = true;
ix++;
continue;
} else if (ch2 == 'u') {
word = word.append(unique);
sawu = true;
ix++;
continue;
} else if (ch2 == '%') {
word = word.append('%');
ix++;
continue;
}
}
word = word.append(ch);
}
prev = elem;
}
if (count > 1 && !sawg) {
word = word.append('.').append(generation);
}
if (unique > 0 && !sawu) {
word = word.append('.').append(unique);
}
if (word.length() > 0) {
String n = word.toString();
Path p = prev == null ? Paths.get(n) : prev.resolveSibling(n);
result = result == null ? p : result.resolve(p);
} else if (result == null) {
result = Paths.get("");
}
if (path.getRoot() == null) {
return result.toFile();
} else {
return path.getRoot().resolve(result).toFile();
}
}
System.out.println(System.getProperty(“user.home”) );
输出内容:C:\Users\zn\java0.log
我们将拷贝的文件稍作修改:
.level= INFO
# default file output is in user's home directory.
java.util.logging.FileHandler.pattern = D:/log/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.maxLocks = 100
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
# Limit the message that are printed on the console to INFO and above.
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
# java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n
public void testProperties() throws Exception {
// 读取自定义配置文件
InputStream in =
JULTest.class.getClassLoader().getResourceAsStream("logging.properties");
// 获取日志管理器对象
LogManager logManager = LogManager.getLogManager();
// 通过日志管理器加载配置文件
logManager.readConfiguration(in);
Logger logger = Logger.getLogger("com.ydlclass.log.JULTest");
logger.severe("severe");
logger.warning("warning");
logger.info("info");
logger.config("config");
logger.fine("fine");
logger.finer("finer");
logger.finest("finest");
文件中也出现了:
打开日志发现是xml,因为这里用的就是XMLFormatter:
上边我们配置了两个handler给根Logger,我们还可以给其他的Logger做独立的配置:
handlers = java.util.logging.ConsoleHandler
.level = INFO
# 对这个logger独立配置
com.ydlclass.handlers = java.util.logging.FileHandler
com.ydlclass.level = ALL
com.ydlclass.useParentHandlers = false
# 修改了名字
java.util.logging.FileHandler.pattern = D:/logs/ydl-java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.maxLocks = 100
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
# 文件使用追加方式
java.util.logging.FileHandler.append = true
# Limit the message that are printed on the console to INFO and above.
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
# 修改日志格式
java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n
执行发现控制台没有内容,文件中有了,说明没有问题OK了: