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

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

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

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

Splunk AppDynamics API ヘッダーの追加

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

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

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

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

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

多数の個別のタスクを実行する長い PHP スクリプトアプリケーションがあり、それらのうちの 1 つ以上のタスクのみをビジネストランザクションとしてエージェントに検出させる場合は、それらの各タスクのコードを 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