aop日志(记录方法调用日志)

一,使用aop记录方法调用日志

  1)使用注解与aop做方法调用日志,只需要把注解添加在要记录的方法上就可以,不会影响代码结构

  2)实现思路 数据库表建立>>配置需要环境>>自定义注解>>定义切点与操作(包含处理逻辑)>>添加注解

二,配置环境

  1)在原来的项目pom文件中添加以下aop需要的依赖

     <springframework>4.0.5.RELEASE</springframework>
        <aspectj>1.8.5</aspectj>

      
        <!-- Spring AOP -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${springframework}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${aspectj}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>${aspectj}</version>
        </dependency>    

  2)springmvc配置

   xmlns:aop="http://www.springframework.org/schema/aop"

  http://www.springframework.org/schema/aop
  http://www.springframework.org/schema/aop/spring-aop-4.0.xsd


<!-- 启动AspectJ支持   只对扫描过的bean有效 -->
    <aop:aspectj-autoproxy proxy-target-class="true" />

    <!-- 指定Sping组件扫描的基本包路径 -->
    <context:component-scan base-package="com.bjsxt.portl">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

三,自定义注解

  1)  

import java.lang.annotation.ElementType;
        import java.lang.annotation.Retention;
        import java.lang.annotation.RetentionPolicy;
        import java.lang.annotation.Target;
        /**
         * 日志记录
         * @author heyuan***
         * @date: 2017年11月22日 上午11:41:57
         */
        @Retention(RetentionPolicy.RUNTIME)
        @Target({ElementType.METHOD})
        public @interface Log {
            String name() default ""; //用于写方法作用
        }

四,定义切点与操作

  1)

@Aspect
@Component
public class SeriveLogAop
{

  @Resource
  private OperationLogMapper operationLogMapper;

  @Pointcut("@annotation(com.bjsxt.portal.annotation.SeriveLog)")
  public void SeriveLogAopqd()
  {
    System.out.println("---------->切点");
  }

  @After("SeriveLogAopqd()")
  public void Afters(JoinPoint joinPoint)
  {
    OperationLog operationLog = new OperationLog();
    User user = new User();
    StringBuffer arg = new StringBuffer();

    Object[] args = joinPoint.getArgs();
    for (int i = 0; i < args.length; ++i) {
      System.out.println("\t==>参数[" + i + "]:\t" + args[i].toString());
      arg.append(args[i].toString());
    }

    Signature signature = joinPoint.getSignature();
    String signa = signature.toString();

    MethodSignature ms = (MethodSignature)joinPoint.getSignature();
    Method method = ms.getMethod();

    String name = ((SeriveLog)method.getAnnotation(SeriveLog.class)).name();

    String name2 = method.getName();

    HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();

    user.setuUsername("无登录人");

    String host = request.getRemoteHost();

    String username = user.getuUsername();

    String time = Time.getTime();

    operationLog.setoIp(host);
    operationLog.setuUsername(username);
    operationLog.setoTime(time);
    operationLog.setoMethodname(name2);
    operationLog.setoExplain(name);
    operationLog.setoFullpath(signa);
    operationLog.setoParameter(arg.toString());

    this.operationLogMapper.addOperationLogs(operationLog);
  }
}

五,在需要记录的方法上添加@Log(name="方法描述")

六,常用知识

  

注解:

        @Before – 目标方法执行前执行  前置通知 JoinPoint joinPoint

        @After – 目标方法执行后执行      后置通知

        @AfterReturning – 目标方法返回后执行,如果发生异常不执行

        @AfterThrowing – 异常时执行      异常通知 

        @Around – 在执行上面其他操作的同时也执行这个方法  环绕通知 ProceedingJoinPoint pjp   执行方法:pjp.proceed(); 要返回pjp  
joinPoint:方法
    joinPoint.getKind() // method-execution
    joinPoint.getTarget().toString()// 获取连接点所在的目标对象; [email protected]
    joinPoint.getArgs() //获取连接点方法运行时的入参列表;
        System.out.println("Args:");
        for(int i=0;i<os.length;i++){
            System.out.println("\t==>参数["+i+"]:\t"+os[i].toString());
        }
    joinPoint.getSignature() //获取连接点的方法签名对象;String com.bjsxt.portal.service.impl.UserServiceImpl.getUser(User,HttpServletRequest,HttpSession)
    joinPoint.getSourceLocation() // org.springframework.aop[email protected]161b0ee2
    joinPoint.getStaticPart() //    execution(String com.xxx.portal.service.impl.UserServiceImpl.getUser(User,HttpServletRequest,HttpSession))    

    MethodSignature ms=(MethodSignature) joinPoint.getSignature();
        Method method=ms.getMethod();
        method.getAnnotation(Log.class).name();
        //method.getAnnotation(Log.class).name()  获取操作名(@log(name="内容"))
        method.getName(); //获取当前执行方法名
