Do You PHP はてブロ

Do You PHPはてなからはてブロに移動しました

MeasurementInterceptor作ってみた

先ほどのeAccelerator/APCパフォーマンスネタですが、元々はs2container.php5/s2dao.php5+eAccelerator0.9.5で例外がthrowされずにFATALになってしまい、「なにー!」と言い始めたことがきっかけです。
で、サンプルアプリでベンチマークを取ろうとMeasurementInterceptorを作ったので、参考になるかどうか分かりませんがコードを乗っけます(というほどのものでもないけど)。元ネタは、以前購入したSeasar入門 はじめてのDI&AOPです。

Seasar入門 はじめてのDI&AOP

Seasar入門 はじめてのDI&AOP

PHPコードは以下の通りで、計測した実行時間をDEBUGレベルでログ出力します。また、PHPにはfinallyがないため、

  • catchした例外を保存
  • ログ出力
  • catchした例外があれば、それをthrow

といった変なコードになっていますが、aspectをかけたメソッドで例外が発生してもログ出力されます。

<?php
class MeasurementInterceptor implements S2Container_MethodInterceptor {

    private static $logger;

    public function __construct(S2Container_DataSource $datasource) {
        self::$logger = S2Container_S2Logger::getLogger(__CLASS__);
    }

    public function invoke(S2Container_MethodInvocation $invocation) {
        $ret = null;
        if(S2CONTAINER_PHP5_LOG_LEVEL == 1){
            $start_time = $this->getCurrentTimeMillis();
        }
        $caught_exception = null;
        try {
            $ret = $invocation->proceed();
        } catch (Exception $e) {
            $caught_exception = $e;
        }
        if(S2CONTAINER_PHP5_LOG_LEVEL == 1){
            $end_time = $this->getCurrentTimeMillis();
            $buf = $invocation->getTargetClass($invocation)->getName() . '#' .
                   $invocation->getMethod()->getName();
            self::$logger->debug($buf . ' : ' . ($end_time - $start_time));
        }
        if (!is_null($caught_exception)) {
            throw $caught_exception;
        }
        return $ret;
    }

    private function getCurrentTimeMillis() {
        list($usec, $sec) = explode(" ", microtime());
        return ((float)$usec + (float)$sec);
    }
}

利用する場合、diconファイルに

    <component name="measurement" class="MeasurementInterceptor"/>
    <component name="targetClass" class="TargetClass">
        <aspect>measurement</aspect>
    </component>

のように記述して、目的のメソッドにMeasurementInterceptorを噛ませればOKのハズです :-)

追記

S2Container_AbstractInterceptorをextendsした方がヨサゲですね。