1概要

このチュートリアルでは、Spring Frameworkがパフォーマンス監視のために提供する2つの基本的なオプションについて説明します。


2

PerformanceMonitorInterceptor


メソッドの実行時間に対する基本的なモニタリング機能を得るための簡単な解決策として、Spring AOP(Aspect Oriented Programming)から

PerformanceMonitorInterceptor

クラスを利用できます。

Spring AOPでは、アプリケーションで分野横断的な懸念を定義することができます。これは、機能を追加するために、1つ以上のメソッドの実行を妨害するコードを意味します。


PerformanceMonitorInterceptor

クラスは、同時に実行されるカスタムメソッドに関連付けることができるインターセプタです。このクラスは

StopWatch

インスタンスを使用して、メソッド実行の開始時刻と終了時刻を決定します。

監視する2つのメソッドを持つ単純な

Person

クラスと

PersonService

クラスを作成しましょう。

public class Person {
    private String lastName;
    private String firstName;
    private LocalDate dateOfBirth;

   //standard constructors, getters, setters
}

public class PersonService {

    public String getFullName(Person person){
        return person.getLastName()+" "+person.getFirstName();
    }

    public int getAge(Person person){
        Period p = Period.between(person.getDateOfBirth(), LocalDate.now());
        return p.getYears();
    }
}

Springモニタリングインターセプターを利用するためには、ポイントカットとアドバイザを定義する必要があります。

@Configuration
@EnableAspectJAutoProxy
@Aspect
public class AopConfiguration {

    @Pointcut(
      "execution(public String com.baeldung.performancemonitor.PersonService.getFullName(..))"
    )
    public void monitor() { }

    @Bean
    public PerformanceMonitorInterceptor performanceMonitorInterceptor() {
        return new PerformanceMonitorInterceptor(true);
    }

    @Bean
    public Advisor performanceMonitorAdvisor() {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression("com.baeldung.performancemonitor.AopConfiguration.monitor()");
        return new DefaultPointcutAdvisor(pointcut, performanceMonitorInterceptor());
    }

    @Bean
    public Person person(){
        return new Person("John","Smith", LocalDate.of(1980, Month.JANUARY, 12));
    }

    @Bean
    public PersonService personService(){
        return new PersonService();
    }
}

ポイントカットには、傍受されたいメソッドを識別する式が含まれています。この場合は、

PersonService

クラスの

getFullName()

メソッドです。


performanceMonitorInterceptor()

Beanを設定したら、インターセプタをポイントカットに関連付ける必要があります。上記の例に示すように、これはアドバイザによって実現されます。

最後に、

@ EnableAspectJAutoProxy

アノテーションは、私たちのBeanに対して

AspectJ support

を有効にします。簡単に言えば、AspectJはSpring @ AOPを

@ Pointcut

のような便利なアノテーションを通して使いやすくするために作られたライブラリです。

設定を作成したら、インターセプタクラスのログレベルを

TRACE

** に設定する必要があります。これはメッセージをログに記録するレベルです。

たとえば、Jog4jを使用して、

log4j.properties

ファイルを介してこれを実現できます。

log4j.logger.org.springframework.aop.interceptor.PerformanceMonitorInterceptor=TRACE, stdout


getAge()

メソッドを実行するたびに、コンソールログに

TRACE

メッセージが表示されます。

2017-01-08 19:19:25 TRACE
  PersonService:66 - StopWatch
  'com.baeldung.performancemonitor.PersonService.getFullName':
  running time (millis) = 10


3カスタムパフォーマンスモニタリングインターセプター

パフォーマンスの監視方法をもっと制御したい場合は、独自のカスタムインターセプタを実装できます。

そのために、

AbstractMonitoringInterceptor

クラスを拡張し、

invokeUnderTrace()

メソッドをオーバーライドしてメソッドの開始、終了、および期間を記録します。また、メソッドの実行が10ミリ秒以上続く場合は警告します。

public class MyPerformanceMonitorInterceptor extends AbstractMonitoringInterceptor {

    public MyPerformanceMonitorInterceptor() {
    }

    public MyPerformanceMonitorInterceptor(boolean useDynamicLogger) {
            setUseDynamicLogger(useDynamicLogger);
    }

    @Override
    protected Object invokeUnderTrace(MethodInvocation invocation, Log log)
      throws Throwable {
        String name = createInvocationTraceName(invocation);
        long start = System.currentTimeMillis();
        log.info("Method " + name + " execution started at:" + new Date());
        try {
            return invocation.proceed();
        }
        finally {
            long end = System.currentTimeMillis();
            long time = end - start;
            log.info("Method "+name+" execution lasted:"+time+" ms");
            log.info("Method "+name+" execution ended at:"+new Date());

            if (time > 10){
                log.warn("Method execution longer than 10 ms!");
            }
        }
    }
}

前のセクションと同じ手順で、カスタムインターセプタを1つ以上のメソッドに関連付けます。


PersonService



getAge()

メソッドのポイントカットを定義し、それを作成したインターセプターに関連付けましょう。

@Pointcut("execution(public int com.baeldung.performancemonitor.PersonService.getAge(..))")
public void myMonitor() { }

@Bean
public MyPerformanceMonitorInterceptor myPerformanceMonitorInterceptor() {
    return new MyPerformanceMonitorInterceptor(true);
}

@Bean
public Advisor myPerformanceMonitorAdvisor() {
    AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
    pointcut.setExpression("com.baeldung.performancemonitor.AopConfiguration.myMonitor()");
    return new DefaultPointcutAdvisor(pointcut, myPerformanceMonitorInterceptor());
}

カスタムインターセプターのログレベルを

INFO

に設定しましょう。

log4j.logger.com.baeldung.performancemonitor.MyPerformanceMonitorInterceptor=INFO, stdout

g

__etAge()

__メソッドを実行すると、次の出力が生成されます。

2017-01-08 19:19:25 INFO PersonService:26 -
  Method com.baeldung.performancemonitor.PersonService.getAge
  execution started at:Sun Jan 08 19:19:25 EET 2017
2017-01-08 19:19:25 INFO PersonService:33 -
  Method com.baeldung.performancemonitor.PersonService.getAge execution lasted:50 ms
2017-01-08 19:19:25 INFO PersonService:34 -
  Method com.baeldung.performancemonitor.PersonService.getAge
  execution ended at:Sun Jan 08 19:19:25 EET 2017
2017-01-08 19:19:25 WARN PersonService:37 -
  Method execution longer than 10 ms!


4結論

このクイックチュートリアルでは、Springで簡単なパフォーマンスモニタリングを紹介しました。

いつものように、この記事の完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/spring-aop[over on Github]にあります。