import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
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.io.UnsupportedEncodingException;
import java.net.URLDecoder; /**
* 实现Web层的日志切面
* @author lpf
*/
@Component
@Aspect
@Order(1)
public class WebLogAspect {
private Logger log = LoggerFactory.getLogger(getClass());
private ThreadLocal<Long> startTime = new ThreadLocal<>(); /**
* 定义一个切入点.
* 解释下:
* <p>
* ~ 第一个 * 代表任意修饰符及任意返回值.
* ~ 第二个 * 任意包名
* ~ 第三个 * 定义在web包或者子包
* ~ 第四个 * 任意方法
* ~ .. 匹配任意数量的参数.
*/
// @Pointcut("execution(public * com.kfit.*.web..*.*(..))")
// use
// @Pointcut("execution(public * org.zhilan..*Controller.*(..))") // @Pointcut("(execution(public * org.zhilan.timer.*Service.*(..)))")
@Pointcut("(execution(public * com.haoyun..*Controller.*(..))) "
// + "|| execution(public * com.haoyun.timer.*Service.*(..)) "
+ "&& !execution(* com.haoyun.login.LoginController.getSystemState())"
)
public void webLog() {
} @Before("webLog()")
public void doBefore(JoinPoint joinPoint) throws UnsupportedEncodingException {
startTime.set(System.currentTimeMillis()); // 接收到请求,记录请求内容
log.info("========================= before start =========================");
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature; log.info("CLASS_METHOD : " + methodSignature.getDeclaringTypeName() + "." + methodSignature.getName()); // 记录下请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if(attributes != null){
HttpServletRequest request = attributes.getRequest();
log.info("IP : " + request.getRemoteAddr());
} log.info("请求参数: 名称 值");
String[] argsNameArray = methodSignature.getParameterNames();
Object[] argsValueArray = joinPoint.getArgs();
for (int i = 0; i < argsNameArray.length; i++) {
log.info("args_name: " + argsNameArray[i]); String argValue = argsValueArray[i] != null ? argsValueArray[i].toString() : "";
if (argsNameArray[i].contains("encode")) {
String str = URLDecoder.decode(argValue, "utf-8");
log.info("args_value: " + (str.length() > 200 ? str.substring(0, 200) + "..." : str));
} else {
log.info("args_value: " + (argValue.length() > 200 ? argValue.substring(0, 200) + "..." : argValue));
}
} log.info("========================= before end =========================");
} @AfterReturning(returning="rvt", pointcut="webLog()")
public void doAfterReturning(JoinPoint joinPoint, Object rvt) {
// 处理完请求, 返回内容
log.info("========================= after returning start =========================");
Signature signature = joinPoint.getSignature();
log.info("CLASS_METHOD : " + signature.getDeclaringTypeName() + "." + signature.getName()); if(rvt != null){
String str = rvt.toString();
if (str.length() > 200) {
str = str.substring(0, 200) + "...";
} log.info("return 返回值:");
log.info(str);
} log.info("耗时(毫秒) : " + (System.currentTimeMillis() - startTime.get())); log.info("========================= after returning end =========================");
}
}

