This page applies to an earlier version of the AppDynamics App IQ Platform.
For documentation on the latest version, see the 4.4 Documentation.


On this page:

Related pages:

Your Rating:
Results:
PatheticBadOKGoodOutstanding!
39 rates

The PHP Agent APIs are typically used to configure custom business transaction detection for CLI scripts in the following scenarios:

  • Only part of the script is the business transaction.

  • Business transaction code executes in a loop.

  • Downstream tier needs to correlate with an upstream service that is not automatically detected as an entry point.

Scenario: Parts of a script are business transactions.

You have a long script that performs a number discrete tasks, but you want the agent to detect only one or more of them as business transactions.

In this case, enclose the code for each of those tasks within appdynamics_start_transaction() and appdynamics_end_transaction() calls. The agent will detect those blocks as separate business transactions.

If you do not do this, the agent detects the entire script as a single business transaction.

Scenario: Business transaction code executes in a loop.

You have a script that executes in a loop, perhaps fetching items from a database or remote service.

If you want the agent to detect every iteration of the loop as a separate business transaction, enclose the code inside the loop within appdynamics_start_transaction() and appdynamics_end_transaction() calls.

If you do not do this, the agent will aggregate each iteration through the loop into a single business transaction.

In the following example, the agent detects a business transaction named "getItem" for every iteration.

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

Scenario: Correlate with upstream service.

You have a distributed business transaction in which a tier needs to correlate with an upstream service that is not an entry point supported by the PHP Agent. In this case, to maintain transaction correlation, use appdynamics_continue_transaction() in the downstream tier, passing it the correlation header from the service.

It is your responsibility to extract the correlation header from the service.

The following sample function extracts the correlation header from each message in an AMQP message queue and passes it to appdynamics_continue_transaction(). After processing the message, it calls appdynamics_end_transaction(), which ends the continuation of the transaction on the calling tier. The appdynamics_end_transaction() call does not end the entire distributed transaction in the case where that tier makes a distributed call to another downstream tier.

Sample appdynamics_continue_transaction usage
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 !");
    }
}

 If the service is not a supported entry point and you do not do this, the tier will not be correlated with the upstream transaction.

Scenario: Application makes socket-based HTTP calls.

The PHP Agent does not support these but you can implement monitoring of socket-based HTTP exit calls yourself.

Sample socket-based HTTP exit call
<?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);
?>

The next example injects a correlation header into the socket-based HTTP payload.

Sample inject correlation header
<?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);
?>

The next example shows how to use non-exclusive flag to start an exit call that may be wrapping other exit calls. The outer socket-HTTP call is started, then the file_get_contents() call is processed by the agent normally, and finally the outer call is finished. We also pass the exception object to report any errors. The end result is that both backends are displayed on the flowmap.

Sample non-exclusive exit call to start an exit call that may wrap other exit calls
<?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);

?>