Commit ba8224f7 by huluobin

log方案修改

parent 678300dd
...@@ -60,17 +60,24 @@ ...@@ -60,17 +60,24 @@
<version>3.3.0</version> <version>3.3.0</version>
</dependency> </dependency>
<!--数据库连接组件-->
<dependency> <dependency>
<groupId>mysql</groupId> <groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-java</artifactId>
</dependency> </dependency>
<!--工具包-->
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId> <artifactId>commons-pool2</artifactId>
<version>2.6.2</version> <version>2.6.2</version>
</dependency> </dependency>
<!--spring aspect 切面-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--springboot自动配置--> <!--springboot自动配置-->
<dependency> <dependency>
......
package com.gogirl.infrastructure.interceptor;
import com.gogirl.infrastructure.common.util.JsonUtilByFsJson;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
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.LinkedHashMap;
import java.util.Map;
/**
* @Description:日志切面
* @Author:Kevin
* @Date:2018-12-07 15:09
*/
//@Profile({"dev", "test"})
@Component
@Aspect
public class LogAspect {
private final Logger logger = LoggerFactory.getLogger(LogAspect.class);
/**
* 定义一个公共的方法,实现切入点
* 拦截Controller下面的所有方法 任何参数(..表示拦截任何参数)
* 以@RestController注解作为切入点 可切入其他业务模块的方法
*
* @within和@target针对类的注解,
* @annotation是针对方法的注解,为自定义注解
*/
// @Pointcut("execution(public * com.*.web..*.*(..))")
@Pointcut("@within(org.springframework.web.bind.annotation.RestController)")
public void point() {
}
/**
* 拦截方法之前的一段业务逻辑
*
* @param joinPoint
*/
@Before("point()")
public void doBefore(JoinPoint joinPoint) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
Map<String, Object> params = new LinkedHashMap<>(10);
params.put("uri", request.getRequestURI()); // 获取请求的url
//params.put( "method", request.getMethod() ); // 获取请求的方式
params.put("args", joinPoint.getArgs()); // 请求参数
//params.put( "className", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName() ); // 获取类名和获取类方法
params.put("ip", getClientIp(request)); // 获取请求的ip地址
// 输出格式化后的json字符串
//logger.info( "params:{}", JSON.toJSONString( params ) );
//logger.info( "params:{}", JSON.toJSONString( params.get( "args" ) ) );
logger.info("params:{}", JsonUtilByFsJson.beanToJson(params));
}
/**
* 获取响应返回值 方法执行return之后
*/
@AfterReturning(returning = "object", pointcut = "point()")
public void doAfterReturning(Object object) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 会打印出一个对象,想打印出具体内容需要在定义模型处加上toString()
//logger.info( "result:{}", object.toString() );
logger.info("result:{}", JsonUtilByFsJson.beanToJson(object));
;
}
/**
* 环绕通知 在方法的调用前、后执行
*/
@Around("point()")
public Object doAround(ProceedingJoinPoint point) throws Throwable {
//开始时间
long begin = System.currentTimeMillis();
//方法环绕proceed结果
Object obj = point.proceed();
//结束时间
long end = System.currentTimeMillis();
//时间差
long timeDiff = (end - begin);
String msg = "方法性能分析: 执行耗时 {}毫秒,来自Dream PWJ的表情";
if (timeDiff < 200) {
logger.info("方法性能分析: 执行耗时 {}毫秒," + "\uD83D\uDE02", timeDiff);
} else {
logger.warn("方法性能分析: 执行耗时 {}毫秒," + "\uD83D\uDE31", timeDiff);
}
return obj;
}
/**
* 拦截方法之后的一段业务逻辑
*/
@After("point()")
public void doAfter() {
// logger.info( "doAfter" );
}
public String getClientIp(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
logger.debug("x-forwarded-for = {}", ip);
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
logger.debug("Proxy-Client-IP = {}", ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
logger.debug("WL-Proxy-Client-IP = {}", ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
logger.debug("RemoteAddr-IP = {}", ip);
}
if (StringUtils.isNotBlank(ip)) {
ip = ip.split(",")[0];
}
return ip;
}
}
package com.gogirl.infrastructure.interceptor; //package com.gogirl.infrastructure.interceptor;
//
import lombok.AllArgsConstructor; //import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import org.springframework.core.NamedThreadLocal; //import org.springframework.core.NamedThreadLocal;
import org.springframework.stereotype.Component; //import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod; //import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor; //import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; //import org.springframework.web.servlet.ModelAndView;
//
import javax.servlet.http.HttpServletRequest; //import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; //import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter; //import java.io.PrintWriter;
import java.io.StringWriter; //import java.io.StringWriter;
import java.text.SimpleDateFormat; //import java.text.SimpleDateFormat;
import java.util.Arrays; //import java.util.Arrays;
import java.util.Map; //import java.util.Map;
//
/** ///**
* 统一日志拦截记录 // * 统一日志拦截记录
*/ // */
@Component //@Component
@AllArgsConstructor //@AllArgsConstructor
@Slf4j //@Slf4j
public class LogHandlerInterceptor implements HandlerInterceptor { //public class LogHandlerInterceptor implements HandlerInterceptor {
//
private static final ThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<>("ThreadLocal StartTime"); // private static final ThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<>("ThreadLocal StartTime");
//
/** // /**
* 将ErrorStack转化为String. // * 将ErrorStack转化为String.
*/ // */
public static String getStackTraceAsString(Throwable e) { // public static String getStackTraceAsString(Throwable e) {
if (e == null) { // if (e == null) {
return ""; // return "";
} // }
StringWriter stringWriter = new StringWriter(); // StringWriter stringWriter = new StringWriter();
e.printStackTrace(new PrintWriter(stringWriter)); // e.printStackTrace(new PrintWriter(stringWriter));
return stringWriter.toString(); // return stringWriter.toString();
} // }
//
private String getParamString(Map<String, String[]> map) { // private String getParamString(Map<String, String[]> map) {
StringBuilder sb = new StringBuilder(); // StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String[]> e : map.entrySet()) { // for (Map.Entry<String, String[]> e : map.entrySet()) {
sb.append(e.getKey()).append("="); // sb.append(e.getKey()).append("=");
String[] value = e.getValue(); // String[] value = e.getValue();
if (value != null && value.length == 1) { // if (value != null && value.length == 1) {
sb.append(value[0]).append("\t"); // sb.append(value[0]).append("\t");
} else { // } else {
sb.append(Arrays.toString(value)).append("\t"); // sb.append(Arrays.toString(value)).append("\t");
} // }
} // }
return sb.toString(); // return sb.toString();
} // }
//
/** // /**
* 该方法将在请求处理之前进行调用。 // * 该方法将在请求处理之前进行调用。
* 多个Interceptor,然后SpringMVC会根据声明的前后顺序一个接一个的执行,而且所有的Interceptor中的preHandle方法都会在 // * 多个Interceptor,然后SpringMVC会根据声明的前后顺序一个接一个的执行,而且所有的Interceptor中的preHandle方法都会在
* Controller方法调用之前调用。SpringMVC的这种Interceptor链式结构也是可以进行中断的,这种中断方式是令preHandle的返 // * Controller方法调用之前调用。SpringMVC的这种Interceptor链式结构也是可以进行中断的,这种中断方式是令preHandle的返
* 回值为false,当preHandle的返回值为false的时候整个请求就结束了。 // * 回值为false,当preHandle的返回值为false的时候整个请求就结束了。
* // *
* @param request // * @param request
* @param response // * @param response
* @param handler // * @param handler
* @return // * @return
* @throws Exception // * @throws Exception
*/ // */
@Override // @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { // public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
long startTime = System.currentTimeMillis(); // long startTime = System.currentTimeMillis();
request.setAttribute("startTime", startTime); // request.setAttribute("startTime", startTime);
startTimeThreadLocal.set(startTime); //线程绑定变量(该数据只有当前请求的线程可见) // startTimeThreadLocal.set(startTime); //线程绑定变量(该数据只有当前请求的线程可见)
if (handler instanceof HandlerMethod) { // if (handler instanceof HandlerMethod) {
StringBuilder sb = new StringBuilder(1000); // StringBuilder sb = new StringBuilder(1000);
sb.append("-----------------------开始计时:").append(new SimpleDateFormat("hh:mm:ss.SSS").format(startTime)).append("-------------------------------------\n"); // sb.append("-----------------------开始计时:").append(new SimpleDateFormat("hh:mm:ss.SSS").format(startTime)).append("-------------------------------------\n");
HandlerMethod h = (HandlerMethod) handler; // HandlerMethod h = (HandlerMethod) handler;
sb.append("Controller: ").append(h.getBean().getClass().getName()).append("\n"); // sb.append("Controller: ").append(h.getBean().getClass().getName()).append("\n");
sb.append("Method : ").append(h.getMethod().getName()).append("\n"); // sb.append("Method : ").append(h.getMethod().getName()).append("\n");
sb.append("Params : ").append(getParamString(request.getParameterMap())).append("\n"); // sb.append("Params : ").append(getParamString(request.getParameterMap())).append("\n");
sb.append("URI : ").append(request.getRequestURI()).append("\n"); // sb.append("URI : ").append(request.getRequestURI()).append("\n");
log.info(sb.toString()); // log.info(sb.toString());
} // }
//
return true; // return true;
} // }
//
//
/** // /**
* 在当前请求进行处理之后,也就是Controller 方法调用之后执行, // * 在当前请求进行处理之后,也就是Controller 方法调用之后执行,
* 但是它会在DispatcherServlet 进行视图返回渲染之前被调用, // * 但是它会在DispatcherServlet 进行视图返回渲染之前被调用,
* 所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。 // * 所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。
* // *
* @param request // * @param request
* @param response // * @param response
* @param handler // * @param handler
* @param modelAndView // * @param modelAndView
* @throws Exception // * @throws Exception
*/ // */
@Override // @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
long startTime = (Long) request.getAttribute("startTime"); // long startTime = (Long) request.getAttribute("startTime");
long endTime = System.currentTimeMillis(); // long endTime = System.currentTimeMillis();
long executeTime = endTime - startTime; // long executeTime = endTime - startTime;
if (handler instanceof HandlerMethod) { // if (handler instanceof HandlerMethod) {
StringBuilder sb = new StringBuilder(1000); // StringBuilder sb = new StringBuilder(1000);
sb.append("CostTime : ").append(executeTime).append("ms").append("\n"); // sb.append("CostTime : ").append(executeTime).append("ms").append("\n");
sb.append("-------------------------------------------------------------------------------"); // sb.append("-------------------------------------------------------------------------------");
log.info(sb.toString()); // log.info(sb.toString());
} // }
} // }
//
//
/** // /**
* 该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。 // * 该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。
* // *
* @param request // * @param request
* @param response // * @param response
* @param handler // * @param handler
* @param ex // * @param ex
* @throws Exception // * @throws Exception
*/ // */
@Override // @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 打印JVM信息。 // // 打印JVM信息。
if (log.isDebugEnabled()) { // if (log.isDebugEnabled()) {
long beginTime = startTimeThreadLocal.get();//得到线程绑定的局部变量(开始时间) // long beginTime = startTimeThreadLocal.get();//得到线程绑定的局部变量(开始时间)
long endTime = System.currentTimeMillis(); //2、结束时间 // long endTime = System.currentTimeMillis(); //2、结束时间
//
//如果controller报错,则记录异常错误 // //如果controller报错,则记录异常错误
if (ex != null) { // if (ex != null) {
log.debug("Controller异常: " + getStackTraceAsString(ex)); // log.debug("Controller异常: " + getStackTraceAsString(ex));
} // }
//
log.debug("计时结束:" + new SimpleDateFormat("hh:mm:ss.SSS").format(endTime) + " 耗时:" + (endTime - beginTime) + " URI:" + // log.debug("计时结束:" + new SimpleDateFormat("hh:mm:ss.SSS").format(endTime) + " 耗时:" + (endTime - beginTime) + " URI:" +
request.getRequestURI() + " 最大内存: " + Runtime.getRuntime().maxMemory() / 1024 / 1024 + "m 已分配内存: " + Runtime.getRuntime().totalMemory() / 1024 / 1024 + "m 已分配内存中的剩余空间: " + Runtime.getRuntime().freeMemory() / 1024 / 1024 + "m 最大可用内存: " + // request.getRequestURI() + " 最大内存: " + Runtime.getRuntime().maxMemory() / 1024 / 1024 + "m 已分配内存: " + Runtime.getRuntime().totalMemory() / 1024 / 1024 + "m 已分配内存中的剩余空间: " + Runtime.getRuntime().freeMemory() / 1024 / 1024 + "m 最大可用内存: " +
(Runtime.getRuntime().maxMemory() - Runtime.getRuntime().totalMemory() + Runtime.getRuntime().freeMemory()) / 1024 / 1024 + "m"); // (Runtime.getRuntime().maxMemory() - Runtime.getRuntime().totalMemory() + Runtime.getRuntime().freeMemory()) / 1024 / 1024 + "m");
startTimeThreadLocal.remove(); // startTimeThreadLocal.remove();
} // }
} // }
} //}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment