JUL日志
如果使用System.out.println
来打印信息,项目中存在大量的控制台输出语句,会显得很凌乱,而且日志的粒度是不够细的,假如我们现在希望,项目只在debug的情况下打印某些日志,而在实际运行时不打印日志,采用直接输出的方式就很难实现了,因此我们需要使用日志框架来规范化日志输出。
而JDK为我们提供了一个自带的日志框架,位于java.util.logging
包下,我们可以使用此框架来实现日志的规范化打印,使用起来非常简单:
// 首先获取日志打印器 Logger logger = Logger.getLogger(Main.class.getName()); // 调用info来输出一个普通的信息,直接填写字符串即可 logger.info("我是普通的日志");
JUL日志讲解
日志分为7个级别,详细信息我们可以在Level类中查看:
- SEVERE(最高值)- 一般用于代表严重错误
- WARNING - 一般用于表示某些警告,但是不足以判断为错误
- INFO (默认级别) - 常规消息
- CONFIG
- FINE
- FINER
- FINEST(最低值)
通过info
方法直接输出的结果就是使用的默认级别的日志
打印时输出日志级别:
logger.log(Level.SEVERE, "严重的错误", new IOException("我就是错误")); logger.log(Level.WARNING, "警告的内容"); logger.log(Level.INFO, "普通的信息"); logger.log(Level.CONFIG, "级别低于普通信息");
设置配置修改日志的打印级别:
public static void main(String[] args) { Logger logger = Logger.getLogger(Main.class.getName()); //修改日志级别 logger.setLevel(Level.CONFIG); //不使用父日志处理器 logger.setUseParentHandlers(false); //使用自定义日志处理器 //默认为console处理 ConsoleHandler handler = new ConsoleHandler(); handler.setLevel(Level.CONFIG); logger.addHandler(handler); logger.log(Level.SEVERE, "严重的错误", new IOException("我就是错误")); logger.log(Level.WARNING, "警告的内容"); logger.log(Level.INFO, "普通的信息"); logger.log(Level.CONFIG, "级别低于普通信息"); }
日志处理器不仅仅只有控制台打印,也可以使用文件处理器来处理日志信息:
//添加输出到本地文件 FileHandler fileHandler = new FileHandler("test.log"); fileHandler.setLevel(Level.WARNING); logger.addHandler(fileHandler);
控制台处理器就默认使用的是SimpleFormatter
,而文件处理器则是使用的XMLFormatter
,可以自定义:
//使用自定义日志处理器(控制台) ConsoleHandler handler = new ConsoleHandler(); handler.setLevel(Level.CONFIG); handler.setFormatter(new XMLFormatter()); logger.addHandler(handler);
直接配置为想要的打印格式:
public class TestFormatter extends Formatter { @Override public String format(LogRecord record) { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); String time = format.format(new Date(record.getMillis())); //格式化日志时间 return time + " : " + record.getMessage() + "\n"; } }
public static void main(String[] args) throws IOException { Logger logger = Logger.getLogger(Main.class.getName()); logger.setUseParentHandlers(false); //为了让颜色变回普通的颜色,通过代码块在初始化时将输出流设定为System.out ConsoleHandler handler = new ConsoleHandler(){{ setOutputStream(System.out); }}; //创建匿名内部类实现自定义的格式 handler.setFormatter(new Formatter() { @Override public String format(LogRecord record) { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); String time = format.format(new Date(record.getMillis())); //格式化日志时间 String level = record.getLevel().getName(); // 获取日志级别名称 // String level = record.getLevel().getLocalizedName(); // 获取本地化名称(语言跟随系统) String thread = String.format("%10s", Thread.currentThread().getName()); //线程名称(做了格式化处理,留出10格空间) long threadID = record.getThreadID(); //线程ID String className = String.format("%-20s", record.getSourceClassName()); //发送日志的类名 String msg = record.getMessage(); //日志消息 //\033[33m作为颜色代码,30~37都有对应的颜色,38是没有颜色,IDEA能显示,但是某些地方可能不支持 return "\033[38m" + time + " \033[33m" + level + " \033[35m" + threadID + "\033[38m --- [" + thread + "] \033[36m" + className + "\033[38m : " + msg + "\n"; } }); logger.addHandler(handler); logger.info("我是测试消息1..."); logger.log(Level.INFO, "我是测试消息2..."); logger.log(Level.WARNING, "我是测试消息3..."); }
不希望某些日志信息被输出,配置过滤规则:
public static void main(String[] args) throws IOException { Logger logger = Logger.getLogger(Main.class.getName()); //自定义过滤规则 logger.setFilter(record -> !record.getMessage().contains("普通"));//为ture才输出 logger.log(Level.SEVERE, "严重的错误", new IOException("我就是错误")); logger.log(Level.WARNING, "警告的内容"); logger.log(Level.INFO, "普通的信息"); }
Properties配置文件
Properties文件是Java的一种配置文件:
name=Test desc=Description
加载Properties配置文件:
public static void main(String[] args) throws IOException { Properties properties = new Properties(); properties.load(new FileInputStream("test.properties")); System.out.println(properties); }
Properties
本质上就是一个Map一样的结构,它会把所有的配置项映射为一个Map,这样我们就可以快速地读取对应配置的值了。
将已经存在的Properties对象放入输出流进行保存:
public static void main(String[] args) throws IOException { Properties properties = new Properties(); // properties.setProperty("test", "lbwnb"); //和put效果一样 properties.put("test", "lbwnb"); properties.store(System.out, "????");//第二个参数设置评论注释 //properties.storeToXML(System.out, "????"); 保存为XML格式 }
通过System.getProperties()
获取系统的参数
编写日志配置文件
配置文件来规定日志打印器的一些默认值:
# RootLogger 的默认处理器为 handlers= java.util.logging.ConsoleHandler # RootLogger 的默认的日志级别 .level= CONFIG # 修改ConsoleHandler的默认配置 # 指定默认日志级别 java.util.logging.ConsoleHandler.level = ALL # 指定默认日志消息格式 java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter # 指定默认的字符集 java.util.logging.ConsoleHandler.encoding = UTF-8
使用配置文件来进行配置:
public static void main(String[] args) throws IOException { //获取日志管理器 LogManager manager = LogManager.getLogManager(); //读取我们自己的配置文件 manager.readConfiguration(new FileInputStream("logging.properties")); //再获取日志打印器 Logger logger = Logger.getLogger(Main.class.getName()); logger.log(Level.CONFIG, "我是一条日志信息"); //通过自定义配置文件,我们发现默认级别不再是INFO了 }
Lombok快速开启日志
添加一个@Log
注解,可以直接使用一个静态变量log,而它就是自动生成的Logger
@Log(topic = "name") //手动指定名称 public class Main { public static void main(String[] args) { System.out.println("自动生成的Logger名称:"+log.getName()); log.info("我是日志信息"); } }
Mybatis日志系统
开启Mybatis的日志系统,来监控所有的数据库操作
配置开启日志系统:
<setting name="logImpl" value="STDOUT_LOGGING" />
logImpl
包括很多种配置项,包括 SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING,而默认情况下是未配置,也就是说不打印。
设定为STDOUT_LOGGING表示直接使用标准输出将日志信息打印到控制台;JDK_LOGGING表示使用JUL进行日志打印
Mybatis的日志级别都比较低,需要设置一下logging.properties
默认的日志级别
handlers= java.util.logging.ConsoleHandler .level= ALL java.util.logging.ConsoleHandler.level = ALL