java中日志切面_java切面做日志记录

前言

众说周知,aop是oop思想的延续,是为了我们更好的程序的开发, 更便于我们对技术及代码的维护。

今天就利用aop来做一个日志的记 录。废话不多说,上代码。

实例

entity

import lombok.Data;

import lombok.NoArgsConstructor;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;

import java.io.Serializable;

@Entity

@Table(name="tb_operate_record")

@Data

@NoArgsConstructor

public class TbOperateRecord implements Serializable {

private static final long serialVersionUID = 4907931420975674126L;

@Id

@GeneratedValue(generator ="paymentableGenerator")

@GenericGenerator(name ="paymentableGenerator", strategy = "uuid")

@Column(name= "log_record_id")

private String id; // 主键 采用UUID 策略目的是为了适配数据库(具体项目可以选择合适的生成策略)

@Column(name="input_Params")

private String inputParams; //方法输入的参数

@Column(name="user_name")

private String userName; //操作人

@Column(name="operate_description")

private String operateDescription ; //用户操作记录描述

@Column( name = "req_ip")

private String reqIp; //请求ip地址

@Column(name="req_url")

private String reqUrl; //请求reqURL

@Column(name = "take_time")

private String takeTime; //耗时

@Column(name="operate_time")

private String operateTime; //操作时间

@Column(name= "method_description")

private String methodDescription; //接口功能描述

@Column(name="method_name")

private String methodName; //方法名

切面类

@Component

@Aspect

public class LoggerRecord {

private final static Logger logger = LoggerFactory.getLogger(LoggerRecord.class);

private final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 规定日期格式

@Autowired

private HttpServletRequest request;

@Autowired

private TbOperateRecordRepository tbOperateRecordRepository;

//定义切点

@Pointcut(value = "execution(* com.*.controller.*.*(..))")

public void PointCutJcLog(){

}

@Around(value = "PointCutJcLog()") //编写逻辑

public Object saveJcRecordLogger(ProceedingJoinPoint joinPoint)throws Throwable{

TbOperateRecord operateRecord = new TbOperateRecord(); //创建日志记录对象

long startTime = System.currentTimeMillis();

Object retVal = joinPoint.proceed();

long entTime = System.currentTimeMillis();

String consumeTime = formatDuring(entTime - startTime);

operateRecord.setTakeTime(consumeTime);

operateRecord.setOperateTime(df.format(new Date()));

//从session中取出用户及部门信息

getUserInfo(operateRecord); //获取用户信息方法

//创建日志操作对象

Class> target = joinPoint.getTarget().getClass();

getJcLoggerSource(operateRecord, target); //获取日志目录

MethodSignature signature =(MethodSignature)joinPoint.getSignature(); //从切面织入点处通过反射机制获取织入点处的方法

Method method = signature.getMethod();

operateRecord.setMethodName(method.getName());

getUsingAndInterfaceFunction(operateRecord, method); //获取用途及接口功能描述

Object[] args = joinPoint.getArgs();

getRequestAgrs(operateRecord, args);

String remoteAddr = request.getRemoteAddr();//获取请求地址

operateRecord.setReqIp(remoteAddr);

String url = request.getRequestURL().toString();

operateRecord.setReqUrl(url);

try {

tbOperateRecordRepository.save(operateRecord);

logger.info("操作日志记录成功");

} catch (Exception e) {

logger.error("操作日志记录新增失败",e.getMessage());

}

return retVal; // 使用 ProceedingJoinPoin 该类必须返回,即释放拦截的

}

//获取请求参数

private void getRequestAgrs(TbOperateRecord operateRecord, Object[] args) {

if(null!= args){

List> paramsMap = new ArrayList>();

HttpServletRequest request;

for (int i = 0; i

try{

request = (HttpServletRequest) args[i]; //过滤参数为接口类型的

//如果是HttpServletRequest则跳过

continue;

}catch (Exception e){

ConcurrentHashMap eachParam = new ConcurrentHashMap<>();

eachParam.put("第"+(i+1)+"参数",args[i]);

paramsMap.add(eachParam);

}

}

String content = JSON.toJSONString(paramsMap);

operateRecord.setInputParams(content);

}else{

operateRecord.setInputParams("该方法没有请求参数");

}

}

//记录信息的组装

private void getOperateDescription(TbOperateRecord operateRecord, String name) {

String description = "";

StringBuffer buffer = new StringBuffer("用户【");

description = buffer.append(operateRecord.getUserName() + "】,于【")

.append(operateRecord.getOperateTime() + "】,执行【")

.append(operateRecord.getMethodDescription()+ "】操作,请求接口【")

.append(name + "】,请求ip【")

.append(operateRecord.getReqIp() + "】,请求参数【")

.append(operateRecord.getInputParams() + "】").toString();

operateRecord.setOperateDescription(description);

}

//请求耗时计算

public static String formatDuring(long time) {

long minutes = (time % (1000 * 60 * 60)) / (1000 * 60);

long seconds = (time % (1000 * 60)) / 1000;

long subsec = time % 1000;

return minutes + "分钟," + seconds + "秒," + subsec + "毫秒 ";

}

// 用户信息的获取 (根据自己项目封装的工具类取值)

private void getUserInfo(TbOperateRecord operateRecord) {

String userName="";

try {

Session currentUser = Session.getCurrentUser(request.getSession());

UserInfo userinfo = currentUser.getUserinfo();

if(null !=userinfo){

userName = userinfo.getUserName();

}

} catch (Exception e) {

logger.error("未获取当前登录人相关信息",e.getMessage());

}

operateRecord.setUserName(userName);

}

Repository

import com.sanling.credit.wd.entity.TbOperateRecord;

import org.springframework.data.jpa.repository.JpaRepository;

public interface TbOperateRecordRepository extends JpaRepository {

}

注意

提高篇:

切点的选择及正则的写法很重要,必须写对

execution使用

本文同步分享在 博客“WindwardBird”(CSDN)。

如有侵权,请联系 support@oschina.cn 删除。

本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值