zoukankan      html  css  js  c++  java
  • 003-log-jul,jdk自带日志服务

    一、简介

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

    1.1、POM依赖

      无依赖

    1.2、配置

      JUL的默认配置文件是logging.properties ,在 $JAVA_HOME/jre/lib下 (Mac 在 $JAVA_HOME/lib). 当然自己也可以修改文件位置,如:-Djava.util.logging.config.file=xxxpath/logging.properties

      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
    View Code

      在tomcat的conf下就有个logging.properties,同时注意catalina.sh 里就有这样代码

    # Set juli LogManager if it is present
    if [ -r "$CATALINA_BASE"/conf/logging.properties ]; then
      JAVA_OPTS="$JAVA_OPTS -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"
      LOGGING_CONFIG="-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties"
    fi

    1.3、使用

    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    public class ApplicationMain {
        private static Logger logger = Logger.getLogger(ApplicationMain.class.getName());
    
        public static void main(String[] args) {
            // 记录debug级别的信息
            logger.log(Level.INFO,"This is debug message.");
            // 记录info级别的信息
            logger.info("This is info message.");
            // 记录error级别的信息
            logger.warning("This is warning message.");
        }
    }

    二、详细说明

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

    1.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);

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

    1.2、Formatter

      定义日志输出的格式,目前有SimpleFormatter和XMLFormatter两种格式,分别对应简单格式和xml格式。

      可自定输出格式,继承抽象类java.util.logging.Formatter即可。

    1.3、Handler

    日志输出的目的,目前有

    FileHandler:输出到文件,默认Level为INFO,Formatter为XMLFormatter;;
    ConsoleHandler:输出到控制台,默认Level为INFO,流为System.err,Formatter为SimpleFormatter;
    SocketHandler:输出到socket;
    MemoryHandler:输出到内存;

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

    1.4、简单示例

    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");
        }
    }

    1.5、自定义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
    ", 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
    ", 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");
        }
    }

    水电费

  • 相关阅读:
    如何使用GOOGLE高级搜索技巧
    你所认为的极限,可能只是别人眼中的起点
    飞机选座——附:东航320选坐攻略
    古诗词里,从初识到相爱到分离到重逢的漫长过程
    从零开始学摄影
    Python之运维
    Linux用户和组密令大全
    centos7 下安装生物信息软件的问题小总结
    VMware锁定文件失败开启模块diskearly的操作失败未能启动虚拟机
    linux 基本命令整理--转
  • 原文地址:https://www.cnblogs.com/bjlhx/p/11064007.html
Copyright © 2011-2022 走看看