为java.util.logging自定义文件处理器及日志输出格式
文章分类:Java编程最近闲来无事,刚好拾起了来公司的第一个项目,发现里面的logging功能有点弱,竟然不支持按日期文件名输出,更惨的是由于引入了些apache的公用了包,一个项目里竟然同时出现logging,log4j,commons-logging,这年头引用下开源包还要用不同的loger.记得log4j好像支持输出的文件按日期来分类的,jdk自带的logging好像还没有,于是google了一把,发现JAVA中自定义日志输出格式及自定义文件处理器的实现 ,功能还不错,有些bug及不合理的地方,于是再修改下,凑合用用.
直接代码:
FileStreamHandler实现
- package com.xunlei.demo.util;
- import java.io.BufferedOutputStream;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.TreeSet;
- import java.util.logging.Filter;
- import java.util.logging.Formatter;
- import java.util.logging.Handler;
- import java.util.logging.Level;
- import java.util.logging.LogManager;
- import java.util.logging.LogRecord;
- import java.util.logging.Logger;
- import java.util.logging.StreamHandler;
- /**
- * 自定义日志文件处理器---日期及文件大小存储,并自动清除过期日志文件
- *
- * @author ZengDong
- * @since 2008-9-11下午11:16:39
- */
- public class XLFileStreamHandler extends StreamHandler {
- /**
- * 抄自FileHandler的实现,用于跟踪写入文件的字节数 这样以便提高效率
- */
- private class MeteredStream extends OutputStream {
- private OutputStream out;
- // 记录当前写入字节数
- private int written;
- MeteredStream(OutputStream out, int written) {
- this.out = out;
- this.written = written;
- }
- public void close() throws IOException {
- out.close();
- }
- public void flush() throws IOException {
- out.flush();
- }
- public void write(byte buff[]) throws IOException {
- out.write(buff);
- written += buff.length;
- }
- public void write(byte buff[], int off, int len) throws IOException {
- out.write(buff, off, len);
- written += len;
- }
- public void write(int b) throws IOException {
- out.write(b);
- written++;
- }
- }
- private class XLLogFile extends File {
- private static final long serialVersionUID = 952141123094287978L;
- private Date date;
- private String dateString;
- private int sid;
- public int getSid() {
- return this.sid;
- }
- public void setSid(int sid) {
- this.sid = sid;
- }
- public Date getDate() {
- return this.date;
- }
- public void setDate(Date date) {
- this.date = date;
- }
- public String getDateString() {
- return this.dateString;
- }
- public void setDateString(String dateString) {
- this.dateString = dateString;
- }
- public int compareTo(File another) {
- XLLogFile ano = (XLLogFile) another;
- int dateComResult = date.compareTo(ano.getDate());
- if (dateComResult == 0) {
- return sid - ano.getSid();
- }
- return dateComResult;
- }
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
- public XLLogFile(String pathname) {
- super(pathname);
- try {
- int dot = pathname.lastIndexOf('.');
- int split = pathname.lastIndexOf(splitDateIndexChar);
- int underline = pathname.lastIndexOf('_');
- dateString = pathname.substring(underline + 1, split);
- String numStr = pathname.substring(split + 1, dot);
- date = sdf.parse(dateString);
- sid = Integer.valueOf(numStr);
- } catch (Exception e) {
- System.err.println("log对应文件夹中包含了不符合XLLOG格式的文件!!");
- e.printStackTrace();
- }
- }
- }
- private static final String undifine = "xlcallcenter";
- // 是否将日志写入已存在的日志文件中
- private boolean append;
- // 保存几天之内的日志文件
- // 时间间隔小于等于0时表明不删除历史记录
- private int dateinterval = 5;
- // 保存存在的日志文件
- private Map > files;
- // 每个日志希望写入的最大字节数,如果日志达到最大字节数则当天日期的一个新的编号的日志文件将被创建,最新的日志记录在最大编号的文件中
- // 文件大小为小于等于0时表明不限制日志文件大小
- private int limit = 1048576 * 5;
- // 输出流
- private MeteredStream msOut;
- // 文件路径, 可以是个目录或希望的日志名称,如果是个目录则日志为"callcenter_zd"
- // 指定日志名称时不需要包括日期,程序会自动生成日志文件的生成日期及相应的编号
- private String pattern = "./log/xunleidemo";
- private char splitDateIndexChar = '#';
- public XLFileStreamHandler() throws Exception {
- configure();
- openWriteFiles();
- }
- /**
- * 初始化自定义文件流处理器
- *
- * @param fileUrl
- * 文件路径, 可以是个目录或希望的日志名称,如果是个目录则日志为"callcenter_zd"
- * 指定日志名称时不需要包括日期,程序会自动生成日志文件的生成日期及相应的编号
- * @param limit
- * 每个日志希望写入的最大字节数,如果日志达到最大字节数则当天日期的一个新的编
- * 号的日志文件将被创建,最新的日志记录在最大编号的文件中
- * @param dateinterval
- * 保存几天之内的日志文件
- * @param append
- * 是否将日志写入已存在的日志文件中
- * @throws java.lang.Exception
- */
- public XLFileStreamHandler(String fileUrl, int limit, int dateinterval,
- boolean append) throws Exception {
- super();
- this.pattern = fileUrl;
- this.limit = limit;
- this.dateinterval = dateinterval;
- this.append = append;
- openWriteFiles();
- }
- /**
- * 检查当前日志时间,删除过期日志
- */
- private void deleteExpiredLog() {
- try {
- // 今天作为基准
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
- String today = sdf.format(new Date().getTime());
- // 删除过期日志
- for (String keyDate : files.keySet()) {
- if ((sdf.parse(today).getTime() - sdf.parse(keyDate).getTime())
- / (86400 * 1000) > dateinterval) {
- TreeSet traceDateFiles = files.get(keyDate);
- for (File deletingFile : traceDateFiles) {
- // if(deletingFile.exists()) {
- deletingFile.delete();
- // }
- }