JUL默认的配置文件 在我们没有手动配置的情况下读取的都是JDK的配置文件image.png
我们目前有两种方式给logger进行相应的配置:
1.通过代码进行配置
2.读取配置文件:
a. 如果没有指明配置文件 则默认按jdk的配置文件去配置
b. 手动添加logging.properties配置文件

怎么样让logger去读指明的配置文件呢?

首先先把jdk的logging.properties配置文件复制一份到我们的项目里
放在resources中 image.png

  1. public void testProperties() throws Exception {
  2. // 读取自定义配置文件
  3. InputStream in =
  4. JULTest.class.getClassLoader().getResourceAsStream("logging.properties");
  5. // 获取日志管理器对象
  6. LogManager logManager = LogManager.getLogManager();
  7. // 通过日志管理器加载配置文件
  8. logManager.readConfiguration(in);
  9. Logger logger = Logger.getLogger("com.ydlclass.log.JULTest");
  10. logger.severe("severe");
  11. logger.warning("warning");
  12. logger.info("info");
  13. logger.config("config");
  14. logger.fine("fine");
  15. logger.finer("finer");
  16. logger.finest("finest");
  17. }
  1. // 读取自定义配置文件 读取properties文件的留
  2. InputStream in =
  3. JULTest.class.getClassLoader().getResourceAsStream("logging.properties");
  4. // 获取日志管理器对象
  5. LogManager logManager = LogManager.getLogManager();
  6. // 通过日志管理器加载配置文件 将流文件传进去
  7. logManager.readConfiguration(in);

从这行下面的代码 只要获取logger的代码都会默认从我们的配置文件去读取配置
记得更改输出方式ConsoleHandler和FileHandlerimage.png
然后还要进一步配置流, 文件存储位置
//查看FileHandler发现是已占位符的形式存储
image.png
//进一步可以设置 输出文件 和 输出的格式image.png

———————————————————————————————————————
我们不妨看看一个文件处理器的源码是怎么读配置项的:

  1. private void configure() {
  2. LogManager manager = LogManager.getLogManager();
  3. String cname = getClass().getName();
  4. pattern = manager.getStringProperty(cname + ".pattern", "%h/java%u.log");
  5. limit = manager.getLongProperty(cname + ".limit", 0);
  6. if (limit < 0) {
  7. limit = 0;
  8. }
  9. count = manager.getIntProperty(cname + ".count", 1);
  10. if (count <= 0) {
  11. count = 1;
  12. }
  13. append = manager.getBooleanProperty(cname + ".append", false);
  14. setLevel(manager.getLevelProperty(cname + ".level", Level.ALL));
  15. setFilter(manager.getFilterProperty(cname + ".filter", null));
  16. setFormatter(manager.getFormatterProperty(cname + ".formatter", new XMLFormatter()));
  17. // Initialize maxLocks from the logging.properties file.
  18. // If invalid/no property is provided 100 will be used as a default value.
  19. maxLocks = manager.getIntProperty(cname + ".maxLocks", MAX_LOCKS);
  20. if(maxLocks <= 0) {
  21. maxLocks = MAX_LOCKS;
  22. }
  23. try {
  24. setEncoding(manager.getStringProperty(cname +".encoding", null));
  25. } catch (Exception ex) {
  26. try {
  27. setEncoding(null);
  28. } catch (Exception ex2) {
  29. // doing a setEncoding with null should always work.
  30. // assert false;
  31. }
  32. }
  33. }

可以从以下源码中看到配置项:

  1. public class FileHandler extends StreamHandler {
  2. private MeteredStream meter;
  3. private boolean append;
  4. // 限制文件大小
  5. private long limit; // zero => no limit.
  6. // 控制日志文件的数量
  7. private int count;
  8. // 日志文件的格式化方式
  9. private String pattern;
  10. private String lockFileName;
  11. private FileChannel lockFileChannel;
  12. private File files[];
  13. private static final int MAX_LOCKS = 100;
  14. // 可以理解为同时可以有多少个线程打开文件,源码中有介绍
  15. private int maxLocks = MAX_LOCKS;
  16. private static final Set<String> locks = new HashSet<>();
  17. }

