perf4j @Profileed аннотация не работает

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

Я что-то упускаю?


person Himalay Majumdar    schedule 24.03.2011    source источник
comment
Все услуги Codehaus были прекращены. Ваша ссылка на Codehaus не работает.   -  person naXa    schedule 06.01.2016


Ответы (6)


Perf4j

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

Как настроить Perf4j. Для обычной настройки вам просто нужно добавить банку perf4j и создать экземпляр 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, который активирует аннотацию @Profiled для perf4j.

(Примечание. Что такое аннотация @Profiled?: вы добавите этот тег ко всем методам во всех классах, которые вызываются из экземпляра Spring или используют внедрение зависимостей. Объект в основном должен быть зарегистрирован в контексте Spring, и метод должен вызываться объект, который зарегистрирован в контексте Spring.Я потратил один день на размышления, почему мой метод не был зарегистрирован, затем я понял, что объект, который я тестировал, не был частью контекста Spring.

ОК, код, который вам нужно добавить в xml конфигурации spring,

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

person Vishal    schedule 19.09.2012

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

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

person gkamal    schedule 24.03.2011
comment
Вы правы, класс WscClientBase.java имел sendMessage(), который НЕ извлекается из контекста приложения Spring. Есть набор классов, которые внедряются как зависимости, и над ними работали EXTEND WscClientBase.java и @Profiled. Есть ли способ заставить @Profiled работать с методами WscClientBase.java или любым другим методом в этом отношении? Благодарю вас! - person Himalay Majumdar; 28.03.2011

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

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

Для обычного весеннего проекта, вероятно, нужно добавить немного больше зависимостей, таких как spring-aop, aopalliance... эти взгляды включены в spring-boot-starter-parent

<сильный>1. Конфигурация Java

Это самый простой способ и в основном работает, но я обнаружил, что он почему-то не работает с методом Spring-data JpaRepository. Он просто предоставляет bean-компонент org.perf4j.log4j.aop.TimingAspect и выполняет автопроксирование аспектов. Так же, как конфигурация xml, предоставленная другими людьми выше

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

<сильный>2. Предоставьте свой аспект

Таким образом, аннотированные методы интерфейса репозитория данных Spring-Data @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;
    }
}
person Steve Park    schedule 08.04.2016

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

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

В обоих случаях они говорят примерно следующее:

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

И ниже…

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

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

person glory1    schedule 14.11.2014

поместите конфигурацию ниже в свой "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"/>
person alex shon    schedule 09.08.2016

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

person jpl    schedule 05.12.2016