日志的处理器

日志组件的编写

主要实现的几个功能:
1 操作的记录的处理理.
2 处理的灵活多样化.
3 使用的主便性.

首先,定义了一个接口Log,功能为:
addLog添加一条日志记录.
addLogFactory removeLogFactory getFactory添加/移除/获取日志处理工厂
setFinalFactory getFinalFactory 设置/获取最终日志处理工厂.
下面看一下LogFactory接口功能
isAccept某条记录是否由日志处理工厂的处理.
processLog处理日志记录
LogItem(日志项目)的功能如下.
getInput获取取操作时送过来的参数
getOldData获取旧数据(在更新数据时有用)
getStaticItem获取静态的数据(比如,用户名,IP等,比较固定的信息)

LogItem的实现如LogItemImpl所示.可以根据自己的实际需要重新继承LogItem.
LogFactory的实现如DBLogFactory所示.DBLogFactory实现的功能是把日志记录写到数据库中去.使用时LogFactory是要重新继承的部分,参照DBLogFactory即可.
Log的实现现AbstractLog实现了Log的大部分方法(除了addLog以外),基本上可以不用再继承Log,只要继承AbstractLog即可.
SwanLog是Log的一个具体实现一般情况下已经够用.不够的话可以自己承继AbstractLog类即可.

以上的类实现以后剩下的就是使用的问题了.
先来测试运行的情况,我是使用postgresql作为测试的,大家可以把DBLogFactory里的getConnection改成自己的连接.因为写到数据库的表名为tbllog我把tbllog的建表sql放到附件最后,可以用该语句建立表先.
然后运行SwanLog可以看到数据表中插入了一条记录.
到此为止该日志已经可以用了,剩下的就是使用中的问题了.
相信大家都想在编写程序时不用管Log的问题,只要把程序写好就可以自动建立Log了.下面是该日志添加代码中的方法.
对WEB程序,直接用我已经写好的类RequestInput,直接从Request里获得Input,然后从session里获取得静态的属性(当然初始化时要先设置好).至于OldData就没什么好办法了.
然后在程序进行Post(或Get)方法之前把代码addLog.如果你的Servlet没继承类或者没有使工作流的话那么就麻烦了,要一个一个的加,如果已经有了那就很简单了直接加就行了.就改一个地方即可.
有的库的日志可能是存在多个表里面的,可以建立多个LogFactory就可以了,只要写一下isAccept方法即可.
对客户端程序或者是RMI…..的程序,最主要的任务就是实现Input方法,相信大家都有自己的数据封装方法,实现起来应该很方便的.
以下是代码供大家浏览,剩余的类如Input….大家可以在我的权限组件的附加代码里找到(最后一篇).如果有什么好建议请与我联系.
========================Log.java===============================
package org.fswan.log;

/**
* @author Swan Fong (方志文)
* E-mail: fswan@yeah.net
* Site: http://blog.csdn.net/fswan
* 2004-11-19 10:37:44
* 日志接口
*/
public interface Log
{
/**
* 添加日志记录
* @param item 日志项目
* @return 添加结果
*/
public int addLog(LogItem item);
/**
* 添加日志处理工厂
* @param fac 日志处理工厂
*/
public void addFactory(LogFactory fac);
/**
* 移除日志处理工厂
* @param fac 日志处理工厂
*/
public void removeFactory(LogFactory fac);
/**
* 获取所有的日志处理工厂
* @return 日志处理工厂
*/
public LogFactory[] getFactory();
/**
* 设置最终日志处理工厂
* @param fac 日志处理工厂
*/
public void setFinalFactory(LogFactory fac);
/**
* 获取最终数据处理工厂
* @return 日志处理工厂
*/
public LogFactory getFinalFactory();
}
============================LogItem.java==================
package org.fswan.log;

import org.fswan.Input;

/**
* @author Swan Fong (方志文)
* E-mail: fswan@yeah.net
* Site: http://blog.csdn.net/fswan
* 2004-11-19 11:17:26
* 日志项目
*/
public interface LogItem
{
/**
* 获取操作信息
* @return 操作信息
*/
public Input getInput();
/**
* 获取原始数据
* @param prop 数据标识
* @return 数据
*/
public String getOldData(String prop);
/**
* 获取静态数据
* @param prop 数据标识
* @return 数据
*/
public String getStaticItem(String prop);
}
==============================LogFactory.java==========================
package org.fswan.log;