我们已经知道系统默认的配置文件的位置,那我们能不能自定义呢?当然可以了,我们从jdk中赋值一个配置文件过来:

  1. .level= INFO
  2. # default file output is in user's home directory.
  3. java.util.logging.FileHandler.pattern = %h/java%u.log
  4. java.util.logging.FileHandler.limit = 50000
  5. java.util.logging.FileHandler.count = 1
  6. # Default number of locks FileHandler can obtain synchronously.
  7. # This specifies maximum number of attempts to obtain lock file by FileHandler
  8. # implemented by incrementing the unique field %u as per FileHandler API documentation.
  9. java.util.logging.FileHandler.maxLocks = 100
  10. java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
  11. # Limit the message that are printed on the console to INFO and above.
  12. java.util.logging.ConsoleHandler.level = INFO
  13. java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
  14. # java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n
  1. pattern = manager.getStringProperty(cname + ".pattern", "%h/java%u.log");
  1. static File generate(String pat, int count, int generation, int unique)
  2. throws IOException
  3. {
  4. Path path = Paths.get(pat);
  5. Path result = null;
  6. boolean sawg = false;
  7. boolean sawu = false;
  8. StringBuilder word = new StringBuilder();
  9. Path prev = null;
  10. for (Path elem : path) {
  11. if (prev != null) {
  12. prev = prev.resolveSibling(word.toString());
  13. result = result == null ? prev : result.resolve(prev);
  14. }
  15. String pattern = elem.toString();
  16. int ix = 0;
  17. word.setLength(0);
  18. while (ix < pattern.length()) {
  19. char ch = pattern.charAt(ix);
  20. ix++;
  21. char ch2 = 0;
  22. if (ix < pattern.length()) {
  23. ch2 = Character.toLowerCase(pattern.charAt(ix));
  24. }
  25. if (ch == '%') {
  26. if (ch2 == 't') {
  27. String tmpDir = System.getProperty("java.io.tmpdir");
  28. if (tmpDir == null) {
  29. tmpDir = System.getProperty("user.home");
  30. }
  31. result = Paths.get(tmpDir);
  32. ix++;
  33. word.setLength(0);
  34. continue;
  35. } else if (ch2 == 'h') {
  36. result = Paths.get(System.getProperty("user.home"));
  37. if (jdk.internal.misc.VM.isSetUID()) {
  38. // Ok, we are in a set UID program. For safety's sake
  39. // we disallow attempts to open files relative to %h.
  40. throw new IOException("can't use %h in set UID program");
  41. }
  42. ix++;
  43. word.setLength(0);
  44. continue;
  45. } else if (ch2 == 'g') {
  46. word = word.append(generation);
  47. sawg = true;
  48. ix++;
  49. continue;
  50. } else if (ch2 == 'u') {
  51. word = word.append(unique);
  52. sawu = true;
  53. ix++;
  54. continue;
  55. } else if (ch2 == '%') {
  56. word = word.append('%');
  57. ix++;
  58. continue;
  59. }
  60. }
  61. word = word.append(ch);
  62. }
  63. prev = elem;
  64. }
  65. if (count > 1 && !sawg) {
  66. word = word.append('.').append(generation);
  67. }
  68. if (unique > 0 && !sawu) {
  69. word = word.append('.').append(unique);
  70. }
  71. if (word.length() > 0) {
  72. String n = word.toString();
  73. Path p = prev == null ? Paths.get(n) : prev.resolveSibling(n);
  74. result = result == null ? p : result.resolve(p);
  75. } else if (result == null) {
  76. result = Paths.get("");
  77. }
  78. if (path.getRoot() == null) {
  79. return result.toFile();
  80. } else {
  81. return path.getRoot().resolve(result).toFile();
  82. }
  83. }

System.out.println(System.getProperty(“user.home”) );
输出内容:C:\Users\zn\java0.log
我们将拷贝的文件稍作修改:

  1. .level= INFO
  2. # default file output is in user's home directory.
  3. java.util.logging.FileHandler.pattern = D:/log/java%u.log
  4. java.util.logging.FileHandler.limit = 50000
  5. java.util.logging.FileHandler.count = 1
  6. java.util.logging.FileHandler.maxLocks = 100
  7. java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
  8. # Limit the message that are printed on the console to INFO and above.
  9. java.util.logging.ConsoleHandler.level = INFO
  10. java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
  11. # java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n
  1. public void testProperties() throws Exception {
  2. // 读取自定义配置文件
  3. InputStream in =
  4. JULTest.class.getClassLoader().getResourceAsStream("logging.properties");
  5. // 获取日志管理器对象
  6. LogManager logManager = LogManager.getLogManager();
  7. // 通过日志管理器加载配置文件
  8. logManager.readConfiguration(in);
  9. Logger logger = Logger.getLogger("com.ydlclass.log.JULTest");
  10. logger.severe("severe");
  11. logger.warning("warning");
  12. logger.info("info");
  13. logger.config("config");
  14. logger.fine("fine");
  15. logger.finer("finer");
  16. logger.finest("finest");

image.png
文件中也出现了:image.png
打开日志发现是xml,因为这里用的就是XMLFormatter:
image.png
上边我们配置了两个handler给根Logger,我们还可以给其他的Logger做独立的配置:

  1. handlers = java.util.logging.ConsoleHandler
  2. .level = INFO
  3. # 对这个logger独立配置
  4. com.ydlclass.handlers = java.util.logging.FileHandler
  5. com.ydlclass.level = ALL
  6. com.ydlclass.useParentHandlers = false
  7. # 修改了名字
  8. java.util.logging.FileHandler.pattern = D:/logs/ydl-java%u.log
  9. java.util.logging.FileHandler.limit = 50000
  10. java.util.logging.FileHandler.count = 1
  11. java.util.logging.FileHandler.maxLocks = 100
  12. java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
  13. # 文件使用追加方式
  14. java.util.logging.FileHandler.append = true
  15. # Limit the message that are printed on the console to INFO and above.
  16. java.util.logging.ConsoleHandler.level = INFO
  17. java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
  18. # 修改日志格式
  19. java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n

执行发现控制台没有内容,文件中有了,说明没有问题OK了:image.pngimage.png