日志的处理器

类别:Java 点击:0 评论:0 推荐:

日志组件的编写

 主要实现的几个功能:
 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: [email protected]
 * 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: [email protected]
 * 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: [email protected]
 * 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: [email protected]
 * 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\",description,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: [email protected]
 * 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: [email protected]
 * 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,0,fs,0,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,0,fs,0,i);
    System.arraycopy(facs,i+1,fs,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: [email protected]
 * 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://com.8s8s.com/it/it13247.htm