常用方法:
    HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
     request.getSession();
     request.getHost();//获取ip

     异常名称: e.getClass().toString()
网络参考资料
@Aspect
        @Component
        public class LogAop {

            ThreadLocal<Long> time=new ThreadLocal<Long>();
            ThreadLocal<String> tag=new ThreadLocal<String>();

            //切点
            @Pointcut("@annotation(com.bjsxt.portal.annotation.Log)")
            public void logqd() {
                System.out.println("---------->切点");
            }

            /**
             * 在所有标注@Log的地方切入
             * @param joinPoint
             * 前置通知
             */
            @Before("logqd()")
            public void beforeExec(JoinPoint joinPoint){

                time.set(System.currentTimeMillis());
                tag.set(UUID.randomUUID().toString());

                info(joinPoint);

                MethodSignature ms=(MethodSignature) joinPoint.getSignature();
                Method method=ms.getMethod();
                //method.getAnnotation(Log.class).name()  获取操作名(@log(name="内容"))
                System.out.println(method.getAnnotation(Log.class).name()+"标记"+tag.get());
            }
            /**
            *后置通知
            */
            @After("logqd()")
            public void afterExec(JoinPoint joinPoint){
                MethodSignature ms=(MethodSignature) joinPoint.getSignature();
                Method method=ms.getMethod();
                System.out.println("标记为"+tag.get()+"的方法"+method.getName()+"运行消耗"+(System.currentTimeMillis()-time.get())+"ms");
            }

            /**
            *环绕通知
            */
            @Around("logqd()")
            public Object aroundExec(ProceedingJoinPoint pjp) throws Throwable{
                System.out.println("前");
                Object proceed = pjp.proceed();
                System.out.println("后");
                return proceed;
            }

            private void info(JoinPoint joinPoint){
                System.out.println("--------------------------------------------------");
                System.out.println("King:\t"+joinPoint.getKind());
                System.out.println("Target:\t"+joinPoint.getTarget().toString());
                Object[] os=joinPoint.getArgs();
                System.out.println("Args:");
                for(int i=0;i<os.length;i++){
                    System.out.println("\t==>参数["+i+"]:\t"+os[i].toString());
                }
                System.out.println("Signature:\t"+joinPoint.getSignature());
                System.out.println("SourceLocation:\t"+joinPoint.getSourceLocation());
                System.out.println("StaticPart:\t"+joinPoint.getStaticPart());
                System.out.println("--------------------------------------------------");
            }

        }

                /**
             * 异常通知
             *@descript
             *@param point
             *@version 1.0
             */
            @AfterThrowing(pointcut = "controllerAspect()", throwing = "e")
            public  void doAfterThrowing(JoinPoint point, Throwable e) {
                LogFormMap logForm = new LogFormMap();
                 Map<String, Object> map = null;
                String user = null;
                String ip = null;
                try {
                    ip = SecurityUtils.getSubject().getSession().getHost();
                } catch (Exception ee) {
                    ip = "无法获取登录用户Ip";
                }
                try {
                    map=getControllerMethodDescription(point);
                    // 登录名
                    user = SecurityUtils.getSubject().getPrincipal().toString();
                    if (Common.isEmpty(user)) {
                        user = "无法获取登录用户信息!";
                    }
                } catch (Exception ee) {
                    user = "无法获取登录用户信息!";
                }

                logForm.put("accountName",user);
                logForm.put("module",map.get("module"));
                logForm.put("methods","<font color=\"red\">执行方法异常:-->"+map.get("methods")+"</font>");
                logForm.put("description","<font color=\"red\">执行方法异常:-->"+e+"</font>");
                logForm.put("actionTime","0");
                logForm.put("userIP",ip);
                try {
                    logMapper.addEntity(logForm);
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
时间: 2024-08-29 08:10:22

aop日志(记录方法调用日志)的相关文章

Atitit &#160;记录方法调用参数上下文arguments

Atitit  记录方法调用参数上下文arguments 1.1. java  java8  新的对象Parameter LocalVariableTable 本地变量表 MethodParameters 方法参数表1 1.2. Js arguments1 1.3. 1 1.4. C#1 2. Php的解决方案2 2.1. func_num_args() 返回传递给该函数参数的个数  2 2.2. func_get_arg(int $arg_num) 取得指定位置的参数值 2 2.3.  3.f

php项目中常用的log日志记录方法

/** * ****************** * 1.写入内容到文件,追加内容到文件 * 2.打开并读取文件内容 * ******************* */ function save_log($path, $msg) { if (! is_dir($path)) { mkdir($path); } $filename = $path . '/' . date('YmdHi') . '.txt'; $content = date("Y-m-d H:i:s")."\r

12.7 给计算增加日志记录

日志通常可以使用全局可变状态实现.然而,如果我们想要避免使用全局可变状态,并保持程序的纯函数性,那又该如何呢?我们有一个选择,就是把日志记录器的状态作为额外的参数值,传递我们要调用的每个函数.实现可能非常困难(想象一下,如果我们决定将另一个参数添加到这个状态中!). 要解决这个问题,我们可以创建自定义计算类型,启用了日志记录,把日志记录器的状态隐藏在计算类型内.这类似于在无任何副作用的纯函数式语言中, Haskell 使用的技术,嵌入处理状态(比如,文件系统).我们要实现的示例依赖于这样的事实,

asp.net5中使用NLog进行日志记录

asp.net5中提供了性能强大的日志框架,本身也提供了几种日志记录方法,比如记录到控制台或者事件中等,但是,对大部分程序员来说,更喜欢使用类似log4net或者Nlog这种日志记录方式,灵活而强大.asp.net5中也包括NLog的实现,下面把最简单的使用方法写出来,抛砖引玉,让更多对此不熟悉的同学们能借此入门. 1.在project.json中添加对Microsoft.Framework.Logging.NLog的引用,目前最新是beta8版本: 2.然后添加NLog.config配置文件到

Mysql日志记录慢查询的SQL

在日常开发当中,经常会遇到页面打开速度极慢的情况,通过排除,确定了,是数据库的影响,为了迅速查找具体的SQL,可以通过Mysql的日志记录方法. -- 打开sql执行记录功能 set global log_output='TABLE'; -- 输出到表 set global log=ON; -- 打开所有命令执行记录功能general_log, 所有语句: 成功和未成功的. set global log_slow_queries=ON; -- 打开慢查询sql记录slow_log, 执行成功的:

SLF4J - 一个允许你统一日志记录API的抽象层

一.什么是SLF4J 我们在做Java开发时,如果需要记录日志,有很多日志API可供选择,如: java.util.logging Apache log4j logback SLF4J又是个什么东东呢?为什么使用SLF4J比使用log4j或者java.util.logging更好呢?这是因为与所有提到的这些日志记录库相比,SLF4J没有真正地实现日志记录,相反它只是一个允许你使用任何处于后端的日志记录库的 抽象层 . 如果你正在编写内部或者外部使用的API或者应用库的话,那么你真的不需要让使用你

[转]asp.net5中使用NLog进行日志记录

本文转自:http://www.cnblogs.com/sguozeng/articles/4861303.html asp.net5中使用NLog进行日志记录 asp.net5中提供了性能强大的日志框架,本身也提供了几种日志记录方法,比如记录到控制台或者事件中等,但是,对大部分程序员来说,更喜欢使用类似log4net或者Nlog这种日志记录方式,灵活而强大.asp.net5中也包括NLog的实现,下面把最简单的使用方法写出来,抛砖引玉,让更多对此不熟悉的同学们能借此入门. 1.在project

Spring Boot 之日志记录

Spring Boot 之日志记录 Spring Boot 支持集成 Java 世界主流的日志库. 如果对于 Java 日志库不熟悉,可以参考:细说 Java 主流日志工具库 关键词: log4j, log4j2, logback, slf4j 日志格式 控制台输出 彩色打印 文件输出 日志级别 日志组 日志配置文件 Spring Boot 中的日志配置 源码 引申和引用 Spring Boot 内部日志全部使用 Commons Logging 记录,但保留底层日志实现.为 Java Util

ASP.NET Core 3中的自定义日志记录

根据我的经验,通常在API中记录请求和响应.这样做可以帮助开发人员调试问题并提供有价值的性能指标.在本教程中,我将介绍如何为ASP.NET Core 3 Web API创建基本的日志记录解决方案.在这篇文章的结尾,我们将有一个有效的日志记录解决方案,它将记录每个请求以及对控制台和文件系统的响应,并且日志将包括API处理每个请求所花费的时间.以下是概述: 1. 先决条件2. 创建RequestLog和ResponseLog模型3. 创建ILogForWebAPI4. 创建WebAPIConsole