设为首页 收藏本站
查看: 1109|回复: 0

[经验分享] HP的项目中曾做一个业务日志系统

[复制链接]

尚未签到

发表于 2015-10-6 09:02:40 | 显示全部楼层 |阅读模式
  项目背景:
   DRAGON是供情报机关等在电信运营商查询处客户通讯记录等的业务系统。因为会牵涉到电信客户的隐私,所以要求对于用户在系统内的所有增加/删除/修改等操作,以及对于客户资料以及通讯记录等隐私内容的查询和查看等操作记录操作日志并且可以通过页面查询这些操作日志。操作日志记录的内容至少包括操作时间,操作人,操作对象的属性等等。
  下图为操作日志的查询页面:用户选择object-type后,将在action下拉表中列出对应的action,选择action之后,将列出该action需要记载的字段,以供用户查询。如用户选择了updateWarrant这个action,将列出如warrantType, warrantId等字段。
  注:本图摘自HP-DRAGON用户使用手册。
  实现思路:
  此系统是通过J2EE实现,遵从常规的 action->service->dao层次。
  (1) 因为所有的增删改以及某些查询/查看都需要记录日志,如果记日志的操作放在增删改的代码中,一来耦合严重,二来工作量巨大,所以采用Spring的AOP对Service层方法进行拦截,然后根据表达时,如“user.name”来读取方法的参数或者返回值,从而生成业务操作日志。
  (2)记录操作日志的行为不可以影响业务流程,并且记录日志的IO操作也会带来性能问题,所以将采用异步写数据的方式,以及核心业务代码会生成logEvent的内容,然后通过JMS发送消息,MDB收到消息后再去写数据库。
  (3)当前登录用户的信息将放在ThreadLocal中。
  具体实现:
  1. 数据库设计:
  1.1.entity: 保存系统中的实体类型相关的信息,如warrant, workitem等。具体字段如下:

  • entity_id:pk
  • entity_name:实体类型的名称
  • ENABLE_FLAG:对于该类实体是否需要记录用户操作日志。
  • description: 描述。
  1.2. action: 保存用户操作,如deleteWarrant等(和action是manyToOne的关系)

  • id_action: pk,
  • name: 操作的名称,
  • description: 描述,
  • entity_id: fk到entity,
  • action_type: 当前操作的类型,如删除/修改/增加等,对于不同的类型,获取数据的方式也不一样。
  • enable_flag:该操作是否需要记录日志。
1.3. event用来保存与action对应的方法名等的信息。(与action是manyToOne的关系。因为从用户角度的一个操作,如修改warrant数据,代码上可能会有多个方法与之对应,如updateWarrantType(),updateWarrantTime()等等。)


  • id_event: pk,
  • id_action: fk to action,
  • method_name:方法名称。
  • serviceClassname:service接口的className。
  • enable_flag:是否对该方法记录日志
  • argClasses(varchar2(1024)):方法参数类型的full name用“,”拼接成的字符串。 该字段主要用于方法重载的情况,需要根据参数的类型来判断是否需要记录业务操作日志。
  1.4. action_detail: 需要在日志中记载的详细内容,如warrant的typeName等

  • ID_ACTION_DETAIL: PK
  • ID_ACTION: FK to Action
  • DETAIL_NAME:字段的名称。
  • DETAIL_ORDER:页面上该字段显示的顺序
  • PARAM_INDEX:该字段对应方法的参数的顺序(从0开始)。如果该字段取自方法的返回值,请设为-1.
  • DETAIL_VALUE_EXPRESSION:取值表达式,如: user.name; users[0].name等。
  • ENABLE_FLAG: 该字段是否需要记录日志
  • FORMAT_PROVIDER_CALSS_NAME:实现了FormatProviderInterf接口的class的fullName。用于处理如: deleteWarrant(LongwarrantId)的情况,我们需要根据先根据warrantId查询到warrant对象,然后才能记录其type等属性。再如根据表达式获得的值是date类型,我们需要先进行格式化后再显示给用户。这些操作都放在formatProviderInterf的实现类中。
  • FORMAT_PATTERN: format的格式,供FORMAT_PROVIDER_CALSS_NAME中指定的class使用。
  • UPDATE_FLAG: 当前字段是否需要记录update前后的值(主要用于update操作的情况)。
  • SEARCHABLE: 客户是否可以根据该字段查询操作日志。
  • DESCRIPTION:描述。
  1.5. log_event: 操作日志(不包括具体的内容)。

  • id_log_event: PK
  • event_date:操作时间,
  • id_user:用户Id
  • id_action: fk to action
  • id_object:所影响的objec的id
  • object_name: 对象的名称。
  • id_status_from: 变化前的状态。
  • id_status_to: 变化后的状态
  • crc: 根据时间,内容等生成的验证码,防止有人通过DB后台修改记录。
  1.6. log_event_detail: 操作日志的详细内容。

  • id_log_event_detail: pk
  • id_log_event: fk至logEvent
  • id_action_detail:fk to action_detail
  • name:字段名称,从action_detail中copy过来的冗余字段。
  • value: 字段的值
  • event_date:copy自log_event的冗余字段。
  • crc:验证码。
  2.接口FormatProviderInterf

package com.hp.dragon.business.formats.interf;  

public interface FormatProviderInterf {   

    public String format(Object data, String formatString) throws BusinessException;  

}  

  3. Spring的配置文件:
  view plaincopy to clipboardprint?


  • <bean id="advisorEventManager" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
  •        <property name="advice">
  •            <ref bean="logEventService" />
  •        </property>
  •        <property name="patterns">
  •            <list>
  •                <value>.*\.create.*</value>
  •                <value>.*\.insert.*</value>
  •                <value>.*\.update.*</value>
  •                <value>.*\.delete.*</value>
  •                <value>.*\.changeStatus.*</value>
  •                <value>.*\..*Tracked</value>
  •            </list>
  •        </property>
  •    </bean>
  4.LogEventSeviceImpl.invoke()的Sequence图:

  注: 对于不同的操作类型:如update操作,需要在beforeTracking()方法中reload更新前的对象,将更新前的属性值保存在一个局部对象中,然后在afterTracking()中再记录下更新后的值,从而生成logevent的信息。create/insert操作则需在afterTracking()记录信息,而delete则只能在beforeTracking()中记录信息。
  5. 总结
  l 日志系统的任何错误或者异常都不可以影响业务的主流程。
  l  由于DRAGON是以产品的形式出售给不同的电信运营商,要求该日志系统具有较高的可配置性以适应不同客户的要求,所以系统中存在大量的可配置选项。
  l  将配置信息放在数据库中,而不是使用annotation,则是为了方便delivery team实施的方便-只需修改数据库数据而不用修改代码即可满足不同运营商的需求。
  l  由于日志数量巨大,所以建议定期删除,至少在查询的时候,只允许客户查询最新的数据。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-123175-1-1.html 上篇帖子: HP unix 常用管理命令 下篇帖子: HP SiteScope 11
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表