jeecg系统日志管理

Jeecg中通过Spring_AOP+注解方式实现日志的管理

一、设计思路

通过spring的aop切面功能,拦截到请求的所有的符合切面表达式的方法,判断是否含有注解标志,生成日志对象,然后通过aop的后置通知进行日志的持久化。

二、代码实现

1、工程结构:

2、pom.xml增加aop依赖:

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.4</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.4</version>
</dependency>

3、定义我们的Log实体对象
package aop;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.GenericGenerator;
import org.jeecgframework.core.common.entity.IdEntity;

@Entity
@Table(name="assess_log_test")
@DynamicInsert(true)
@DynamicUpdate(true)
@SuppressWarnings("serial")
public class Log implements java.io.Serializable{
/**
* 日志id
*/
private String id;

/**
* 当前操作人id
*/
private String loginAccount;

/**
* 当前操作人ip
*/
private String loginIp;

/**
* 操作请求的链接
*/
private String actionUrl;

/**
* 执行的模块
*/
private String module;

/**
* 执行的方法
*/
private String method;

/**
* 执行操作时间
*/
private Long actionTime;

/**
* 描述
*/
private String description;

/**
* 执行的时间
*/
private Date gmtCreate;

/**
* 该操作状态,1表示成功,-1表示失败!
*/
private Short state;

@Id
@GeneratedValue(generator = "paymentableGenerator")
@GenericGenerator(name="paymentableGenerator",strategy="uuid")
@Column(name="id",nullable=false,length=32)
public String getId() {
return id;
}
@Column(name="login_account",length=32)
public String getLoginAccount() {
return loginAccount;
}
@Column(name="login_ip",length=32)
public String getLoginIp() {
return loginIp;
}
@Column(name="action_url",length=100)
public String getActionUrl() {
return actionUrl;
}
@Column(name="module",length=32)
public String getModule() {
return module;
}
@Column(name="method",length=32)
public String getMethod() {
return method;
}
@Column(name="action_time")
public Long getActionTime() {
return actionTime;
}
@Column(name="description",length=200)
public String getDescription() {
return description;
}
@Column(name="gmt_create")
public Date getGmtCreate() {
return gmtCreate;
}
@Column(name="state")
public Short getState() {
return state;
}

public void setId(String id) {
this.id = id;
}

public void setLoginAccount(String loginAccount) {
this.loginAccount = loginAccount;
}

public void setLoginIp(String loginIp) {
this.loginIp = loginIp;
}

public void setActionUrl(String actionUrl) {
this.actionUrl = actionUrl;
}

public void setModule(String module) {
this.module = module;
}

public void setMethod(String method) {
this.method = method;
}

public void setActionTime(Long actionTime) {
this.actionTime = actionTime;
}

public void setDescription(String description) {
this.description = description;
}

public void setGmtCreate(Date gmtCreate) {
this.gmtCreate = gmtCreate;
}

public void setState(Short state) {
this.state = state;
}

@Override
public String toString() {
return "Log [id=" + id + ", loginAccount=" + loginAccount
+ ", loginIp=" + loginIp + ", actionUrl=" + actionUrl
+ ", module=" + module + ", method=" + method + ", actionTime="
+ actionTime + ", description=" + description + ", gmtCreate="
+ gmtCreate + ", state=" + state + "]";
}

}

