java 输出日志文件_JAVA中自定义日志输出到指定文件

本文介绍了一个名为CustomFileStreamHandler的JAVA类,该类扩展了StreamHandler,用于自定义日志输出到指定文件。类中包含了初始化方法、打开写入文件的方法以及发布日志信息的方法,支持设置日志文件的最大字节数、是否追加写入和日志保存天数等参数。
摘要由CSDN通过智能技术生成

packagecom.bsk.log;importjava.io.BufferedOutputStream;importjava.io.BufferedReader;importjava.io.BufferedWriter;importjava.io.File;importjava.io.FileOutputStream;importjava.io.FileReader;importjava.io.FileWriter;importjava.io.IOException;importjava.io.OutputStream;importjava.text.ParsePosition;importjava.text.SimpleDateFormat;importjava.util.Date;importjava.util.LinkedList;importjava.util.logging.Level;importjava.util.logging.LogRecord;importjava.util.logging.Logger;importjava.util.logging.StreamHandler;public class CustomFileStreamHandler extendsStreamHandler{//输出流

privateMeteredStream msOut;//日志玩家的写入的字节数, limit 为0 表示没有限制

private int limit = 50000;//是否添加的玩家末尾

private booleanappend;//保存存在的日志文件

private LinkedListfiles;//希望写入的日志文件

privateFile file;//希望写入的日志路径

privateString fileUrl;//希望写入的当天日志路径

privateString fileUrlDay;//保存几天之内的日志文件

private int dateInter = 1;//索引文件,用于记录当前日志记录信息,请不要认为的修改

privateFile indexFile;/*** 初始化自定义文件流处理器

*@paramfileUrl 文件路径, 可以是个目录或希望的日志名称,如果是个目录则日志为“未命名”

* 指定日志名称时不需要包括日期,程序会自动生成日志文件的生成日期及相应的编号

*@paramlimit 每个日志希望写入的最大字节数,如果日志达到最大字节数则当天日期的一个新的编 号的日志文件将被创建,最新的日志记录在最大编号的文件中

*@paramdateInter 事务保存的日期间隔

*@paramappend 是否将日志写入已存在的日志文件中

*@throwsjava.lang.Exception*/

public CustomFileStreamHandler(String fileUrl, int limit, int dateInter, boolean append) throwsException {super();this.fileUrl =fileUrl;if (dateInter <= 0) {throw new IllegalArgumentException("时间间隔必须大于0");

}if (limit < 0) {throw new IllegalArgumentException("写入日志文件的最大字节数必须大于0");

}this.limit =limit;this.dateInter =dateInter;this.append =append;

openWriteFiles();

}public CustomFileStreamHandler(String fileUrl, boolean append) throwsException {super();this.fileUrl =fileUrl;this.append =append;

openWriteFiles();

}/*** 获得将要写入的文件*/

private synchronized void openWriteFiles() throwsException {if (fileUrl == null) {throw new IllegalArgumentException("文件路径不能为null");

}//files = getWritedLog();//checkLogFile();

getWriteFile();if(append) {//openFile(files.getLast(), append);

openFile(file, append);

}else{

getLastFile();

}

}private void getWriteFile()throwsException{

SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd");

String trace= sdf.format(newDate().getTime());

fileUrlDay= fileUrl+"_"+trace+".log";

file= newFile(fileUrlDay);if (!file.exists()) {

file.createNewFile();

}

}/*** 打开需要写入的文件

*@paramfile 需要打开的文件

*@paramappend 是否将内容添加到文件末尾*/

private void openFile(File file, boolean append) throwsException {//System.out.println("***opend = true " + file.toString());

int len = 0;if(append) {

len= (int) file.length();

}

FileOutputStream fout= newFileOutputStream(file.toString(), append);

BufferedOutputStream bout= newBufferedOutputStream(fout);

msOut= newMeteredStream(bout, len);

setOutputStream(msOut);

}/*** 将离现在最近的文件作为写入文件的文件

* 例如 D:logmylog_30_2008-02-19.log

* mylog表示自定义的日志文件名,2008-02-19表示日志文件的生成日期,30 表示此日期的第30个日志文件*/

private voidgetLastFile() {try{super.close();

SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd");

String trace= sdf.format(newDate().getTime());int maxLogCount = 0; //获得当前最大的日志文件编号//System.out.println("********共有文件**********");

for(File file : files) {//System.out.println(file.toString());

String fileName =file.toString();//获得相同同日期日志文件的最大编号

if (fileName.indexOf(trace) != -1) {int last = fileName.lastIndexOf('_');int beforeLast = fileName.lastIndexOf('_', last - 1);

maxLogCount= Integer.valueOf(fileName.substring(beforeLast + 1, last));

}

}//System.out.println("********");//System.out.println("maxLogCount == " + maxLogCount);

File file = newFile(fileUrl);

String logIndex= (maxLogCount + 1) + "_" +trace;if (file.isDirectory()) { //是个目录

files.add(new File(fileUrl + File.separator + "未命名_" + logIndex + ".log"));

}else{

files.add(new File(fileUrl + "_" + logIndex + ".log"));

}

writeLogIndex(logIndex,true);

openFile(files.getLast(),false);

}catch(Exception ex) {

Logger.getLogger(CustomFileStreamHandler.class.getName()).log(Level.SEVERE, null, ex);

}

}/*** 读取已经记录的日志的时间信息*/

private LinkedListgetWritedLog() {

LinkedList fileList = new LinkedList();

BufferedReader br= null;try{

File file= newFile(fileUrl);if (fileUrl.endsWith("/") || fileUrl.endsWith("/")) { //是个目录

if (!file.exists()) {

file.mkdirs();

}

}if (file.isDirectory()) { //只有指定file存在且是个目录

indexFile = new File(file.toString() + File.separator + "logindex");

}else{

indexFile= new File(file.getParent() + File.separator + "logindex");

}if (!indexFile.exists()) {

indexFile.createNewFile();

}

FileReader fr= null;

fr= newFileReader(indexFile);

br= newBufferedReader(fr);

String line= null;while ((line = br.readLine()) != null) {if (line.trim().length() != 0) {if (file.isDirectory()) { //是个目录

fileList.add(new File(fileUrl + File.separator + "未命名" + "_" + line + ".log"));

}else{

fileList.add(new File(fileUrl + "_" + line + ".log"));

}

System.out.println("line == " +line);

}

}returnfileList;

}catch(Exception ex) {

Logger.getLogger(CustomFileStreamHandler.class.getName()).log(Level.SEVERE, null, ex);

}finally{try{

br.close();

}catch(IOException ex) {

Logger.getLogger(CustomFileStreamHandler.class.getName()).log(Level.SEVERE, null, ex);

}

}return null;

}/*** 写入日志索引

*@paramlogIndex 日志所以

*@paramisAppend 是否添加到索引文件中*/

private void writeLogIndex(String logIndex, booleanisAppend) {

File file= newFile(fileUrl);

BufferedWriter bw= null;try{

FileWriter fw= null;if (file.isDirectory()) { //是个目录//是个目录

fw = new FileWriter(new File(file.toString() + File.separator + "logindex"), isAppend);

}else{

fw= new FileWriter(new File(file.getParent() + File.separator + "logindex"), isAppend);

}

bw= newBufferedWriter(fw);

bw.newLine();

bw.write(logIndex,0, logIndex.length());

bw.flush();

}catch(Exception ex) {

Logger.getLogger(CustomFileStreamHandler.class.getName()).log(Level.SEVERE, null, ex);

}finally{try{

bw.close();

}catch(IOException ex) {

Logger.getLogger(CustomFileStreamHandler.class.getName()).log(Level.SEVERE, null, ex);

}

}

}/*** 检查当前日志时间

* 删除过期日志,并检查日志索引中是否包含了现在日期*/

private voidcheckLogFile() {try{

SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd");

String trace= sdf.format(newDate().getTime());boolean isIncludeNow = false;

LinkedList overdueLog = new LinkedList(); //过期的日志文件

long nowDate =sdf.parse(trace).getTime();for(File file : files) {if (file.toString().indexOf(trace) != -1) {

isIncludeNow= true;

}if ((nowDate - sdf.parse(file.toString(), new ParsePosition(file.toString().lastIndexOf('_') + 1)).getTime()) / (86400 * 1000) > 5) {

overdueLog.add(file);//System.err.println("将被删除的日志为 " + file);

}

}//删除过期日志记录, 并重写日志索引文件

if (overdueLog.size() != 0) {

files.removeAll(overdueLog);

indexFile.delete();

indexFile.createNewFile();

String fileStr= null;for(File file : files) {

fileStr=file.toString();

writeLogIndex(fileStr.substring(fileStr.lastIndexOf('_') - 1, fileStr.lastIndexOf('.')), true);

}//删除过期文件

for(File file : overdueLog) {

file.delete();

}

}//如果没有包含当天的日期同时日志需要添加到文件末尾,则添加当天日期的日志文件

if (!isIncludeNow &&append) {

File file= newFile(fileUrl);

String logIndex= 1 + "_" +trace;if(file.isDirectory()) {//是个目录

files.add(new File(fileUrl + File.separator + "未命名_" + logIndex + ".log"));

}else{

files.add(new File(fileUrl + "_" + logIndex + ".log"));

}

writeLogIndex(logIndex,true);

}

}catch(Exception ex) {

Logger.getLogger(CustomFileStreamHandler.class.getName()).log(Level.SEVERE, null, ex);

}

}/*** 发布日志信息*/@Overridepublic synchronized voidpublish(LogRecord record) {super.publish(record);super.flush();if (limit > 0 && msOut.written >=limit) {

getLastFile();

}

}/*** 抄自FileHandler的实现,用于跟踪写入文件的字节数

* 这样以便提高效率*/

private class MeteredStream extendsOutputStream {privateOutputStream out;//记录当前写入字节数

private intwritten;

MeteredStream(OutputStream out,intwritten) {this.out =out;this.written =written;

}public void write(int b) throwsIOException {

out.write(b);

written++;

}

@Overridepublic void write(byte buff[]) throwsIOException {

out.write(buff);

written+=buff.length;

}

@Overridepublic void write(byte buff[], int off, int len) throwsIOException {

out.write(buff, off, len);

written+=len;

}

@Overridepublic void flush() throwsIOException {

out.flush();

}

@Overridepublic void close() throwsIOException {

out.close();

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值