此时情绪此时天,无事小神仙
好好生活,平平淡淡每一天

编辑

SpringMVC配置监听器:功能耗时&异常捕获输出日志

相关依赖jar包

web.xml 配置监听器 ServletContextListener

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- 配置监听器 -->
<listener>
  <listener-class>net.wwwyibu.ServletContextListener.LoadSystem</listener-class>
</listener>

ServletContextListener 配置 log4j 日志

public class LoadSystem implements ServletContextListener {

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {

    }

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        // 加载log4j日志:后面配置 log4j 文件的路径
        PropertyConfigurator.configure("D:/logfile/log4j.properties");

    }

}

log4j 日志文件代码

timeAround 和 功能耗时、异常捕获日志 切面类的 日志 一致

log4j.rootLogger=info,A1,R,E

log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH\:mm\:ss} [%c]-[%p] %m%n
log4j.logger.org.apache.commons=info
log4j.logger.org.apache.struts=info
log4j.logger.com.opensymphony.xwork2=info
log4j.logger.org.springframework=info
log4j.logger.org.hibernate.ps.PreparedStatementCache=info
log4j.logger.org.hibernate=info

# info级别日志
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=D:\\LogOut\\Project\\Project.log
log4j.appender.R.MaxFileSize=200MB
log4j.appender.R.MaxBackupIndex=10
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%-d{yyyy-MM-dd HH\:mm\:ss,SSS}[%p] [%l][%t]%n                   \u3010%m\u3011%n%n

# error级别日志
log4j.appender.E=org.apache.log4j.RollingFileAppender
log4j.appender.E.File=D:\\LogOut\\Project\\error.log
log4j.appender.E.Threshold= ERROR
log4j.appender.E.MaxFileSize=200MB
log4j.appender.E.MaxBackupIndex=50
log4j.appender.E.layout=org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern=%-d{yyyy-MM-dd HH\:mm\:ss,SSS}[%p] [%l][%t]%n                   \u3010%m\u3011%n%n

# 功能耗时、异常捕获日志
log4j.logger.timeAround=info,timeAround
log4j.appender.timeAround=org.apache.log4j.RollingFileAppender
log4j.appender.timeAround.File=D:\\LogOut\\Project\\timeAround.log
log4j.appender.timeAround.MaxFileSize=200MB
log4j.appender.timeAround.MaxBackupIndex=10
log4j.appender.timeAround.layout=org.apache.log4j.PatternLayout
log4j.appender.timeAround.layout.ConversionPattern=%-d{yyyy-MM-dd HH\:mm\:ss,SSS}[%p] [%l][%t]%n                   \u3010%m\u3011%n%n
log4j.additivity.timeAround=false  ——指定子 log4j.additivity.timeAround 的日志不会出现在 父类 project.log 中,默认是true

web.xml 配置扫描 applicationContext.xml

<!-- aop 配置功能耗时、异常捕获日志:指定切面类的路径-->
<bean id="baseAspect" class="net.wwwyibu.aop.BaseAspect"></bean>

<aop:config>
    <!-- baseAspect:关联 aop bean 的 配置id -->
    <aop:aspect id="concurrentOperationRetry" ref="baseAspect">
        <!-- controller.*.*(..):第一个*记录的是controller包下所有类,第二个*是所有类下的记录所有方法,(..)表示匹配所有的输入参数 -->
        <aop:pointcut id="idempotentOperation" expression="execution(* net.wwwyibu.controller.*.*(..))"/>
        <!-- net.wwwyibu.aop.BaseAspect 切面类里面的功能耗时方法 -->
        <aop:around pointcut-ref="idempotentOperation" method="doAround"/>
        <!-- net.wwwyibu.aop.BaseAspect 切面类里面的异常捕获捕获方法 -->
        <aop:after-throwing pointcut-ref="idempotentOperation" method="doThrowing" throwing="ex"/>
    </aop:aspect>
</aop:config>

监听器实现类代码

applicationContext.xml 配置 扫描 AOP 功能耗时和异常捕获 切面类 >> 在此切面类里面编写 功能耗时 和 异常捕获 日志代码

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

/**
 * @version 创建时间:2020年4月28日下午2:53:39
 * @Description: Spring AOP打印功能耗时日志和未捕获的异常信息
 */
public class BaseAspect {

    private static final Logger LOGGER=Logger.getLogger("timeAround");
    private static final Logger ERROR = Logger.getLogger(BaseAspect.class);
    // 初始化当前时间
    long current=0;

    /**
     * @Title:doBefore
     * @date:2020年4月28日 下午2:53:59
     * @Description: 方法执行前调用
     * @param jp--JoinPoint对象封装了SpringAop中切面方法的信息
     * void
     */
    public void doBefore(JoinPoint jp) {
//        Object[] o=jp.getArgs();
//        for(int i=0;i<o.length;i++){
//            System.err.println("输入参数为"+o[i]);
//        }
//        current=System.currentTimeMillis();
//        System.err.println("当前方法执行时间为: " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName());
    }

    /**
     * @Title:doAfter
     * @date:2020年4月28日 下午2:54:58
     * @Description: 方法执行后调用
     * @param jp--JoinPoint对象封装了SpringAop中切面方法的信息
     * void
     */
    public void doAfter(JoinPoint jp) {
//        System.err.println("方法结束时间为: " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName());
//        System.err.println("\r<br>执行耗时 : "+(System.currentTimeMillis()-current)+" 秒 ");
    }

    /**
     * @Title:doAround
     * @date:2020年4月28日 下午2:55:25
     * @Description: 把方法执行时间打印到timeAround日志中
     * @param pjp--ProceedingJoinPoint对象是JoinPoint的子接口,该对象只用在@Around的切面方法中
     * @return Object
     * @throws Throwable
     */
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        long time = System.currentTimeMillis();
        Object retVal = pjp.proceed();
        time = System.currentTimeMillis() - time;
        Object[] o=pjp.getArgs();
        for(int i=0;i<o.length;i++){
            LOGGER.info("第"+(i+1)+"输入参数 = "+o[i]);
        }
        LOGGER.info("当前方法为 " + pjp.getTarget().getClass().getName() + "." + pjp.getSignature().getName()+"  执行时间为"+time+"ms");
        return retVal;
    }

    /**
     * @Title:doThrowing
     * @date:2020年4月28日 下午2:56:14
     * @Description: 把没有try catch的异常打印到error日志中
     * @param jp--JoinPoint对象封装了SpringAop中切面方法的信息
     * @param ex--抛出异常类,序列化接口的实现类
     * void
     */
    public void doThrowing(JoinPoint jp, Throwable ex) {
        ERROR.error("method " + jp.getTarget().getClass().getName()
        + "." + jp.getSignature().getName() + " throw exception,没有try catch",ex);
    }
}
posted @ 2020-07-13 12:02  踏步  阅读(265)  评论(0编辑  收藏  举报