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. ASP.NET MVC底层原理与框架

    前言 鄙人有一毛病,喜欢钻研原理性的东西,感觉只知道怎么用还不太够,更想知道如何实现的以及为什么会这样. 暑假的时候做积分系统是第一次接触MVC,感觉MVC就是一个框架,分为Module ,view和 ...

  2. 关于jquery.extend()的坑:我的数组变成相同元素了?

    首先呢我有一个数组,存放了多个json对象.这些json对象的属性有缺失,我设置了一个对象模板来存放默认值 先来看一段代码 var source = [ { name: 'dapianzi', bor ...

  3. 用Decorator控制Koa路由

    在Spring中Controller长这样 @Controller public class HelloController{ @RequestMapping("/hello") ...

  4. 【三支火把】--- 关于BIOS&UEFI查阅资料网站总结

    UEFI和BIOS的水太深,网上能找到的资料是那么的少,各个组织之间互有交叉,难弄的很,总结了下常用的BIOS资料网站,仅供参考,如果遗漏之处,请指出,博主将继续完善补充……

  5. Django 13 admin和auth系统、权限问题

    一.auth系统 auth系统的数据表 #User:User是auth模块中维护用户信息的关系模式(继承了models.Model), 数据库中该表被命名为auth_user. #Group:User ...

  6. Github常见命令整理

    常见命令: 将文件增加到index/stage暂存区: git add filename 将暂存的文件更新到本地库中:git commit -m "备注内容" 将本地库更新到远程库 ...

  7. Number Sequence (KMP第一次出现位置)

    Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b[2], ...... , b[M] (1 <= M ...

  8. Codeforces Round #529 (Div. 3) C. Powers Of Two

    http://codeforces.com/contest/1095/problem/C 题意:给n找出k个2的幂,加起来正好等于n.例如 9,4:9 = 1 + 2 + 2 + 4 思路:首先任何数 ...

  9. C#工具类之Xml序列化扩展类

    using System; using System.IO; using System.Linq; using System.Runtime.Serialization; using System.T ...

  10. Django ORM 最后操作

    F查询:代表2个字段之间的比较 from django.db.models import F models.Book.objects.filter(price__gt=F('keep_price')) ...