/**
* @author Swan Fong (方志文)
* E-mail: fswan@yeah.net
* Site: http://blog.csdn.net/fswan
* 2004-11-19 11:15:00
* 日志处理工厂
*/
public interface LogFactory
{
/**
* 该工厂是否能处理某一日志
* @param item 日志项目
* @return 能否处理
*/
public boolean isAccept(LogItem item);
/**
* 处理日志,处理结果为有理数,不能为负数和0
* @param item 日志项目
* @return 处理结果
*/
public int processLog(LogItem item);
}
=======================DBLogFactory.java ==========================
package org.fswan.log;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.sqlException;
import java.sql.Timestamp;
import java.util.Date;

/**
* @author Swan Fong (方志文)
* E-mail: fswan@yeah.net
* Site: http://blog.csdn.net/fswan
* 2004-11-19 14:25:14
* 这个日志工厂把数据存到数据库中,如果成功返回SUCCESS失败返回FAILURE
* 包含字段 IP,描述,时间,是否成功
* 表名为tbllog,对应的字段为 ip,user,description,date,returnvalue
*
*/
public class DBLogFactory implements LogFactory
{
/**
* 操作成功
*/
public static final int SUCCESS = 1;
/**
* 操作失败
*/
public static final int FAILURE = 2;
/* (non-Javadoc)
* @see org.fswan.log.LogFactory#doneLog(org.fswan.log.LogItem)
*/
public int processLog(LogItem item)
{
Connection conn = getConnection();
try
{
PreparedStatement pst = conn.prepareStatement("insert into tbllog (ip,/"user/",processdate,retvalue) values(?,?,?)");
pst.setInt(1,ipToInt(item.getStaticItem("IP")));
pst.setString(2,item.getStaticItem("user"));
pst.setString(3,"It's Operate");
pst.setTimestamp(4,new Timestamp(new Date().getTime()));
pst.setInt(5,1);
pst.executeUpdate();
conn.close();
return 1;
}catch (sqlException e)
{
e.printStackTrace();
}
return 2;
}

/* (non-Javadoc)
* @see org.fswan.log.LogFactory#isAccept(org.fswan.log.LogItem)
*/
public boolean isAccept(LogItem item)
{
return true;
}
/**
* 获取数据库连接
* @return 数据库联接
*/
public Connection getConnection()
{
try
{

Class.forName("org.postgresql.Driver");
return DriverManager.getConnection("jdbc:postgresql://localhost:5432/hrms","fswan","314843");
} catch (ClassNotFoundException e)
{
e.printStackTrace();
} catch (sqlException e)
{
e.printStackTrace();
}
return null;
}
/**
* 把IP的字符串转成数字型
* @param ip IP的字符串表示
* @return IP对应的数字
*/
public int ipToInt(String ip)
{
String[] ips = ip.split("//.");
if(ips.length != 4)return -1;
int[] iip = new int[ips.length];
for (int i = 0; i < iip.length; i++)
{
iip[i] = Integer.parseInt(ips[i]);
}
return (iip[0]<<24) | (iip[1] << 16) | (iip[2] << 8) | iip[3];
}
}
========================LogItemImpl.java=====================
package org.fswan.log;

import java.util.HashMap;
import java.util.Properties;

import org.fswan.Input;

/**
* @author Swan Fong (方志文)
* E-mail: fswan@yeah.net
* Site: http://blog.csdn.net/fswan
* 2004-11-19 14:17:04
*
*/
public class LogItemImpl implements LogItem
{
Input input;
HashMap map;
Properties staticItem;
public LogItemImpl(Input input,HashMap map,Properties staticItem)
{
this.input = input;
this.map = map;
this.staticItem = staticItem;
}
/* (non-Javadoc)
* @see org.fswan.log.LogItem#getInput()
*/
public Input getInput()
{
return input;
}

/* (non-Javadoc)
* @see org.fswan.log.LogItem#getOldData(java.lang.String)
*/
public String getOldData(String prop)
{
return ""+map.get(prop);
}

/* (non-Javadoc)
* @see org.fswan.log.LogItem#getStaticItem(java.lang.String)
*/
public String getStaticItem(String prop)
{
return staticItem.getProperty(prop);
}

}

