7

我已经通过 perf4J 站点的以下链接进行了相同的操作:http: //perf4j.codehaus.org/devguide.html#Using_Spring_AOP_to_Integrate_Timing_Aspects

在我的 spring.xml 中添加了以下内容。

<aop:aspectj-autoproxy/>
<bean id="timingAspect" class="org.perf4j.log4j.aop.TimingAspect"/>
<bean id="wscClientBase" class="com.xyz.csa.core.common.WscClientBase"/>

在 WscClientBase 类中,我有以下带有@Profiled注释的方法。

@Profiled(tag = "SOAPCALLTEST")
public Object sendMessage(Object message) {
    String msg = message.toString();
    if (msg.indexOf(' ') > 1) {
        msg = msg.substring(1, msg.indexOf(' '));
    }
    try {
        Object ret = marshalSendAndReceive(message);
        return ret;
    } catch (RuntimeException ex) {
        throw ex;
    }
}

我没有在应用程序日志中看到 perf4j TimingLogger 语句。但是,如果我像下面这样突兀地使用它(没有注释),我会成功看到日志语句。

public Object sendMessage(Object message) {
    String msg = message.toString();
    if (msg.indexOf(' ') > 1) {
        msg = msg.substring(1, msg.indexOf(' '));
    }
    StopWatch stopWatch = new Slf4JStopWatch();
    try {
        Object ret = marshalSendAndReceive(message);
        stopWatch.stop("PERF_SUCCESS_TAG", msg);
        return ret;
    } catch (RuntimeException ex) {
        stopWatch.stop("PERF_FAILURE_TAG", msg);
        throw ex;
    }
}

我错过了什么吗?

4

6 回答 6

9

Perf4j

这是一个应用程序的性能分析和检查插件。它可以使用spring AOP与spring集成。它创建一个日志文件,提供给解析器以分析和生成相关信息。它可以默认提供平均,平均,标准偏差。有关更多一般信息,请查看http://perf4j.codehaus.org/index.html

如何设置 Perf4j。对于正常设置,您只需要添加 perf4j jar 并为要监视的每个代码片段创建 StopWatch 实例。

StopWatch stopWatch= new StopWatch(“snipletTagName”)
…
//{your code sniplet}
…
stopwatch.stop();

这将创建 perf4j 监视器,您将在控制台上获得日志信息。

本文档的主要目的是通过设置了解将 perf4j 与 spring 集成。

1.添加以下所有Jar文件。

   1.perf4j-0.9.16-slf4jonly.jar
   2.aspectjweaver-1.6.12.jar
   3.aopalliance-1.0.jar
   4.commons-logging-1.1.1.jar
   5.logback-classic-1.0.7.jar
   6.logback-core-1.0.7.jar
   7.slf4j-api-1.7.1.jar
   8.perf4j-0.9.16.jar
   9.aspectjrt-1.6.1.jar
   10.commons-jexl-1.1.jar
   11.asm-1.5.3.jar
   12.cglib-2.1_3.jar

确保在你的类路径中拥有所有这些 jar 以及 spring 库。

2.创建你自己的 logback.xml 将被 perf4j 隐式使用 logback.xml 的内容将是

<configuration>
    <appender name="perf4jFileAppender"
        class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>logs/perf4j.log</File>
        <encoder>
            <Pattern>%date %-5level [%thread] %logger{36} [%file:%line] %msg%n
            </Pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>logs/perf4j.%d{yyyy-MM-dd}.log</FileNamePattern>
        </rollingPolicy>
    </appender>

    <appender name="CoalescingStatistics"
        class="org.perf4j.logback.AsyncCoalescingStatisticsAppender">
        <param name="TimeSlice" value="1" />        
        <appender-ref ref="perf4jFileAppender" />       
    </appender>

    <appender name="RootConsoleAppender" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>debug</level>
        </filter>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%date %-5level [%thread] %logger{36} [%file:%line] %msg%n
            </pattern>
        </layout>
    </appender>

    <!-- Loggers -->
    <!-- The Perf4J logger. Note that org.perf4j.TimingLogger is the value of 
        the org.perf4j.StopWatch.DEFAULT_LOGGER_NAME constant. Also, note that additivity 
        is set to false, which is usually what is desired - this means that timing 
        statements will only be sent to this logger and NOT to upstream loggers. -->
    <logger name="org.perf4j.TimingLogger" additivity="false">
        <level value="DEBUG" />
        <appender-ref ref="CoalescingStatistics" />
        <appender-ref ref="perf4jFileAppender" />
        <appender-ref ref="RootConsoleAppender" />
    </logger>
</configuration>

3.在你的spring配置文件中,你需要添加aspectj标签来启用perf4j的@Profiled注解。