4.定义注解对象
package aop;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* 日志记录
*
* @author mgj
* @date 2017-8-11 上午10:53:19
*/
@Target({ElementType.PARAMETER,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemLog {
String module() default "";
String methods() default "";
}
5.定义aop界面拦截方法
package aop;

import java.lang.reflect.Method;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.jeecgframework.core.util.ResourceUtil;
import org.jeecgframework.core.util.StringUtil;
import org.jeecgframework.web.system.pojo.base.TSUser;
import org.jeecgframework.web.system.service.SystemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import antlr.StringUtils;

@Component
@Aspect
public class LogAopAction {
private long BEGIN_TIME;
private long END_TIME;
private Log log = new Log();
@Autowired
private SystemService systemService;

//@Pointcut("execution(* vote.backmanage.teachermanage.controller.AssessTeacherInfoController.*(..))")
//@Pointcut("execution(* vote.backmanage.teachermanage.controller.*.*(..))")
//@Pointcut("execution(* vote.backmanage.teachermanage.controller..*.*(..))")
@Pointcut("execution(* vote.backmanage.teachermanage.controller..*.*(..))")
public void controllerAspect(){}

@Before("controllerAspect()")
public void doBefore(){
BEGIN_TIME = new Date().getTime();
}

@AfterReturning("controllerAspect()")
public void doAfter(){
if (log.getState() == 1 || log.getState() == -1) {
log.setActionTime(END_TIME - BEGIN_TIME);
log.setGmtCreate(new Date(BEGIN_TIME));

System.out.println(log);
System.out.println("存入到数据库");
systemService.save(log);

}else {
System.out.println(log);
System.out.println("不存到数据库里");
}
}
@After("controllerAspect()")
public void after(){
END_TIME = new Date().getTime();
}

@Around("controllerAspect()")
public Object around(ProceedingJoinPoint pjp) throws Throwable{
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes())
.getRequest();
//获得当前用户
TSUser user = ResourceUtil.getSessionUserName();
String name = user.getRealName();
log.setLoginAccount(name);

//拦截的实体类
Object target = pjp.getTarget();
//拦截的方法名
String methodName = pjp.getSignature().getName();
//拦截的方法参数
Object[] args = pjp.getArgs();
//拦截的放参数类型
Signature sig = pjp.getSignature();

MethodSignature msig = null;
if (!(sig instanceof MethodSignature)) {
throw new IllegalArgumentException("该注解只能用于方法");
}

msig = (MethodSignature)sig;
Class[] parameterTypes = msig.getMethod().getParameterTypes();

Object object = null;
Method method = null;

try{
method = target.getClass().getMethod(methodName, parameterTypes);
}catch (Exception e) {
e.printStackTrace();
}

if (null != method) {
if (method.isAnnotationPresent(SystemLog.class)) {//判断是否包含我们自定义的注解
SystemLog systemlog = method.getAnnotation(SystemLog.class);
log.setModule(systemlog.module());
log.setMethod(systemlog.methods());
log.setLoginIp(getIp(request));
log.setActionUrl(request.getRequestURI());

try {
object = pjp.proceed();
log.setDescription("执行成功");
log.setState((short)1);
} catch (Exception e) {
log.setDescription("执行失败");
log.setState((short)-1);
e.printStackTrace();
}

}else {//不包自定义注解
object = pjp.proceed();
log.setDescription("此操作不包含注解");
log.setState((short)0);
}

}else {//不需要拦截
object = pjp.proceed();
log.setDescription("不需要拦截直接运行");
log.setState((short)0);
}

return object;
}

/**
* 获得ip地址
* @param request
* @return
* @author mgj
* @date 2017-8-11 下午2:19:51
*/
private String getIp(HttpServletRequest request){
if (request.getHeader("x-forwarded-for") == null) {
return request.getRemoteAddr();
}
return request.getHeader("x-forwarded-for");
}

}

6.增加aop自动扫描配置

(1)打开spring-mvc.xml文件,增加aop上下文

如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

(2)增加aop自动扫描并实例化bean
<aop:aspectj-autoproxy proxy-target-class="true" />
<bean id="logAopAction" class="aop.LogAopAction"></bean>

7.持久化Log实体的xml配置,使用自动扫描class的形式进行配置。打开spring-mvc-hibernate.xml文件,增加<value>aop.</value>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="entityInterceptor" ref="hiberAspect" />
<property name="hibernateProperties">
<props>
<!--<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> -->
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>
</props>
</property>
<!-- 注解方式配置 -->
<property name="packagesToScan">
<list>
<value>org.jeecgframework.web.system.pojo.*</value>
<value>org.jeecgframework.web.demo.entity.*</value>
<value>org.jeecgframework.web.test.entity.*</value>
<value>org.jeecgframework.web.cgform.entity.*</value>
<value>org.jeecgframework.web.cgreport.entity.*</value>
<value>aop.</value>
</list>
</property>
</bean>

8.使用注解方式,配置日志,在访问的controller方法上,增加@SystemLog(module="区教师库登录",methods="区教师库的assessTeacherInfo()方法")配置
/**
* 教师库管理列表 页面跳转
*
* @return
*/
@RequestMapping(params = "assessTeacherInfo")
@SystemLog(module="区教师库登录",methods="区教师库的assessTeacherInfo()方法")
public ModelAndView assessTeacherInfo(HttpServletRequest request) {
return new ModelAndView("vote/backmanage/teachermanage/assessTeacherInfoList");
}

9.效果

三、注意事项
         1.增加aop自动扫描包时,必须写到spring-mvc.xml内,不可写到spring-mvc-aop.xml文件中。因为spring-mvc.xml会比spring-mvc-aop.xml文先执行。
         2.持久化Log实体,使用自动扫描class的形式进行配置时,规则如下
(1)<value>aop.</value>,会解析为aop/*.class 或者 aop/xxx/*.class。即aop的包以及子包下的所有class。
            (2)<value>aop</value>,会解析为aop/*.class 。即aop的包下的所有class。
            (3)<value>aop.*</value>,会解析为 aop/xxx/*.class。即aop的子包下的所有class。

四、思考
1.需要深刻理解spring_mvc.xml文件的执行顺序。
2.需要深刻理解使用自动扫描class的形式的配置规则。

---------------------------------------------------------------------------

附录:

Log实体创建的mysql脚本:

drop table if exists assess_log_test;

create table assess_log_test (
id varchar(32) not null COMMENT ‘主键id‘,
login_account varchar(32) default null comment ‘当前操作人‘,
login_ip varchar(32) default null comment ‘登录ip‘,
action_url varchar(100) default null comment ‘请求url‘,
module varchar(32) default null comment ‘执行模块‘,
method varchar(32) default null comment ‘执行方法‘,
action_time bigint default 0 comment ‘执行操作时间‘,
description varchar(200) default null comment ‘描述‘,
gmt_create datetime default null comment ‘执行时间‘,
state smallint(6) default null comment ‘操作状态‘,
primary key (id)
)engine=innodb default charset=utf8 comment ‘操作日志表‘;

转自:https://blog.csdn.net/ma451152002/article/details/77234236

原文地址:https://www.cnblogs.com/ybal/p/10417124.html

时间: 2024-10-26 12:50:33

jeecg系统日志管理的相关文章

Linux(RadHat)基础学习—系统日志管理

系统日志管理 1.系统日志 系统日志是记录系统中硬件.软件和系统问题的信息,同时还可以监视系统中发生的事件.用户可以通过它来检查错误发生的原因,或者寻找受到×××时×××者留下的痕迹.系统日志包括系统日志.应用程序日志和安全日志. 2.系统日志默认分类 /var/log/messages 系统服务的日志,包括服务的信息,报错等等 /var/log/secure 系统登陆认证信息日志 /var/log/maillog 系统邮件服务信息日志 /var/log/cron 系统定时任务信息日志 /var

Linux系统日志管理:(3)系统和服务日志

Linux操作系统中有三种主要的日志子系统: (1)连接时间日志 (2)进程统计日志 (3)系统和服务日志 连接时间日志和进程统计日志由rsyslog(旧版是syslog)日志服务驱动,系统和服务日志由相对应的网络服务驱动和管理: 系统和服务日志   除了连接时间日志和进程统计日志,系统很多的其他日志文件,这些日志文件是有rsyslog(旧版为syslog服务)的日志服务负责管理:由rsyslog日志服务驱动的默认放在/var/log/路径下: 其中几个重要的系统日志: /var/log/las

Linux系统日志管理:(2)进程统计日志

Linux操作系统中有三种主要的日志子系统: (1)连接时间日志 (2)进程统计日志 (3)系统和服务日志 连接时间日志和进程统计日志由rsyslog(旧版是syslog)日志服务驱动,系统和服务日志由相对应的网络服务驱动和管理: 进程统计日志   进程统计日志可以监控用户在服务器上的操作时非常有效,所记录的操作会存入/var/account/pacct文件中: #accton accton: no arguments Usage: accton [OPTION] on|off|ACCOUNTI

Linux系统日志管理

2015-03-17 iptables 日志单独管理 vim /etc/rsyslog.conf # Don't log private authentication messages! *.info;mail.none;authpriv.none;cron.none;kern.none        /var/log/messages # Save iptables messages also to iptables.log kern.*                            

Linux系统日志管理:(1)连接时间日志

Linux操作系统中有三种主要的日志子系统: (1)连接时间日志 (2)进程统计日志 (3)系统和服务日志 连接时间日志和进程统计日志由rsyslog(旧版是syslog)日志服务驱动,系统和服务日志由相对应的网络服务驱动和管理: 连接时间日志 连接时间日志由/var/run/utmp和/var/log/wtmp两个文件记录,系统自动更新:这两个文件不能通过cat命令来查看,但是可以通过w/who/ac/finger/last/lastlog等命令查看.(关于/var/run/utmp的字段定义

:Linux 系统日志管理 日志转储

Linux日志服务器设置 使用“@IP:端口”或“@@IP:端口”的格式可以把日志发送到远程主机上. 假设需要管理几十台服务器,每天的重要工作就是查看这些服务器的日志,可是每台服务器单独登录,并且查看日志非常烦琐,此时可以把几十台服务器的日志集中到一台日志服务器上吗?这样每天只要登录这台日志服务器,就可以查看所有服务器的日志,. 设置过程 假设服务器端的服务器 IP 地址是 192.168.0.210,主机名是 localhost.localdomain:客户端的服务器 IP 地址是 192.1

Linux syslog 系统日志管理

=============================================================================== rsyslog记录日志于mysql: 操作如下: 实验环境:CentOS 7 操作系统 前提: 准备好msql server或mariadb server(一定要编辑配置文件/etc/my.cnf,添加跳过反向解析等)并启动服务: 实验步骤: 1.安装rsyslog连接至mysql server的驱动模块: # yum install r

利用Spring AOP做系统日志管理(annotaction注解版)

在进入主题之前,你必须对Spring 的AOP有一定的认识了解,本文还引用到一定的反射机制,请一并学之哦,谢谢大家支持! 首先,在构建好ssh框架后,我们先声明用来记录日志的实体类Log,代码如下: package com.smartsoft.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.p

RDIFramework.NET ━ 9.13 系统日志与系统异常管理 ━ Web部分

RDIFramework.NET ━ .NET快速信息化系统开发框架 9.13  系统日志与系统异常管理 -Web部分  一个软件在投入运行时不可能没有任何异常,在软件发生异常时及时的记录下来,也好我们及时对异常进行跟踪,以解决发生的异常,避免异常的再次发生.异常分为两种情况,一种为客户端发生的异常,另一种为服务端发生的异常.对于客户端发生的异常,通常都会及时的弹出,用户看到后可以反馈给我们.服务器端产生的异常会自动记录到数据库中,管理员可以通过框架异常管理进行查看操作. 框架日志管理对于框架的