`
zhangshixi
  • 浏览: 675572 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

方法日志记录器

阅读更多

    在实际项目开发中,我们常常需要实时监测一个方法的执行情况,如:方法执行开始、注入方法的参数列表、方法执行时间、方法结束等信息。将这些信息以日志形式进行记录,可以方便开发人员分析方法的执行情况,比如,可以自定义一个时间标准,将执行时间超过此标准时间的方法标记为慢速,以便能及时监测到执行时间过慢的方法,给检查和调试带来方便。

    下面为一个记录方法执行情况的日志记录器,使用Spring AOP的方式实现,并可定义方法执行过慢的时间标准,以便监测方法的执行情况。

package com.zhangsx.util.log;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aopalliance.intercept.MethodInvocation;
import org.aopalliance.intercept.MethodInterceptor;

/**
 * 记录方法执行情况的日志记录器。
 * 使用Spring AOP的方式,记录方法运行情况,
 * 包括方法开始、方法参数列表、方法执行时间、是否为执行慢速、方法结束等。
 * 可配置将方法定义为执行慢速的时间参数slowExecuteTime,单位为毫秒。
 * 
 * @author ZhangShixi
 */
public class OperationLog implements MethodInterceptor {

    // 方法为执行慢速的时间标准,默认为 1000 毫秒
    private long slowExecuteTime = 1000;
    // 日志级别静态常量
    private static final String LEVEL_INFO = "info";
    private static final String LEVEL_DEBUG = "debug";
    private static final String LEVEL_ERROR = "error";
    private static final String LEVEL_WARAN = "waran";
    // 日志记录器
    private static Log log = LogFactory.getLog(OperationLog.class);

    /**
     * 获取将方法标记为执行慢速的时间标准,如果方法执行时间超过此值,将被标记为执行慢速。
     * @return 执行慢速的时间标准
     */
    public long getSlowExecuteTime() {
        return slowExecuteTime;
    }

    /**
     * 设置将方法标记为执行慢速的时间标准,如果方法执行时间超过此值,将被标记为执行慢速。
     * 如果不配置此参数,将默认为 1000 毫秒。
     * @param slowExecuteTime 执行慢速的时间标准
     */
    public void setSlowExecuteTime(long slowExecuteTime) {
        this.slowExecuteTime = slowExecuteTime;
    }

    /**
     * 重写invoke(MethodInvocation invocation)方法,以便在日志中记录方法执行情况的信息。
     * @param invocation 目标对象信息
     * @return Object 方法返回值
     * @throws java.lang.Throwable 异常
     */
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {

        before(invocation);

        long startTime = System.currentTimeMillis();
        Object result = invocation.proceed();
        long endTime = System.currentTimeMillis();

        long executeTime = endTime - startTime;
        logExecuteTime(invocation, executeTime);

        after(invocation);

        return result;
    }

    /**
     * 在目标对象方法调用之前调用,以记录方法调用之前的情况。
     * @param invocation 目标对象信息
     */
    private void before(MethodInvocation invocation) {
        String methodName = invocation.getMethod().getName();

        StringBuilder builder = new StringBuilder();
        builder.append("Started ");
        builder.append(methodName);
        builder.append(" method!");
        recordLog(builder.toString(), LEVEL_DEBUG, null);

        Object[] args = invocation.getArguments();
        builder.delete(0, builder.length());
        builder.append(methodName);
        builder.append(" way into the parameters are different:");
        recordLog(builder.toString(), LEVEL_DEBUG, null);

        for (int count = 0; count < args.length; count++) {
            builder.delete(0, builder.length());
            builder.append("The ");
            builder.append(count);
            builder.append(" parameters for the ");
            builder.append(args[count] == null ? null : args[count].toString());
            recordLog(builder.toString(), LEVEL_DEBUG, null);
        }
    }

    /**
     * 在目标对象方法调用之后调用,以记录方法调用之后的情况。
     * @param invocation 目标对象信息
     */
    private void after(MethodInvocation invocation) {
        String methodName = invocation.getMethod().getName();
        recordLog(methodName + " the implementation of the end.", LEVEL_DEBUG,
                null);
    }

    /**
     * 记录方法执行时间。
     * 如果执行时间超过 getSlowExecuteTime() 的返回值,
     * 则将记录等级提升为 waran ,并标记为慢速执行。
     * @param invocation 目标对象信息
     * @param executeTime 方法执行时间
     */
    private void logExecuteTime(MethodInvocation invocation, long executeTime) {
        long slowTime = getSlowExecuteTime();
        StringBuilder builder = new StringBuilder();
        builder.append(invocation.getMethod().getName());
        if (executeTime > slowTime) {
            builder.append(" implementation of the method is much too slow,");
            builder.append(" the execute time for the implementation is ");
            builder.append(executeTime);
            builder.append(" ms.");
            recordLog(builder.toString(), LEVEL_WARAN, null);
        } else {
            builder.append(" execution time od the method is ");
            builder.append(executeTime);
            builder.append(" ms.");
            recordLog(builder.toString(), LEVEL_DEBUG, null);
        }
        builder = null;
    }

    /**
     * 记录日志信息。
     * @param message 日志信息
     * @param level 日志级别
     * @param throwable 如果日志级别是异常,此属性用来描述异常信息。
     */
    private void recordLog(String message, String level, Throwable throwable) {
        if (message != null && !message.isEmpty() &&
                level != null && !level.isEmpty()) {
            if (LEVEL_INFO.equals(level)) {
                if (log.isInfoEnabled()) {
                    log.info(message);
                }
            } else if (LEVEL_DEBUG.equals(level)) {
                if (log.isDebugEnabled()) {
                    log.debug(message);
                }
            } else if (LEVEL_ERROR.equals(level)) {
                if (log.isErrorEnabled()) {
                    log.error(message);
                }
            } else if (LEVEL_WARAN.equals(level)) {
                if (log.isWarnEnabled()) {
                    if (throwable == null) {
                        log.warn(message);
                    } else {
                        log.warn(message, throwable);
                    }
                }
            }
        }
    }
}

 

在使用时,只需在Spring的配置文件中,配置要记录的方法即可。

例如,记录所有Dao层的方法执行情况的配置:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

    <!-- 方法运行情况日志记录器 -->
    <bean id="log" class="com.zhangsx.util.log.OperationLog">
        <!-- 方法运行时间高于500毫秒定义为慢速 -->
        <property name="slowExecutionTime" value="500" />
    </bean>

    <!-- 记录DAO方法的执行 -->
    <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
        <property name="beanNames" value="*Dao" />
        <property name="interceptorNames">
            <list>
                <value>log</value>
            </list>
        </property>
    </bean>

</beans>
5
0
分享到:
评论

相关推荐

    日志记录器日志记录器日志记录器

    日志记录器日志记录器日志记录器日志记录器日志记录器

    日志记录器

    《日志记录器:ZHN.LogLib的深度解析与应用》 日志记录在软件开发中扮演着至关重要的角色,它能帮助开发者追踪程序运行状态,定位错误源,以及进行性能分析。ZHN.LogLib是一个优秀的、免费的日志记录库,它的出现为...

    使用python写的单例模式日志记录器(设计模式之单例模式)

    然后,我们将这个初始化的记录器赋值给 `SingletonLogger` 的 `write_log` 方法,这样每次调用 `write_log` 都会返回已配置好的日志记录器。 总结来说,这个Python实现的单例模式日志记录器结合了设计模式与日志...

    PHP实现工厂模式设计日志记录器

    由于工厂模式的使用,客户端代码无需关心具体日志记录器的实现细节,只需要调用工厂的`createLogger()`方法即可。这样,即使日志记录方式改变,客户端代码也不需要做任何修改。 `FileLogFactory`和`...

    Node.js-基于express的访问日志记录器

    Express访问日志记录器的主要目标是捕获并记录每个HTTP请求的关键信息,如请求方法(GET、POST等)、URL、响应状态码、响应时间、客户端IP地址、用户代理等。这些信息对于调试、性能优化以及安全分析都极其有用。 ...

    工厂方法设计模式

    本文将基于给定的实验内容,深入探讨工厂方法设计模式,并通过一个具体的案例——系统日志记录器的支持来说明如何应用这一模式。 #### 二、工厂方法设计模式概述 工厂方法模式的主要目标是解耦客户端和产品类之间...

    使用Java单例模式实现一个简单的日志记录器.txt

    本文介绍了一种使用Java单例模式实现简单日志记录器的方法。通过定义静态变量、私有构造函数以及线程安全的实例获取方法,实现了日志记录器的单例模式。此外,还提供了写入日志的方法,便于实际应用中的日志管理。...

    ping记录软件,有日志;断网记录器

    于是,断网记录器、具备ping记录功能的软件应运而生。 这种软件的核心功能是通过执行ping命令,实时检测网络连接的质量。Ping命令是基于Internet控制报文协议(ICMP)的一种网络诊断工具,它可以检测目标主机是否可...

    C# 面向切面编程--监控日志记录方案

    在代理方法中的在原有方法的前后新增日志记录,动态代理采用装饰器模式实现通常称为AOP,AOP方面的内容请参阅: https://msdn.microsoft.com/zh-cn/library/dn574804.aspx 。以上是对已经存在的类的方法进行日志记录...

    Go-golang简单的日志记录器。日志可输出到控制台文件或ElasticSearch。简单易于使用

    "Go-golang简单的日志记录器"是一个旨在简化日志管理的库,它提供了将日志输出到控制台、文件以及ElasticSearch的能力。这个库的设计理念是简洁易用,使得开发者可以快速集成并开始记录日志。 首先,让我们了解一下...

    Node.js-一个轻量级日志记录器底部带有状态栏滚动时不会消失

    标题中的“Node.js-一个轻量级日志记录器底部带有状态栏滚动时不会消失”表明我们正在讨论一个专门针对Node.js环境设计的日志记录工具,它具备独特的特性:在命令行界面中,其状态栏在用户滚动查看日志时会保持可见...

    设计模式—工厂方法模式

    2. `LoggerFactory.cs`:这是一个抽象工厂类,它定义了创建日志记录器(Logger)的接口,例如`CreateLogger()`方法。这个接口不具体实现创建逻辑,而是由它的子类去实现。 3. `DatabaseLoggerFactory.cs`和`...

    使用Java反射实现一个简单的日志记录器.txt

    此日志记录器能够根据不同级别(如INFO、ERROR)记录日志,并允许通过反射动态调用日志记录方法,从而提供了一种灵活的日志管理方式。 #### 二、核心概念 1. **反射机制**:Java的反射机制允许程序在运行时检查类...

    labview操作logger,日志记录

    在LabVIEW中,"logger"通常指的是日志记录功能,用于捕获和存储程序运行时的各种信息,如变量值、错误信息、事件触发等,这对于调试、优化和分析程序行为至关重要。 日志记录在LabVIEW中的实现可以通过自定义VI...

    LabVIEW日志记录实时更新模块.zip

    在这个"LabVIEW日志记录实时更新模块.zip"中,我们有两个关键的VI(虚拟仪器):main.vi和updateInfo.vi,它们是实现日志记录功能的核心部分。 1. **main.vi**:这是整个系统的主程序,通常它会负责协调和控制其他...

    _配电线路故障指示器日志记录

    故障指示器的日志记录对于维护电网的正常运行和故障排除具有非常重要的作用。从提供的文件内容中,我们可以提炼出以下几点关键知识点: 1. 故障指示器的日志信息类型 日志信息类型包括故障指示器上电、重启记录,...

    vc++ c++ mfc 日志 log 记录

    日志记录(log recording)是软件开发中的一个重要环节,它有助于调试、监控和故障排查。本篇文章将深入探讨如何在VC++、C++和MFC环境下实现日志功能。 1. **日志的基本概念** - 日志是记录程序运行过程中的事件、...

    小巧易于使用且可扩展的记录器可打印漂亮的日志

    本文将详细探讨一个名为"logger"的轻量级、易用且可扩展的日志记录器,特别关注其在JavaScript和Flutter开发环境中的应用。 首先,我们来理解"小巧"这个特性。在编程领域,"小巧"通常意味着该工具具有小体积、低...

Global site tag (gtag.js) - Google Analytics