このページでは PHP エージェントの API について説明し、API のユースケースの例を示します。

PHPエージェントのAPIについて

PHPエージェントのAPIを使用して以下のことができます。 

  • カスタム ビジネス トランザクションをプログラムで定義する
  • デフォルトの検出で対応していないエントリポイントの相関ヘッダーを提供する
  • カスタム終了コールを作成し、PHP エージェントが自動検出しないバックエンドを検出する

PHP AppDynamics APIヘッダーファイルのインクルード

エージェントがアンインストールされたり、一時的に無効にされた場合でも正常に動作するように、アプリケーションに appdynamics_api_header.php ファイルを含める必要があります。このファイルにはエージェントが存在しない場合にアプリケーションがエラーをスローするのを防ぐ空のAPI関数があります。

appdynamics_api_header.php  ファイルは、install.sh スクリプトと同じディレクトリにある PHP エージェントパッケージにあります。

ヘッダーファイルをインクルードするには、次の手順に従います。

  1. モニタ対象のアプリケーションのヘッダーファイルを保持する場所に appdynamics_api_header.php をコピーする。
  2. appdynamics_api_header.php が include パスにあることを確認する。
  3. そして、スクリプトに以下を追加する。
 require 'appdynamics_api_header.php';

MySQLiドライバによるバックエンド検出

PHP対応環境」に示されているように、PHP エージェントは、new キーワードを使用して MySQLi データベースドライバでデータベースバックエンドをインスタンス化する PHP 5.2 アプリケーションでは機能しません。たとえばAppDynamicsは、PHP 5.2アプリケーションで次のように作成されたMySQLiバックエンドを検出しません。

$db = new mysqli("localhost", "user", "password", "database");
CODE

これを回避するには、代わりに mysqli_connect() を使用します。

$db = mysqli_connect("localhost", "user", "password", "database");
CODE

スクリプトの一部がビジネストランザクションの場合。

多数の個別タスクを実行する長い PHP スクリプトアプリケーションがあって、その中の一部のみをビジネストランザクションとしてエージェントで検出する場合は、各タスク用のコードを appdynamics_start_transaction() コールと appdynamics_end_transaction() コールの間に追加します。エージェントはそれらのブロックを個別のビジネストランザクションとして検出します。これをしない場合、エージェントはスクリプト全体を1つのビジネストランザクションとして検出します。

ループで実行されるビジネストランザクションのコードの処理

データベースやリモートサービスからアイテムを取得するような、ループ内で実行されるスクリプトベースのCLIアプリケーションについては、ループの各反復を個別のビジネストランザクションとしてエージェントに検出させたい場合があります。この場合は appdynamics_start_transaction() コールと appdynamics_end_transaction() コール間のループ内にコードを追加します。

これをしない場合、エージェントはループ中のすべての反復を1つのビジネストランザクションに集約します。

以下の例では、エージェントはすべての反復で「getItem」という名前のビジネストランザクションを検出します。

while (true){
    appdynamics_start_transaction("getItem", AD_CLI);
    //your code goes here
    . . .
    appdynamics_end_transaction();
}
CODE

アップストリームサービスとの相関

分散ビジネストランザクションがあり、そこでティアと PHP エージェントが対応しないエントリポイントのアップストリームサービスを相関する必要がある場合、トランザクション相関を保つには、ダウンストリームティアで appdynamics_continue_transaction() を使用し、サービスからの相関ヘッダーを渡します。

Transaction Correlation

次のサンプルに示すように、サービスから相関ヘッダを抽出する必要があります。このサンプル関数は、AMQP メッセージキューの各メッセージから相関ヘッダーを抽出し、appdynamics_continue_transaction() に渡します。

メッセージを処理後、appdynamics_end_transaction() を呼び出し、呼び出し側のティアでトランザクションの継続を終了します。そのティアが他のダウンストリームティアに分散コールを行う場合、appdynamics_end_transaction() コールは、分散トランザクションの全体を終了するわけではありません。

