具体实施方式
以下结合附图对本发明的原理和特征进行描述,所举实例只用于解释本发明,并非用于限定本发明的范围。
如图1所示,本发明包括以下步骤:
步骤1:配置包含日志存储API的文件,即log.jar文件,并将该文件导入JAVA(Java,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台的总称)工程中,即将本发明Jar文件:log.jar文件复制到JAVA工程的Lib(类库)目录中,并设置到JAVA工程类路径classpath(让Java执行环境找到指定的Java程序(也就是.class文件)的变量)中。
log.jar文件内核心处理程序片段如下:
1. Scheduler.Java -把阻塞队列里边的日志入库的线程
package com.sitech.i4a.audit.log;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.concurrent.ArrayBlockingQueue;
import org.apache.log4j.Logger;
import com.sitech.i4a.audit.log.env.LogENV;
import com.sitech.i4a.audit.log.vo.LogVO;
/**
* 项目名称:i4a-v2.0
* <p>Title: Scheduler</p>
* <p>Description: 把阻塞队列里边的日志入库的线程</p>
* <p>Copyright: Copyright (c) 2009</p>
* <p>Company: SI-TECH </p>
* authorsi-tech
* 创建时间:Aug 15, 2009 8:14:42 PM
* version 1.0
* 修改人:si-tech
* 修改时间:Aug 15, 2009 8:14:42 PM
* 修改备注:
*
*/
public class Scheduler extends AbstractScheduler { private static Logger logger = Logger.getLogger(Scheduler.class);
//存放日志的队列。
private final ArrayBlockingQueue<LogVO> queue;
public Scheduler(ArrayBlockingQueue<LogVO> queue) {
this.queue = queue;
}
/**
* 执行存放。
*/
public void run() {
while(true) {
//如果不够执行批量存储的数,则等待0.5秒后再做判断。
int size = queue.size();
if(size >= LogENV.EXCUT_BATCH_SIZE) {
try { excute();
} catch (Exception e) { e.printStackTrace();
logger.error("日志批量入库出错:"+e.getMessage());
continue;
}
}else {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
logger.error("日志批量入库线程异常:" +e.getCause());
continue;
}
}
}
}
protected void excute() throws Exception {
Connection conn = getConnection();
PreparedStatement preState = null;
Statement statment = null;
try {
preState = conn.prepareStatement(sql);
statment = conn.createStatement();
//则执行批量入库。
for(int i=0; i < LogENV.EXCUT_BATCH_SIZE; i++) {
LogVO log = queue.take();
excuteSQL(preState,statment,log);
}
preState.executeBatch();
conn.commit();
} catch (SQLException e) {
logger.error(e.getMessage());
throw new Exception(e);
} catch (InterruptedException e) {
logger.error(e.getMessage());
throw new Exception(e);
} finally {
try {
closeConn(conn,statment,preState);
} catch (SQLException e) {
logger.error(e.getMessage());
e.printStackTrace();
}
}
}
}
2. LogWriter.Java -提供写日志的公用方法
package com.sitech.i4a.audit.log;
import java.util.concurrent.ArrayBlockingQueue;
import com.sitech.i4a.audit.log.env.LogENV;
import com.sitech.i4a.audit.log.vo.LogVO;
import com.sitech.i4a.audit.log.buffer.*;
/**
*
* 项目名称:i4a-v2.0
* <p>Title: LogWriter</p>
* <p>Description: 提供写日志的公用方法</p>
* <p>Copyright: Copyright (c) 2009</p>
* <p>Company: SI-TECH </p>
* authorsi-tech
* 创建时间:Aug 17, 2009 8:50:54 AM
* version 1.0
* 修改人:si-tech
* 修改时间:Aug 17, 2009 8:50:54 AM
* 修改备注:
*
*/
public class LogWriter {
//存放日志的队列。
private static ArrayBlockingQueue<LogVO> queue =
new ArrayBlockingQueue<LogVO>(LogENV.QUEUE_SIZE);
//执行队列中的日志入库的线程。
private static Scheduler scheduler = new Scheduler(queue);
static{
scheduler.start();
}
/**
* 外部调用写日志的方法。
*/
public static void writeLog(LogVO log) {
if(!queue.offer(log)) {
FileManager.deal(log);
}
}
}
步骤2:配置文件参数:
配置调用日志存储API的文件参数,即配置logenv.properties文件中的内容(即数据库连接参数、队列大小参数、批量入库条数参数等参数),然后将文件放入JAVA工程类路径(classpath)。配置文件参数如下:
#存放logVO阻塞队列的大小。
LOG_QUEUE_SIZE=10
#批量存储大小。
SQL_BATCH_EXCUTE_SIZE=4
#队列放满后,临时文件路径。
LOG_FILE_DIR=d:/working
#是否用容器配置的JNDI数据源,value = true Or false。
USE_WEB_APPS_DATASOURCE=false
#数据源名称,(如果使用容器的JNDI数据源,则配置该项)
DATA_SOURCE_NAME=jdbc/logDB
##----如果USE_WEB_APPS_DATASOURCE=false,请对数据源参数进行配置。
步骤3:加载配置的logenv.properties文件参数,并初试化数据库连接、日志队列以及日志文件目录;
#驱动名
DRIVER_CLASS=oracle.jdbc.driver.OracleDriver
#数据库连接URL
JDBC_URL=jdbc:oracle:thin:172.XX.XX.117:1523:basdb
#数据库用户
DB_USER=XXX
#该用户密码
USER_PASSWORD=XXX
#池最大连接数
MAX_POOL_SIZE=20
#池最小的连接数。
MIN_POOL_SIZE=2
#池初始化连接数。
INITIAL_POOL_SIZE=2
步骤4:调用日志存储API:
Java Class代码中需要引用以下JAVA类:
import com.sitech.i4a.audit.log.LogWriter;
import com.sitech.i4a.audit.log.vo.LogVO;
import com.sitech.i4a.audit.log.vo.LogVOFactory;
Java Class代码进行日志存储调用过程如下:
// 初始化log日志对象
LogVO log = LogVOFactory.createLogVO();
// 设置日志类型字段,字段数据可根据具体应用去定义
log.setLogType();
// 设置操作类型字段,字段数据可根据具体应用去定义
log.setOperateModule();
// 构造日志操作内容
StringBuffer contentSb = new StringBuffer();
contentSb.append("log content : ");
contentSb.append("log content log content.");
// 设置log日志对象操作内容属性
log.setOperateContent(contentSb.toString());
log.setOperateResult();
// 调用日志记录API
LogWriter.writeLog(log);
// 调用操作完成
步骤5:通过判断日志队列是否已满,将日志记录至日志队列,或将日志记录至日志文件中并更新日志文件目录,然后将日志存入数据库。
本发明支持属性配置文件方式进行配置,配置项包括数据库连接参数、队列大小参数、批量入库条数参数、日志文件存储目录等,可以根据系统性能要求以及硬件资源配置进行灵活调整。JAVA程序加载logenv.properties配置文件参数,并完成数据库连接、日志队列、文件目录的初试化。
配置参数成功加载后,可以使用本发明提供的存储API(application programming interface,应用程序接口)进行日志存储,本发明提供简洁的存储API对JAVA开发者屏蔽具体的程序处理的流程,JAVA开发者可以通过简单的程序语言调用API,完成日志的异步存储。
调用存储API,判断此时日志队列是否已满,如果未满,直接记录至日志队列,扫描日志队列进程进行数据的批量入库操作存储日志记录;如果此时日志队列已满,则将日志记录到配置目录中的日志文件中,文件扫描线程重复扫描文件队列,并进行日志存储,日志存储后删掉日志文件。日志记录队列和文件与日志存储异步进行,提高日志存储的效率和性能。
本发明支持Oracle、MysqL、MsSql等各版本数据库。
本发明在将日志存储如数据库时采用了数据库连接技术,在将日志存储入日志队列或日志文件时采用了阻塞队列技术、JAVA线程技术以及文件读写等技术实现JAVA程序中异步方式的日志存储,解决同步日志存储性能瓶颈问题,提高日志存储效率,从而提高系统整体性能。
以上所述仅为本发明的较佳实施例,并不用以限制本发明,凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。