(注意:@Profiled注解是什么?:你将把这个标签添加到所有从spring实例调用的类中的所有方法中,或者使用依赖注入。对象基本上应该是spring上下文注册的,方法应该被调用在 Spring 上下文中注册的对象。我浪费了一天时间思考为什么我的方法没有被记录,然后我意识到我测试的对象不是 Spring 上下文的一部分。

好的,您需要添加到 spring 配置 xml 的代码是

<!-- this is my spring-context.xml -->
<beans>

    <aop:aspectj-autoproxy>
        <aop:include name="timingAspect" />
    </aop:aspectj-autoproxy>

    <bean id="timingAspect" class="org.perf4j.slf4j.aop.TimingAspect" />

<!-- this is the class that will be registered with the spring and now we can get this class and call the method that we need to monitor-->
    <bean class="com.perf4jexample.Test" />


</beans>

4.创建将实现@Profiled 注解的Test 类。

public class Test {

    private String testVal;

    public Test() {
        // TODO Auto-generated constructor stub
    }

    @Profiled
    public void testing() {
        System.out.println("testt" );
    }

    public String getTestVal() {
        return testVal;
    }

    public void setTestVal(String testVal) {
        this.testVal = testVal;
    }
}

5.Ok 现在你已经设置好了所有东西,剩下的就是测试类,它将启动 spring 上下文并加载 perf4j。

public class Test(){

public static void main(){
        AbstractApplicationContext context = new ClassPathXmlApplicationContext(
                "spring-context.xml");

        context.start();

        Test bean = context.getBean(Test.class);
        bean.testing();
}

我希望通过遵循这些设置,您应该能够使用 perf4j 控制台附加程序在控制台上显示一行。

日志上的 Perf4j 监控命令:

在您的记录器路径上执行生成性能统计信息

java -jar perf4j-0.9.16.jar myLogger.log

用于生成图

java -jar perf4j-0.9.16.jar --graph perfGraphs.out myLogger.log

我希望本教程可以帮助您将 Spring、perf4j、logback 与 Profiled 注解集成。

于 2012-09-19T11:57:19.253 回答
2

尝试aop:include name="timingAspect"/><aop:aspectj-autoproxy/>.

您是否还可以确认您正在对从 spring 应用程序上下文检索的对象调用 sendMessage(使用 getBean 或作为依赖项注入)。

于 2011-03-24T07:51:55.120 回答
1

在这里,我有两种方法可以使 perf4j @Profiled在 spring boot 项目上工作。前提是在依赖项下添加

"org.aspectj:aspectjweaver",
"org.perf4j:perf4j:0.9.16",
"commons-jexl:commons-jexl:1.1",
"cglib:cglib:3.2.1",

对于普通的 spring 项目,可能需要添加更多的依赖项,例如 spring-aop、aopalliance ......这些看起来包含在 spring-boot-starter-parent

1.Java配置

这是最简单的方法,而且大部分都有效,但我发现不知何故不能使用 spring-data JpaRepository 方法。它只提供org.perf4j.log4j.aop.TimingAspect bean 并执行 aspectj 自动代理。与上面其他人提供的xml配置相同

@Configuration
@EnableAspectJAutoProxy
public class PerformanceConfig {
    @Bean
    public TimingAspect timingAspect() {
        return new TimingAspect();
    }
}

2.提供你自己的方面

这样, @ Profiled注解的 spring-data 存储库接口方法也可以正常工作。但是这样做的缺点是忽略了@Profiled(tag='some tag')中给出的标签,并使用 joinPoint 方法名称作为标签。

@Aspect
@Component
public class PerformanceTracker {

    @Around(value="execution(@org.perf4j.aop.Profiled * com.mypackage..*(..))")
    public Object checkPerformance(ProceedingJoinPoint pjp) throws Throwable {
        StopWatch stopWatch = new Log4JStopWatch(pjp.getSignature().toShortString());
        Object result = pjp.proceed();
        stopWatch.stop();
        return result;
    }
}
于 2016-04-08T05:28:19.460 回答
0

它不能工作的原因是被分析的方法在 Spring-bean 的父类中。我可以通过查看您的 bean 名称来判断:WscClientBase。我假设这是你有许多子类的基类。

经过一段时间的研究,我在 Spring 文档中发现了关于 @Transactional 和 @Cacheable 的非常重要的注释。

在这两种情况下,他们都会这样说:

“使用代理时,您应该只将 <> 注释应用于具有公共可见性的方法。如果您使用这些注释对受保护的、私有的或包可见的方法进行注释,则不会引发错误,但带注释的方法不会显示配置的缓存设置。如果您需要在更改字节码本身时注释非公共方法,请考虑使用 AspectJ(见下文)。”</p>

而下面……</p>

“Spring 建议您只使用 @Cache* 注释来注释具体类(和具体类的方法),而不是注释接口。您当然可以将 @Cache* 注释放在接口(或接口方法)上,但这仅在您使用基于接口的代理时才起作用。Java 注释不是从接口继承的事实意味着,如果您使用基于类的代理 (proxy-target-class="true") 或基于编织的方面 (mode="aspectj"),那么缓存设置为代理和编织基础设施无法识别,并且对象不会被包装在缓存代理中,这绝对是糟糕的。”</p>

我假设@Profiled 使用类似的编织机制,因此您不能将@Profiled 放在父类中的任何方法上。事实上,我在我的应用程序中遇到了类似的问题:我在父类中有 @Profiled 和 @Cacheable,但这些都不起作用:我在 Perf4J 日志中没有看到任何记录,并且缓存没有更新。当我将@Profiled 移动到子类的方法中时,我开始在 perf4j.log 中看到记录。

于 2014-11-14T18:36:16.423 回答
0

把配置放在你的“ servlet-context-config.xml ”下面。玩得开心!

    <aop:aspectj-autoproxy/>
    <bean id="timingAspect" class="org.perf4j.log4j.aop.TimingAspect"/>
    <bean id="wscClientBase" class="com.xyz.csa.core.common.WscClientBase"/>
于 2016-08-09T08:05:51.600 回答
0

对于遇到此类问题的人,他们可以检查 Spring 日志(级别信息)中是否存在类似“不符合所有 BeanPostProcessors 处理的条件(例如:不符合自动代理条件)”的消息。

于 2016-12-05T08:57:32.170 回答