function amqp_receive($exchangeName, $routingKey, $queueName) {
    $amqpConnection = amqp_connection();
    $channel = new AMQPChannel($amqpConnection);
    $queue = new AMQPQueue($channel);
    $queue->setName($queueName);
    $queue->bind($exchangeName, $routingKey);
    while($message = $queue->get()) {
        // Extracting the correlation header.
        echo("Message #".$message->getDeliveryTag()." '".$message->getBody()."'");
        echo("Correlation header: " . $message->getHeader("singularityheader"));
        // Passing correlation header to API.
        appdynamics_continue_transaction($message->getHeader("singularityheader"));
        doStuff($message);
        // End transaction.
        appdynamics_end_transaction();
    }
    if(!$amqpConnection->disconnect()) {
        throw new Exception("Could not disconnect !");
    }
}
CODE

 サービスがサポートされていないエントリーポイントで、これを行わない場合、ティアはアップストリームトランザクションと相関されません。

ソケットベースのHTTPコールの例

APIにはソケットベースのHTTPコール用のビルトインコールは含まれませんが、次の例に示すように、ご自分でソケットベースのHTTP終了コールの監視を実装できます。 

<?php function doSocketHTTPCall($url, $corrHeader = null)
{
    $parts = parse_url($url);
    $fs = @fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80, $errno, $error);
    if (!$fs)
        return null;
    $send = "GET {$parts['path']} HTTP/1.1\r\n" .
        "Host: {$parts['host']}\r\n" .
        "Connection: Close\r\n";
    if ($corrHeader)
        $send .= "singularityheader: $corrHeader\r\n";
    $send .= "\r\n";
    fwrite($fs, $send);
    $data = stream_get_contents($fs);
    fclose($fs);
    return $data;
}

$url = 'http://httpstat.us/200';
$parts = parse_url($url);

$exitCall = appdynamics_begin_exit_call(
                AD_EXIT_HTTP,
                'HTTP Status Service',
                array('HOST' => $parts['host'],
                      'PORT' => (string)$parts['port'])
            );

doSocketHTTPCall($url);

appdynamics_end_exit_call($exitCall);
?>

CODE

HTTPペイロードへの相関ヘッダの挿入

次の例では、ソケットベースのHTTPペイロードに相関ヘッダを挿入します。

<?php $url = 'http://myhost.mydomain/continue.php';
$parts = parse_url($url);

$exitCall = appdynamics_begin_exit_call(
                AD_EXIT_HTTP,
                'HTTP Status Service',
                array('HOST' => $parts['host'],
                      'PORT' => (string)$parts['port'])
            );

$corrHeader = $exitCall->getCorrelationHeader();

doSocketHTTPCall($url, $corrHeader);

appdynamics_end_exit_call($exitCall);
?>

CODE

以下の例では、包括的なフラグを使用し、他の終了コールを内包している可能性のある終了コールの開始方法を示します。まず外側のソケット HTTP コールが開始され、次に file_get_contents() コールがエージェントにより正常に処理され、最後に外側のコールが終了します。また、エラーを報告するために、例外オブジェクトも渡します。結果として、両方のバックエンドがフローマップに表示されます。

<?php class SocketHTTPException extends Exception
{
}

$url = 'http://httpstat.us/200';
$javaTierURL = 'http://myhost.mydomain/process.jsp';
$parts = parse_url($url);

$exitCall = appdynamics_begin_exit_call(
                AD_EXIT_HTTP,
                'HTTP Status Service',
                array('HOST' => $parts['host'],
                      'PORT' => (string)$parts['port']),
                false
            );

$contents = file_get_contents($javaTierURL);

if (doSocketHTTPCall($url) == null) {
    $error = new SocketHTTPException("something bad happened");
}

appdynamics_end_exit_call($exitCall, $error);

?>
CODE