一、日志的重要性
对于一个应用程序来说日志记录是必不可少的一部分。线上问题追踪,基于日志的业务逻辑统计分析等都离不日志。
二、实现核心代码(本文不做持久层操作,只提示切入点)
1.创建新的Springboot项目,我使用之前已经创建过的:hello-rabbit
2.核心依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--spring boot web的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
3.创建包com.basic.hellorabbit.aspect,创建日志切面操作类LogAspect.java
package com.basic.hellorabbit.aspect;
import com.basic.hellorabbit.entity.RequestLog;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
/**
* @Description: 日志切面操作
* @Author: Joe
* @CreateDate: 2020/3/18 13:11
*/
@Aspect
@Component
public class LogAspect {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
RequestLog requestLog = null;
/**
* 定义一个切面(第1*:所有请求;第2*:com.basic.hellorabbit.controller下所有类;第3*:所有方法;..任何参数)
*/
@Pointcut("execution(* com.basic.hellorabbit.controller.*.*(..))")
public void logs(){
}
/**
* 切面之前
* @param joinPoint
*/
@Before("logs()")
public void doBefore(JoinPoint joinPoint){
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String url = request.getRequestURL().toString();
String ip = request.getRemoteAddr();
String classMethod = joinPoint.getSignature().getDeclaringTypeName()+"."+joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
ArrayList<Object> objects = new ArrayList<>();
for (int i = 0; i < args.length; i++) {
objects.add(args[i]);
}
requestLog = new RequestLog(url,ip,classMethod,objects,new Date());
logger.info("request:{}",requestLog);
}
/**
* 请求之后
*/
@After("logs()")
public void doAfter(){
}
/**
* 方法执行完返回结果
* @param result
*/
@AfterReturning(returning = "result",pointcut = "logs()")
public void doAfterReturn(Object result){
logger.info("return:"+result);
requestLog.setResult(result);
/*此处可加入写入数据库操作*/
System.out.println(requestLog);
}
}
4.创建包com.basic.hellorabbit.controller,创建类IndexController.java
package com.basic.hellorabbit.controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class IndexController {
@RequestMapping(value ="/{id}/{name}",method = RequestMethod.GET)
public String index(@PathVariable Integer id, @PathVariable String name){
System.out.println("测试index方法");
return "test";
}
}
5.创建包com.basic.hellorabbit.entity,创建日志记录类RequestLog.java
package com.basic.hellorabbit.entity;
import lombok.Data;
import java.util.Date;
/**
* @Description: 日志类
* @Author: Joe
* @CreateDate: 2020/3/18 13:36
*/
@Data
public class RequestLog {
/**
* 访问的url
*/
private String url;
/**
* 访问的IP
*/
private String ip;
/**
* 访问类的方法
*/
private String classMethod;
/**
* 请求参数的值
*/
private Object args;
/**
* 操作时间
*/
private Date createTime;
/**
* 返回结果
*/
private Object result;
public RequestLog() {
}
public RequestLog(String url, String ip, String classMethod, Object args, Date createTime) {
this.url = url;
this.ip = ip;
this.classMethod = classMethod;
this.args = args;
this.createTime = createTime;
}
}
三、测试如图
四、异常、注意及建议
注意
1.有时候本地测试的IP是:0:0:0:0:0:0:0:1,这是ipv6的表现形式,对应ipv4来说相当于127.0.0.1,也就是本机。
建议
1.1 该用本机自己的IP地址访问;
1.2 将localhost改为127.0.0.1;
1.3修改C:\Windows\System32\drivers\etc\hosts这个文件,文件中的 # ::1 localhost 这一行被注释掉
2. 获取输入参数值的问题,出现类型异常,我使用遍历
后续建议
由于日志操作比较频繁且数据量大,建议抛给RabbitMQ等消息队列处理以减少数据库I/O压力
RabbitMQ搭建和使用,可以去看消息队列——RabbitMQ在Centos的基本搭建和消息队列——RabbitMQ与Springboot的简单使用