实现Web层的日志切面(方便清晰查看日志)
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层的日志切面(方便清晰查看日志)的更多相关文章
- web部署启动或者运行报错查看日志寻找问题方法
今天运行一个项目,启动报错,查看日志,只看到了前半段错误日志,根据前半段错误日志差查找原因,找了两个小时,也没有解决掉,最后根据后半段错误日志十分钟定位错误,给解决了,以后出现问题不能急躁,查看完成的 ...
- 【docker】docker限制日志文件大小的方法+查看日志文件的方法
一.docker日志文件的方法 除了 docker logs -f 容器ID/容器名 这个方法以外. 在linux上,一般docker的日志文件存储在/var/lib/docker/container ...
- Web层后端权限模块
从零开始编写自己的C#框架(19)——Web层后端权限模块 不知不觉本系统写了快三个月了,最近写页面的具体功能时感觉到有点吃力,很多地方如果张嘴来讲的话可以说得很细,很全面,可写成文字的话,就不太 ...
- Django websocket之web端实时查看日志实践案例
这是Django Channels系列文章的第二篇,以web端实现tailf的案例讲解Channels的具体使用以及跟Celery的结合 通过上一篇<Django使用Channels实现WebS ...
- 从零开始编写自己的C#框架(16)——Web层后端父类
本章节讲述的各个类是后端系统的核心之一,涉及到系统安全验证.操作日志记录.页面与按键权限控制.后端页面功能封装等内容,希望学习本系列的朋友认真查看新增的类与函数,这对以后使用本框架进行开发时非常重要. ...
- Spring Boot 2.0 教程 | AOP 切面统一打印请求日志
欢迎关注微信公众号: 小哈学Java 文章首发于个人网站 https://www.exception.site/springboot/spring-boot-aop-web-request 本节中,您 ...
- 状态维持在web层 每层都可以Cache
API网关的开源解决方案那么多,为什么我们却还要选择自研? - SDK.CN - 中国领先的开发者服务平台 https://sdk.cn/news/8001 技术细节Microservice+SOA状 ...
- Web 层由 Web,Web-MVC,Web-Socket 和 Web-Portlet 组成
Web 层由 Web,Web-MVC,Web-Socket 和 Web-Portlet 组成,它们的细节如下: Web 模块提供面向web的基本功能和面向web的应用上下文,比如多部分(multipa ...
- SpringBoot2.0 基础案例(11):配置AOP切面编程,解决日志记录业务
本文源码 GitHub地址:知了一笑 https://github.com/cicadasmile/spring-boot-base 一.AOP切面编程 1.什么是AOP编程 在软件业,AOP为Asp ...
随机推荐
- 记一次成功部署kolla-ansible ocata版本过程
1.安装的docker版本 [root@controller ~]# docker --versionDocker version 17.09.1-ce, build 19e2cf6 2.安装的ans ...
- UISplitViewController
前言 大多数时候,iPhone.iPod 应用与 iPad 应用开发没有太大的区别,但是 iPad 的屏幕比 iPhone 大, 设计程序时可以充分利用 iPad 的大屏幕特点,例如 TabBar 和 ...
- MySQL之常用命令
前言 在说MySQL命令之前,需要介绍一些navicat:navicat是一套快速.可靠并且价格相宜的数据库管理工具,它的出现简化了数据库的管理,降低了管理成本,提高了对数据库的管理效率.Navica ...
- 5、OpenCV Python ROI和泛洪填充
__author__ = "WSX" import cv2 as cv import numpy as np #泛洪填充 从一个点开始 ,填充周围和他相似的点,直到遇到一个边界 # ...
- JDK源码 Integer.bitCount(i)
1.问题:输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 2.解决方法很多,JDK提供了一种,如下图 /** * Returns the number of one-bits in ...
- P3978 [TJOI2015]概率论
\(\color{#0066ff}{ 题目描述 }\) 为了提高智商,ZJY开始学习概率论.有一天,她想到了这样一个问题:对于一棵随机生成的n个结点的有根二叉树(所有互相不同构的形态等概率出现),它的 ...
- js常用代码收集
1. PC - js 返回指定范围的随机数(m-n之间)的公式 Math.random()*(n-m)+m return false return false // event.preventDefa ...
- github 第三方登录
第三方登录先了解 OAuth 2.0 OAuth 协议的认证和授权的过程如下: 用户打开我的博客后,我想要通过GitHub获取改用户的基本信息 在转跳到GitHub的授权页面后,用户同意我获取他的基本 ...
- windows_study_2
描述:如何确定像%ProgramFiles%这样格式的目录的具体位置? 解决:运行——cmd——echo %ProgramFiles%——回车——界面就显示出目录位置了.
- 毕业设计 python opencv实现车牌识别 界面
主要代码参考https://blog.csdn.net/wzh191920/article/details/79589506 GitHub:https://github.com/yinghualuow ...