日志的处理器

日志组件的编写

主要实现的几个功能:
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)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读601次。Oracle的数据导入导出是一项基本的技能,但是对于懂数据库却不熟悉Oracle的同学可能会有一定的障碍。正好在最近的一个项目中碰到了这样一个任务,于是研究了一下Oracle的数据导入导出,在这里跟大家分享一下。......_oracle 迁移方法 对比
文章浏览阅读553次。开头还是介绍一下群,如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请联系 liuaustin3 ,在新加的朋友会分到2群(共700多人左右 1 + 2)。最近我们在使用MYSQL 8 的情况下(8.025)在数据库运行中出现一个问题 参数prefer_order_i..._mysql prefer_ordering_index
文章浏览阅读3.5k次,点赞3次,收藏7次。折腾了两个小时多才成功连上,在这分享一下我的经验,也仅仅是经验分享,有不足的地方欢迎大家在评论区补充交流。_navicat连接opengauss
文章浏览阅读2.7k次。JSON 代表 JavaScript Object Notation。它是一种开放标准格式,将数据组织成中详述的键/值对和数组。_postgresql json
文章浏览阅读2.9k次,点赞2次,收藏6次。navicat 连接postgresql 注:navicat老版本可能报错。1.在springboot中引入我们需要的依赖以及相应版本。用代码生成器生成代码后,即可进行增删改查(略)安装好postgresql 略。更改配置信息(注释中有)_mybatisplus postgresql
文章浏览阅读1.4k次。postgre进阶sql,包含分组排序、JSON解析、修改、删除、更新、强制踢出数据库所有使用用户、连表更新与删除、获取今年第一天、获取近12个月的年月、锁表处理、系统表使用(查询所有表和字段及注释、查询表占用空间)、指定数据库查找模式search_path、postgre备份及还原_pgsql分组取每组第一条
文章浏览阅读3.3k次。上一篇我们学习了日志清理,日志清理虽然解决了日志膨胀的问题,但就无法再恢复检查点之前的一致性状态。因此,我们还需要日志归档,pg的日志归档原理和Oracle类似,不过归档命令需要自己配置。以下代码在postmaster.c除了开启归档外,还需要保证wal_level不能是MINIMAL状态(因为该状态下有些操作不会记录日志)。在db启动时,会同时检查archive_mode和wal_level。以下代码也在postmaster.c(PostmasterMain函数)。......_postgresql archive_mode
文章浏览阅读3k次。系统:ubuntu22.04.3目的:利用向日葵实现windows远程控制ubuntu。_csdn局域网桌面控制ubuntu
文章浏览阅读1.6k次。表分区是解决一些因单表过大引用的性能问题的方式,比如某张表过大就会造成查询变慢,可能分区是一种解决方案。一般建议当单表大小超过内存就可以考虑表分区了。1,继承式分区,分为触发器(trigger)和规则(rule)两种方式触发器的方式1)创建表CREATE TABLE "public"."track_info_trigger_partition" ( "id" serial, "object_type" int2 NOT NULL DEFAULT 0, "object_name..._pg数据表分区的实现
文章浏览阅读3.3k次。物联网平台开源的有几个,就我晓得的有、、thingskit、JetLink、DG-iot(还有其他开源的,欢迎在评论区留言哦!),然后重点分析了下ThingsBoard、ThingsPanel和JetLink,ThingsBoard和Jetlinks是工程师思维产品,可以更多的通过配置去实现开发的目的,ThingsPanel是业务人员思路产品,或者开发或者用,避免了复杂的配置带来的较高学习门槛。ThingsBoard和Jetlinks是Java技术体系的,ThingsPanel是PHP开发的。_jetlinks和thingsboard
文章浏览阅读3.8k次。PostgreSQL 数据类型转换_pgsql数字转字符串
文章浏览阅读7k次,点赞3次,收藏14次。在做数据统计页面时,总会遇到统计某段时间内,每天、每月、每年的数据视图(柱状图、折线图等)。这些统计数据一眼看过去也简单呀,不就是按照时间周期(天、月、年)对统计数据进行分个组就完了嘛?但是会有一个问题,简单的写个sql对周期分组,获取到的统计数据是缺失的,即没有数据的那天,整条记录也都没有了。如下图需求:以当前月份(2023年2月)为起点,往后倒推一年,查询之前一年里每个月的统计数据。可见图中的数据其实是缺少的,这条sql只查询到了有数据的月份(23年的1月、2月,22年的12月)_如何用一条sql查出按年按月按天的汇总
文章浏览阅读3.8k次,点赞66次,收藏51次。PostgreSQL全球开发小组与2022年10月13日,宣布发布PostgreSQL15,这是世界上最先进的开源数据库的最新版本_mysql8 postgresql15
文章浏览阅读1.3k次。上文介绍了磁盘管理器中VFD的实现原理,本篇将从上层角度讲解磁盘管理器的工作细节。_smgrrelationdata
文章浏览阅读1.1k次。PostgreSQL设置中文语言界面和局域网访问_postgressql汉化
文章浏览阅读4.2k次。PostgreSQL 修改数据存储路径_如何设置postgresql 数据目录
文章浏览阅读4.7k次。在项目中用到了多数据源,在连接postgres数据库时,项目启动报错,说数据库连接错误,说dual不存在,网上好多教程都是说数据库查询的时候的大小写问题,而这个仅仅是连接,咋鞥却处理方法是修改application-dev.yml中的配置文件.项目中的druid参数是这样的:确实在配置文件中有个查询语句。_relation "dual" does not exist
文章浏览阅读4.9k次。PostgreSQL是一款强大的关系型数据库,但在实际使用过程中,许多用户经常会遇到慢SQL的问题。这些问题不仅会降低数据库性能,还会直接影响业务流程和用户体验。因此,本文将会深入分析PostgreSQL慢SQL的原因和优化方案,帮助用户更好地利用这个优秀的数据库系统。无论你是初学者还是专业开发者,本文都将为你提供实用的技巧和方法,让你的PostgreSQL数据库始终保持高效快速。_postgresql数据库优化
文章浏览阅读1.6k次。Linux配置postgresql开机自启_linux 启动pgsql
文章浏览阅读2k次。本篇介绍如何在centos7系统搭建一个postgresql主备集群实现最近的HA(高可用)架构。后续更高级的HA模式都是基于这个最基本的主备搭建。_postgresql主备