美文网首页Java随笔
Java日志的使用

Java日志的使用

作者: rainbowtrash | 来源:发表于2018-11-25 16:37 被阅读0次

    开始

    介绍

    Java.util.logging是JDK 1.4 版本之后用于添加的日志记录的功能包。

    创建 logger 对象

    import java.util.logging.Logger;
    
    public class MyLogger(){
      // 当前类叫MyLogger
      private final static Logger LOGGER = Logger.getLogger(MyLogger.class.getName());
      //其他代码
    }
    

    其中创建的Logger是有层次结构的。使用.(点)来表示这种层次。比如,你获得一个com.example的日志对象, 这个对象是com的子对象(child), 而com是空字符串的子对象(child)。

    级别(Level)

    日志级别定义了消息的严重性,Level类用于标识哪个等级的消息需要被记录。

    日志级别(降序排列)

    • SEVERE | 严重 (highest)

    • WARNING | 警告

    • INFO | 信息

    • CONFIG

    • FINE

    • FINER

    • FINEST

    另外,你还可以使用 OFF(关闭log记录)ON(记录所有log)。

    LOGGER.setLevel(Level.INFO);
    

    Handler

    每个Logger都能添加多个Handler。

    Handler接收来自Logger的日志,并导出到某个目标(certain target)。

    可以使用setLevel(Level.OFF)方法来关闭Handler,setLevel()方法开启Handler。

    这几个handler是默认提供的

    • ConsoleHandler: 将日志消息输出到控制台
    • FileHandler: 将日志写入文件
    • StreamHandler:将日志写入一个OutputStream
    • SocketHandler: 将日志写入TCP端口
    • MemoryHandler:将日志写入内存缓存中

    INFO 及其以上级别的信息都会默认写到控制台。

    格式化(Formatter)

    Formatter能格式化Handler的输出。

    现成的Formatter

    • impleFormatter:把所有的信息生成为文本
    • XMLFormatter:把日志信息生成为XML输出

    当然,你也可以构建自己的Formatter。后文将会有一个输出HTML的Formatter例子。

    Log Manager

    Log Manager 负责创建和管理Logger和维护配置。

    我们能通过LogManager.setLevel(String name, Level level)方法,来设置一个或多个包的日志级别,如下:

    LogManager.getLogManager().getLogger(Logger.GLOBAL_LOGGER_NAME).setLevel(Level.FINE);
    

    例子

    一个最简单的例子

    package com.twikura.blog;
    
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    public class SimpleLogger {
    
        private static Logger logger = Logger.getLogger(SimpleLogger.class.getName());
    
        public static void main (String[] args) {
    
            logger.info("Logging begins...");   // 记录一个INFO级别的日志,
            try {
                throw new Exception("抛出一个异常");
            } catch (Exception ex){
                logger.log(Level.SEVERE, ex.getMessage(), ex); // // 记录一个SEVERE级别的日志
            }
            logger.info("完成...");
        }
    }
    

    控制台会有相应的信息输出,如下,有三条日志记录,每条记录由时间戳、完全限定类名(fully-qualified class name)、方法名、消息,如果有异常,也会输出异常栈追踪(exception stack trace)。

    十一月 25, 2018 3:47:45 下午 com.twikura.blog.SimpleLogger main
    信息: Logging begins...
    十一月 25, 2018 3:47:45 下午 com.twikura.blog.SimpleLogger main
    严重: 抛出一个异常
    java.lang.Exception: 抛出一个异常
        at com.twikura.blog.SimpleLogger.main(SimpleLogger.java:14)
    
    十一月 25, 2018 3:47:45 下午 com.twikura.blog.SimpleLogger main
    信息: 完成...
    

    通过 FileHandler 来输出一个log文件

    package com.twikura.blog;
    
    import java.io.IOException;
    import java.util.logging.*;
    
    public class FileLogger {
    
        private static Logger logger = Logger.getLogger(FileLogger.class.getName());
    
        public static void main (String[] args)  throws IOException {
    
            // 先创建一个默认的FileHandler
            Handler fh = new FileHandler("path/to/test.log", true);
    
            // 给logger添加一个Handler
            logger.addHandler(fh);
    
            //设置logger级别
            logger.setLevel(Level.FINE);
    
            try {
                // Simulating Exceptions
                throw new Exception("抛出一个异常");
            } catch (Exception ex){
                logger.log(Level.SEVERE, ex.getMessage(), ex);
            }
    
            fh.flush();
            fh.close();
        }
    }
    

    重定向 System.out 和 System.err到log文件中

    package com.twikura.blog;
    
    import java.io.*;
    import java.util.logging.*;
    
    public class FileLoggerRedirect {
        private static final Logger logger = Logger.getLogger(FileLoggerRedirect.class.getName());
    
        public static void main(String[] args) throws IOException {
    
            Handler fh = new FileHandler("path/to/test.log", true);
    
            logger.addHandler(fh);
    
            logger.setLevel(Level.FINE);
    
            // 重定向 System.out 和 System.err
            PrintStream outPS =
                    new PrintStream(
                            new BufferedOutputStream(
                                    new FileOutputStream("path/to/test.log", true)));
            System.setErr(outPS);    // 重定向 System.err
            System.setOut(outPS);
    
            try {
                throw new Exception("抛出一个异常");
            } catch (Exception ex){
                logger.log(Level.SEVERE, ex.getMessage(), ex);
            }
    
    
            System.out.println("输出 System.out");
            System.err.println("输出 System.err");
        }
    }
    

    自定义Formatter

    自定义一个HTML Formatter

    package com.twikura.blog;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.logging.Formatter;
    import java.util.logging.Handler;
    import java.util.logging.Level;
    import java.util.logging.LogRecord;
    
    public class MyHtmlFormatter extends Formatter {
        // this method is called for every log records
        public String format(LogRecord rec) {
            StringBuffer buf = new StringBuffer(1000);
            buf.append("<tr>\n");
    
            // colorize any levels >= WARNING in red
            if (rec.getLevel().intValue() >= Level.WARNING.intValue()) {
                buf.append("\t<td style=\"color:red\">");
                buf.append("<b>");
                buf.append(rec.getLevel());
                buf.append("</b>");
            } else {
                buf.append("\t<td>");
                buf.append(rec.getLevel());
            }
    
            buf.append("</td>\n");
            buf.append("\t<td>");
            buf.append(calcDate(rec.getMillis()));
            buf.append("</td>\n");
            buf.append("\t<td>");
            buf.append(formatMessage(rec));
            buf.append("</td>\n");
            buf.append("</tr>\n");
    
            return buf.toString();
        }
    
        private String calcDate(long millisecs) {
            SimpleDateFormat date_format = new SimpleDateFormat("MMM dd,yyyy HH:mm");
            Date resultdate = new Date(millisecs);
            return date_format.format(resultdate);
        }
    
        // this method is called just after the handler using this
        // formatter is created
        public String getHead(Handler h) {
            return "<!DOCTYPE html>\n<head>\n<style>\n"
                    + "table { width: 100% }\n"
                    + "th { font:bold 10pt Tahoma; }\n"
                    + "td { font:normal 10pt Tahoma; }\n"
                    + "h1 {font:normal 11pt Tahoma;}\n"
                    + "</style>\n"
                    + "</head>\n"
                    + "<body>\n"
                    + "<h1>" + (new Date()) + "</h1>\n"
                    + "<table border=\"0\" cellpadding=\"5\" cellspacing=\"3\">\n"
                    + "<tr align=\"left\">\n"
                    + "\t<th style=\"width:10%\">Loglevel</th>\n"
                    + "\t<th style=\"width:15%\">Time</th>\n"
                    + "\t<th style=\"width:75%\">Log Message</th>\n"
                    + "</tr>\n";
        }
    
        // this method is called just after the handler using this
        // formatter is closed
        public String getTail(Handler h) {
            return "</table>\n</body>\n</html>";
        }
    }
    

    调用Formatter

    package com.twikura.blog;
    
    import java.io.IOException;
    import java.util.logging.*;
    
    public class Test {
        private static Logger logger = Logger.getLogger(Test.class.getName());
    
        public static void main (String[] args)  throws IOException {
            Handler fh = new FileHandler("path/to/test.html", true);
    
            // 设置 Formatter
            fh.setFormatter(new MyHtmlFormatter());
            logger.addHandler(fh);
            try {
                throw new Exception("抛出一个异常");
            } catch (Exception ex){
                logger.log(Level.SEVERE, ex.getMessage(), ex);
            }
    
            fh.flush();
            fh.close();
        }
    }
    
    

    参考

    Java Logging API - Tutorial

    ava Logging Framework

    授权

    知识共享许可协议
    本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
    原文:blog.twikura.com

    相关文章

      网友评论

        本文标题:Java日志的使用

        本文链接:https://www.haomeiwen.com/subject/jgwpqqtx.html