欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java日志(二)--java官方日志jul的使用

程序员文章站 2022-05-24 15:29:55
...

java日志(二)–java官方日志jul的使用

一、简介

java官方日志jul,位于java.util.logging包下。

二、jul模块

jul模块主要包含三个:Level、Formatter和Handler。

2.1 Level

日志级别,由高到低有:OFF/SEVERE/WARNIN/INFO/CONFIG/FINE/FINERG/FINEST/ALL,
每个级别有自己的数值,在java.util.logging.Level类中源码如下:

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1PF9zh3R-1583640384948)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]

可自定义日志级别,继承java.util.logging.Level类即可。

2.2 Formatter

定义日志输出的格式,目前有SimpleFormatter和XMLFormatter两种格式,分别对应简单格式和xml格式。
可自定输出格式,继承抽象类java.util.logging.Formatter即可。

2.3 Handler

日志输出的目的,目前有
FileHandler:输出到文件,默认Level为INFO,Formatter为XMLFormatter;;
ConsoleHandler:输出到控制台,默认Level为INFO,流为System.err,Formatter为SimpleFormatter;
SocketHandler:输出到socket;
MemoryHandler:输出到内存;
可自定义日志级别,继承java.util.logging.Formatter类即可。

三、使用

jul关键类是java.util.logging.Logger,通过此类定义logger,相同logger名称只有一个实例。
如:Logger logger = Logger.getLogger(“javaLog”);
java.util.logging包下的类图如下:
java日志(二)--java官方日志jul的使用[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0H5l1XwZ-1583640384951)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]​

四、简单示例

这里直接通过代码,介绍Logger的使用,详情请查看注释。

import java.util.logging.*;

public class JavaLogStudyMain {
    public static void main(String[] args) throws Exception {
        //简单格式的Formatter
        SimpleFormatter sf = new SimpleFormatter();
        //xml格式的formatter
        XMLFormatter xf = new XMLFormatter();

        //输出到文件的hander,指定日志输出级别为ALL
        FileHandler fh = new FileHandler("jul_study.log");
        fh.setLevel(Level.ALL);
        fh.setFormatter(sf);
//        fh.setFormatter(xf);

        //输出到控制台的handler,指定日志输出级别为INFO
        ConsoleHandler ch = new ConsoleHandler();
        ch.setLevel(Level.INFO);

        //获取logger实例,相同名的只能生成一个实例
        Logger logger = Logger.getLogger("javaLog");
        logger.addHandler(fh);   //添加输出handler
        logger.addHandler(ch);   //添加输出handler
        logger.setLevel(Level.ALL);  //指定logger日志级别

        //日志输出简写形式,有不同的级别,可带参数,其它类似
        logger.log(Level.INFO, "this is a info, {0}", "p1");
        logger.log(Level.WARNING, "this is a warn, {0} {1}", new Object[]{"p1", "p2"});
        logger.log(Level.SEVERE, "this is a severe");
        logger.log(Level.FINE, "this is a fine");
        logger.log(Level.FINEST, "this is a finest");
        logger.log(Level.CONFIG, "this is a config");
        logger.log(Level.INFO, "this is a info", new Exception("my excep")); //带异常输出

        //日志输出简写形式,有不同的级别
        logger.severe("severe log");
        logger.warning("warning log");
        logger.info("info log");
        logger.config("config log");
        logger.fine("fine log");
        logger.finer("finer log");
        logger.finest("finest log");
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qRF2EHTZ-1583640384952)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]

四、自定义logger
这里通过继承Level、Handler、Formatter自定义Logger,日志存在文件中,且每个不同的loggerName存不同日志文件中。
示例如下,解释请查看注释:

import org.apache.commons.lang.time.DateFormatUtils;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.logging.*;

public class SelfJavaLogMain {
    //生成单例日志输出handler实例
    private static SelfHandle sf = new SelfHandle();

    /**
     * 根据class获取logger
     * @param clazz
     * @return
     */
    public static Logger getLogger(Class clazz){
        return getLogger(clazz.getSimpleName());
    }

