美文网首页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