实现Web层的日志切面(方便清晰查看日志)的更多相关文章

  1. web部署启动或者运行报错查看日志寻找问题方法

    今天运行一个项目,启动报错,查看日志,只看到了前半段错误日志,根据前半段错误日志差查找原因,找了两个小时,也没有解决掉,最后根据后半段错误日志十分钟定位错误,给解决了,以后出现问题不能急躁,查看完成的 ...

  2. 【docker】docker限制日志文件大小的方法+查看日志文件的方法

    一.docker日志文件的方法 除了 docker logs -f 容器ID/容器名 这个方法以外. 在linux上,一般docker的日志文件存储在/var/lib/docker/container ...

  3. Web层后端权限模块

    从零开始编写自己的C#框架(19)——Web层后端权限模块   不知不觉本系统写了快三个月了,最近写页面的具体功能时感觉到有点吃力,很多地方如果张嘴来讲的话可以说得很细,很全面,可写成文字的话,就不太 ...

  4. Django websocket之web端实时查看日志实践案例

    这是Django Channels系列文章的第二篇,以web端实现tailf的案例讲解Channels的具体使用以及跟Celery的结合 通过上一篇<Django使用Channels实现WebS ...

  5. 从零开始编写自己的C#框架(16)——Web层后端父类

    本章节讲述的各个类是后端系统的核心之一,涉及到系统安全验证.操作日志记录.页面与按键权限控制.后端页面功能封装等内容,希望学习本系列的朋友认真查看新增的类与函数,这对以后使用本框架进行开发时非常重要. ...

  6. Spring Boot 2.0 教程 | AOP 切面统一打印请求日志

    欢迎关注微信公众号: 小哈学Java 文章首发于个人网站 https://www.exception.site/springboot/spring-boot-aop-web-request 本节中,您 ...

  7. 状态维持在web层 每层都可以Cache

    API网关的开源解决方案那么多,为什么我们却还要选择自研? - SDK.CN - 中国领先的开发者服务平台 https://sdk.cn/news/8001 技术细节Microservice+SOA状 ...

  8. Web 层由 Web,Web-MVC,Web-Socket 和 Web-Portlet 组成

    Web 层由 Web,Web-MVC,Web-Socket 和 Web-Portlet 组成,它们的细节如下: Web 模块提供面向web的基本功能和面向web的应用上下文,比如多部分(multipa ...

  9. SpringBoot2.0 基础案例(11):配置AOP切面编程,解决日志记录业务

    本文源码 GitHub地址:知了一笑 https://github.com/cicadasmile/spring-boot-base 一.AOP切面编程 1.什么是AOP编程 在软件业,AOP为Asp ...

随机推荐

  1. Input is not proper UTF-8, indicate encoding !错误处理

    xml 中如果包含部分 ascii 控制字符(小数字)则 chrome会报告如下类型错我: This page contains the following errors: error on line ...

  2. 运维利器:钉钉机器人脚本告警(Linux Shell 篇)

    写在前面的话 目前换了几家公司,且最近几家都是以钉钉作为公司 OA 聊天工具,总的来说还是很不错的.最近去了新公司,由于公司以前没有运维,所以监控,做自动化等方面都没有实施,恰逢这个机会把最近做的关于 ...

  3. 算法训练 K好数 (DP)

    问题描述 如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数.求L位K进制数中K好数的数目.例如K = 4,L = 2的时候,所有K好数为11.13.20.22 ...

  4. Git 分支管理-git stash 和git stash pop

    https://blog.csdn.net/u010697394/article/details/56484492 合并分支,冲突是难免的,在实际协作开发中我们遇到的情况错综复杂,今天就讲两个比较重要 ...

  5. 洛谷P3726 [AH2017/HNOI2017]抛硬币(组合数+扩展Lucas)

    题面 传送门 题解 果然--扩展\(Lucas\)学了跟没学一样-- 我们先考虑\(a=b\)的情况,这种情况下每一个\(A\)胜的方案中\(A\)和\(B\)的所有位上一起取反一定是一个\(A\)败 ...

  6. Spark大数据处理 之 从WordCount看Spark大数据处理的核心机制(2)

    在上一篇文章中,我们讲了Spark大数据处理的可扩展性和负载均衡,今天要讲的是更为重点的容错处理,这涉及到Spark的应用场景和RDD的设计来源. Spark的应用场景 Spark主要针对两种场景: ...

  7. 牛客寒假算法基础集训营4 I Applese 的回文串

    链接:https://ac.nowcoder.com/acm/contest/330/I来源:牛客网 自从 Applese 学会了字符串之后,精通各种字符串算法,比如……判断一个字符串是不是回文串. ...

  8. pycharm、idea 2018软件安装教程

    Python3.7安装: https://www.jb51.net/article/146326.htm pycharm软件: https://www.jianshu.com/p/cf77d74bef ...

  9. js 弹性菜单

    <!doctype html> <html> <head> <meta http-equiv="Content-Type" content ...

  10. 本地访问Vmware虚机Web网站

    情况:公司是域环境,Vmware网络设置的是NAT连接模式,里外装的都是Windows,虚机网络IP地址是自动获取的. 查看: 1.虚机Ping本地的IP地址可以Ping通: 2.本地Ping虚机的I ...