您的位置:首页 > 编程语言 > Java开发

JAVA 实现简单的日志工具

2016-04-18 11:26 441 查看
因为需求有点变化,原来需要写入数据库的数据现在变为把json字符串写到文档,本来使用logback轻松可以做到日志写入,但是上面说需要自己写。

需求比较简单,在rest服务调用写文件接口,当文件大小超过定值时,新建文件进行存储。

开始我采用的方式是每次调用都会实例一个File,对文件进行写操作,完成后进行关闭,但是rest服务后期会做压力测试,当很多请求写同一个文件时,最后程序卡死了,所以最后想采用一个专门线程对单一文件进行写,所以需要在内存中申请一块内存,调用文件写接口将数据放入内存,然后线程将内存中数据写到文件。

为了提高写入内存,和从内存读取数据落地操作的并发性,我申请了两块内存,一块专门进行写,一块进行读取落地,当写入内存满滞后,进行两块内存作业的切换。后来考虑到采用当内存满才进行写入操作的方式,可能当程序发生错误时,会将很大一部分内存中的数据都丢失掉,所以我有参考oracle日志线程的功能,添加了定时落地功能,在内存满或者定时器时间到达时进行数据落地,具体代码如下,以供参考。package com.liwe.commons;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import org.springframework.stereotype.Service;

@Service
public class FileBufferWrite implements Runnable {
final static long filesize=1024;
final int size = 1024;
byte[] cache1 = new byte[size];
byte[] cache2 = new byte[size];
Object lockr = new Object();
Thread thd = null;
FileBufferWrite ptr = this;
FileOutputStream fos;
int pos = 0;
int cacheforuse = 1;
long filelen=0;
int writting = 0;
int lastlen=0;
String pathName;
public String getPathName() {
return pathName;
}

public void setPathName(String pathName) {
this.pathName = pathName;
}

File file=new File(pathName+"log.txt");
public FileBufferWrite() {

}

public void switchcache() {
if (pos != 0) {
System.out.println("switch cache");
cacheforuse = 1 - cacheforuse;
lastlen=pos;
pos = 0;
synchronized (lockr) {
lockr.notify();
}
}
}

public Thread getThread() {
Thread thd = new Thread(this);
thd.start();
new Thread(new Runnable() {
public void run() {
while (true) {
try {
Thread.sleep(1000);
synchronized (ptr) {
while (writting == 1) {
Thread.sleep(100);
}
switchcache();

}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}
}).start();
return thd;
}

public void run() {
try {
while (true) {
synchronized (lockr) {
lockr.wait();
}
writting = 1;
System.out.println("start write file from cache" + cacheforuse);
try {
byte[] bfw;
bfw=new byte[lastlen];
if (cacheforuse == 1) {
System.arraycopy(cache2, 0,bfw, 0,lastlen);
} else {
System.arraycopy(cache1, 0,bfw, 0,lastlen);
}
try {
file=new File(pathName+"log.txt");
if(!file.getParentFile().exists())
file.getParentFile().mkdirs();
if(!file.exists())
file.createNewFile();
fos = new FileOutputStream(file);

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(filelen+lastlen>filesize){

File[] fl=new File(pathName).listFiles();
int num=fl.length;
fos.close();
file.renameTo(new File(pathName+"log"+num+".txt"));

file=new File(pathName+"log.txt");
fos=new FileOutputStream(file);
filelen=0;
System.out.println("change file");
}
fos.write(bfw);
fos.flush();
filelen+=lastlen;

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("file write over");
writting = 0;
}

} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public synchronized void write(String str) throws InterruptedException {
if (thd == null) {
thd = getThread();
}
str+="\r\n";
byte[] tmp = str.getBytes();
if (pos + tmp.length > size) {
System.out.println("cache filled");
while (writting == 1) {
System.out.println("sleeping");
Thread.sleep(10);
}
switchcache();

System.out.println("notify");

}
System.out.println("cache write");
if (cacheforuse == 1) {
System.arraycopy(tmp, 0, cache1, pos, tmp.length);
pos += tmp.length;
} else {
System.arraycopy(tmp, 0, cache2, pos, tmp.length);
pos += tmp.length;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 日志 简单实现