============================AbstractLog.java========================
package org.fswan.log;

/**
* @author Swan Fong (方志文)
* E-mail: fswan@yeah.net
* Site: http://blog.csdn.net/fswan
* 2004-11-19 11:37:24
*
*/
public abstract class AbstractLog implements Log
{
private LogFactory[] facs;
private LogFactory finalFactory;

/* (non-Javadoc)
* @see org.fswan.log.Log#addFactory(org.fswan.log.LogFactory)
*/
public void addFactory(LogFactory fac)
{
if(fac == null) return;
if(facs == null)
{
facs = new LogFactory[1];
facs[0] = fac;
}
else
{
LogFactory[] fs = new LogFactory[facs.length+1];
System.arraycopy(facs,fs,facs.length);
fs[fs.length-1] = fac;
facs = fs;
}
}

/* (non-Javadoc)
* @see org.fswan.log.Log#getFactory()
*/
public LogFactory[] getFactory()
{
return facs;
}

/* (non-Javadoc)
* @see org.fswan.log.Log#getFinalFactory()
*/
public LogFactory getFinalFactory()
{
return finalFactory;
}

/* (non-Javadoc)
* @see org.fswan.log.Log#removeFactory(org.fswan.log.LogFactory)
*/
public void removeFactory(LogFactory fac)
{
if(fac == null) return;
if(facs == null) return;
for (int i = 0; i < facs.length; i++)
{
if(facs[i] == fac)
{
LogFactory[] fs = new LogFactory[facs.length-1];
System.arraycopy(facs,i);
System.arraycopy(facs,i+1,i,fs.length-i);
facs = fs;
return;
}
}
}

/* (non-Javadoc)
* @see org.fswan.log.Log#setFinalFactory(org.fswan.log.LogFactory)
*/
public void setFinalFactory(LogFactory fac)
{
finalFactory = fac;
}

}
==========================SwanLog.java============================
package org.fswan.log;

import java.util.Properties;


/**
* @author Swan Fong (方志文)
* E-mail: fswan@yeah.net
* Site: http://blog.csdn.net/fswan
* 2004-11-19 11:49:27
* 实现的日志处理器,先在LogFactory里找到合适的处理器并进行处理,如果处理不了再在最终处理器处理,处理后的返回值是false
*
*/
public class SwanLog extends AbstractLog
{
public static final int HAVENTPROCESS = 0;
public SwanLog()
{
addFactory(new DBLogFactory());
}
/* 如果是factory进行处理的返回值为处理返回的值,如果是最终处理器处理返回值为处理返回值的负数
* (non-Javadoc)
* @see org.fswan.log.Log#addLog(org.fswan.log.LogItem)
*/
public int addLog(LogItem item)
{
LogFactory[] fs = getFactory();
if(fs != null)
{
for (int i = 0; i < fs.length; i++)
{
if(fs[i].isAccept(item))
{
return fs[i].processLog(item);
}
}
}
LogFactory f = getFinalFactory();
if(f!=null)
if(f.isAccept(item))
{
return -f.processLog(item);
}
return HAVENTPROCESS;
}

public static void main(String[] args)
{
Properties p = new Properties();
p.setProperty("user","Swan");
p.setProperty("IP","202.192.133.145");
new SwanLog().addLog(new LogItemImpl(null,null,p));
}
}

==========================tbllog.script=========================CREATE TABLE tbllog( ip int8,"user" varchar(40),description varchar(4000),processdate timestamp,retvalue int2)

相关文章

来源:http://www.postgres.cn/docs/11/ 4.1.1.&#160;标识符和关键词 SQL标识符和关键词必须以一个...
来源:http://www.postgres.cn/docs/11/ 8.1.&#160;数字类型 数字类型由2、4或8字节的整数以及4或8...
来源:http://www.postgres.cn/docs/11/ 5.1.&#160;表基础 SQL并不保证表中行的顺序。当一个表被读...
来源:http://www.postgres.cn/docs/11/ 6.4.&#160;从修改的行中返回数据 有时在修改行的操作过程中...
来源:http://www.postgres.cn/docs/11/ 13.2.1.&#160;读已提交隔离级别 读已提交是PostgreSQL中的...
来源:http://www.postgres.cn/docs/11/ 9.7.&#160;模式匹配 PostgreSQL提供了三种独立的实现模式匹...