perf4j @Профилированная аннотация не работает - PullRequest
7 голосов
/ 24 марта 2011

Я прошел по приведенной ниже ссылке с сайта 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;
    }
}

Я что-то упустил?

Ответы [ 6 ]

9 голосов
/ 19 сентября 2012

Perf4j Это плагин для анализа производительности и проверки приложения.Он может быть интегрирован с пружиной с помощью пружины АОП.Он создает файл журнала, который передается анализатору для анализа и выдачи соответствующей информации.Это может обеспечить среднее, среднее, стандартное отклонение по умолчанию.Для получения более общей информации, пожалуйста, проверьте http://perf4j.codehaus.org/index.html

Как настроить Perf4j.Для нормальной настройки вам просто нужно добавить perf4j jar и создать экземпляр StopWatch для каждого снипплета кода, который вы хотите отслеживать.

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

Это создаст монитор perf4j и вы получите информацию о журнале на консоли.

Основная цель этой документации состоит в том, чтобы настроить настройку интеграции perf4j с пружиной.

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

Убедитесь, что у вас есть все этокувшин в вашем классе путь вместе с весенней библиотекой.2. создайте свой собственный logback.xml, который неявно будет использоваться perf4j. Содержимое файла logback.xml будет

<configuration>

    <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>

    <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>

    <!-- 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 ?: вы добавите этот тег ко всем

методам во всех классах, вызываемых изэкземпляр экземпляра Spring или использование зависимости. Объект в основном должен быть зарегистрирован в контексте Spring, а метод должен вызываться объектом, зарегистрированным в контексте Spring. Я потратил один день, думая, почему мой метод не был зарегистрирован, тогда я понял, что объект, который я тестировалне был частью весеннего контекста. **

OK the code that you need to add to spring configuration xml is.

<!-- 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.Создайте класс Test, который будет реализовывать аннотацию @Profiled.

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. Хорошо, теперь у вас есть настройкавсе, что остается, - это тестовый класс, который запускает контекст 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.

2 голосов
/ 24 марта 2011

Попробуйте добавить <<code>aop:include name="timingAspect"/> внутри <aop:aspectj-autoproxy/>.

Можете ли вы также подтвердить, что вы вызываете sendMessage для объекта, который извлекается из контекста весеннего приложения (используя getBean или внедряется как зависимость).

1 голос
/ 08 апреля 2016

Здесь у меня есть два способа заставить perf4j @ Profiled работать над проектом весенней загрузки. Условием является добавление ниже зависимостей

"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 также работают нормально. Но недостатком этого является игнорирование тега, указанного в @ 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;
    }
}
0 голосов
/ 05 декабря 2016

Для людей, у которых есть этот тип проблемы, они могут проверить, что нет в весенних журналах (информация об уровне), такие сообщения "не могут обрабатываться всеми BeanPostProcessors (например, не имеют права на авто-проксирование)».

0 голосов
/ 09 августа 2016

Поместите конфигурацию ниже в ваш " 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"/>
0 голосов
/ 14 ноября 2014

Причина, по которой он не может работать, заключается в том, что профилируемый метод находится в родительском классе Spring-bean-компонента.Я могу сказать это, посмотрев на ваше имя компонента: WscClientBase.Я предполагаю, что это базовый класс, из которого у вас есть много дочерних классов.

После некоторого времени исследования я нашел очень важную заметку в документации Spring о @Transactional и @Cacheable.

В обоих случаях они говорят что-то вроде этого:

«При использовании прокси вы должны применять аннотации <> только к методам с публичной видимостью.Если вы аннотируете защищенные, частные или видимые пакетами методы с этими аннотациями, ошибка не возникает, но аннотированный метод не отображает настроенные параметры кэширования.Рассмотрите возможность использования AspectJ (см. Ниже), если вам нужно аннотировать непубличные методы, так как он изменяет сам байт-код ».

И ниже…

« Spring рекомендуетчто вы аннотируете только конкретные классы (и методы конкретных классов) с помощью аннотации @ Cache * , в отличие от аннотирования интерфейсов.Вы, конечно, можете разместить аннотацию @ Cache * на интерфейсе (или методе интерфейса), но это работает только так, как вы ожидаете, если вы используете прокси на основе интерфейса.Тот факт, что аннотации Java не наследуются от интерфейсов, означает, что если вы используете прокси на основе классов (proxy-target-class = "true") или аспект на основе ткачества (mode = "aspectj"), то параметры кэшированияне распознается инфраструктурой прокси и ткачества, и объект не будет помещен в кеширующий прокси, что было бы явно плохо ».

Я предполагаю, что @Profiled использует подобный механизм ткачества, поэтому вы можете 'положить @Profiled на любой метод в родительских классах.На самом деле у меня была похожая проблема в моем приложении: у меня были @Profiled и @Cacheable в родительском классе, и ни одна из них не работала: я не видел никаких записей в моем журнале Perf4J, и кэш не обновлялся.Когда я перешел @Profiled в методы дочерних классов, я начал видеть записи в perf4j.log.

...