    /**
     * 根据loggerName获取logger
     * @param loggerName
     * @return
     */
    public static Logger getLogger(String loggerName){
        Logger logger = Logger.getLogger(loggerName);
        logger.addHandler(sf);
        return logger;
    }

    /**
     * 自定义日志格式formatter
     */
    public static class SelfFormater extends Formatter {

        public static SelfFormater selfFormater = new SelfFormater();

        @Override
        public String format(LogRecord record) {
            return String.format("[%s] %s %s.%s: %s\r\n", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"),
                    record.getLevel().getName(), record.getSourceClassName(), record.getSourceMethodName(), record.getMessage());
        }

        public static SelfFormater getInstance() {
            return selfFormater;
        }
    }

    /**
     * 自定义日志level
     */
    public static class SelfLevel extends Level {

        public static SelfLevel ERROR = new SelfLevel("ERROR", 910);

        /**
         * @param name  自定义级别名称
         * @param value 自定义级别的权重值
         */
        protected SelfLevel(String name, int value) {
            super(name, value);
        }
    }

    /**
     * 自定义日志输出handler
     */
    public static class SelfHandle extends Handler {

        /**
         * 日志写入的位置
         *
         * @param record
         */
        @Override
        public void publish(LogRecord record) {
            try {
                //每一个不同的loggerName分别记在不同的日志文件中
                File file = new File(String.format("%s_%s.log",record.getLoggerName(), DateFormatUtils.format(new Date(),"yyyy-MM-dd")));
                if(!file.exists()){
                    file.createNewFile();
                }
                FileWriter fw = new FileWriter(file,true);
                PrintWriter pw = new PrintWriter(fw);
                String log = String.format("[%s] %s %s.%s: %s\r\n", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"),
                        record.getLevel().getName(), record.getSourceClassName(), record.getSourceMethodName(), record.getMessage());
                pw.write(log);
                pw.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        /**
         * 刷新缓存区,保存数据
         */
        @Override
        public void flush() {
        }

        /**
         * 关闭
         *
         * @throws SecurityException
         */
        @Override
        public void close() throws SecurityException {
        }
    }

    public static void main(String[] args) throws Exception {
        //获取自定义的logger
        Logger logger = getLogger(SelfJavaLogMain.class);
        logger.info("info log");
        logger.severe("severe log");
        //使用自定义的logger level
        logger.log(SelfLevel.ERROR, "error log");
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JnEhXWZ7-1583640384952)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]

五、jre日志默认配置

jre(java runtime environment, 即java运行环境)的默认日志配置为jre/lib/logging.properties,
其配置如下:

\############################################################
\#    Default Logging Configuration File
\#
\# You can use a different file by specifying a filename
\# with the java.util.logging.config.file system property.  
\# For example java -Djava.util.logging.config.file=myfile
\############################################################

\############################################################
\#    Global properties
\############################################################

\# "handlers" specifies a comma separated list of log Handler 
\# classes.  These handlers will be installed during VM startup.
\# Note that these classes must be on the system classpath.
\# By default we only configure a ConsoleHandler, which will only
\# show messages at the INFO and above levels.
handlers= java.util.logging.ConsoleHandler

\# To also add the FileHandler, use the following line instead.
\#handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler

\# Default global logging level.
\# This specifies which kinds of events are logged across
\# all loggers.  For any given facility this global level
\# can be overriden by a facility specific level
\# Note that the ConsoleHandler also has a separate level
\# setting to limit messages printed to the console.
.level= INFO

\############################################################
\# Handler specific properties.
\# Describes specific configuration info for Handlers.
\############################################################

\# 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
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

\# Example to customize the SimpleFormatter output format 
\# to print one-line log message like this:
\#   <level>: <log message> [<date/time>]
\#
\# java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n

\############################################################
\# Facility specific properties.
\# Provides extra control for each logger.
\############################################################

\# For example, set the com.xyz.foo logger to only log SEVERE
\# messages:
com.xyz.foo.level = SEVERE
相关标签: java日志