Monitoring PHP

The PHP sensor is automatically deployed and installed after you install the Instana agent.

Supported Versions

PHP version CPU architecture Supported Zend Thread Safety Supported type
PHP 5.3 - PHP 8.1 x86_64 Both ZTS and non-ZTS GA
PHP 7.2 - PHP 8.1 aarch64 Both ZTS and non-ZTS GA
SAPI Support
PHP-FPM GA
PHP-CGI GA
Apache with mod_php GA
CLI Experimental

Caveats

PHP on Windows systems is currently not supported.

Currently, Apache HTTP server that is configured to serve PHP content with threaded MPM "worker" or "event" and PHP ZTS are not supported.

Configuration

The PHP sensor is configured with reasonable defaults. Usually you don't need to modify these settings in the configuration.yml file of the Instana agent. The currently available settings are listed as follows:

# PHP Tracing
#com.instana.plugin.php:
#  # Lightweight PHP Tracing. Requires the Instana Tracing extension. Enabled by default.
#  tracing:
#    # Enabling tracing will automatically download the Instana Tracing
#    # extension and enable it in your php.ini. If you are using preforked
#    # PHP workers, like PHP-FPM, you will need to restart them. Disabling
#    # tracing again will not remove the extension. It will only disable the
#    # tracing sensor.
#    enabled: true
#    # Whether to install the PHP Tracing extension. Default is true. Disabling
#    # the installation will still create the TraceAcceptor daemon though.
#    installExtension: true
#    # The filename to use when querying Apache or PHP-CGI installations for
#    # environment data such as version, architecture, etc. By default, this
#    # is "instana." + Math.random(). + ".php". Uncommenting the setting
#    # as follows will force a static filename instead.
#    phpInfoFilename: instana.php
#    # Pins the PHP Tracing extension to download and install to a specific
#    # version. This can be used to rollback to previous versions of the
#    # extension or to test beta versions (when asked to do so). Expects
#    # the version to be given as major.minory.patch, e.g. 0.3.7
#    pinExtensionVersion: x.y.z
#    # The absolute path to the script to trigger whenever the sensor installed
#    # a different version of the PHP tracing extension than is currently
#    # installed. Works for upgrades and downgrades. Default is empty.
#    notificationScript: /path/to/restart_php.sh
#    # The number of executor threads to use for processing traces. This setting
#    # can be used to fine tune the PHP sensor for specific load environments.
#    # Defaults to the number of available logical processors or 8 (whichever is less).
#    # In general, you don't need to touch this setting unless advised to do so.
#    executorThreads: n
#    # The maximum number of traces the sensor is allowed to keep in the backlog
#    # for processing. Can be used in conjunction with executorThreads to fine tune
#    # the sensor for specific load environments. In general, you don't need to touch
#    # this setting unless advised to do so. Defaults to 750.
#    executorQueueLimit: 750
#    # Port on which the sensor is listening for traces. Changing this setting will
#    # not automatically update any .ini files created for the PHP Tracing extension.
#    # In general, you don't need to touch this setting unless advised to do so.
#    # Defaults to port 16816.
#    port: 16816
#    # Whether to remove values in SQL queries to prevent sensitive data from
#    # reaching our backend. This can help to improve agent performance in certain
#    # setups. In general, you don't need to touch this setting unless advised to do so.
#    sanitizeSql: true

See the section titled Automatic Restarts as follows for additional details on how to use notificationScript.

Enable PHP-FPM status page

In order to thoroughly monitor PHP-FPM metrics, you need to enable the status page. To do so, open the worker pool config and add the entry pm.status_path = /status. The Instana PHP-FPM sensor will directly access this endpoint via fcgi.

Apache Configuration: The Apache configuration needs to contain the following line.

SetHandler application/x-httpd-php

Without it, the sensor will fail to load and the following error message will be logged:

> "PHP Sensor is failing because of "NO Version found"

Metrics collection

To view the metrics, select Infrastructure in the sidebar of the Instana User interface, click a specific monitored host, and then you can see a host dashboard with all the collected metrics and monitored processes.

For PHP, the configuration data, performance metrics, and the health signatures depend on the utilized SAPI.

Like any other Instana sensors, PHP does not require any configuration and automatically detects your installation.

Configuration
PHP version
Server API
Zend Thread Safety
Loaded Modules
Main Ini file
Ini directory
Additional Ini files parsed
PHP extensions directory

PHP-FPM

In addition to the generally tracked configuration above, PHP-FPM will also include

Configuration Metrics
Master Process ID Connections
Master Configuration Processes
Worker Pools Resources

Health Signatures

For each sensor, there is a curated knowledgebase of health signatures that are evaluated continuously against the incoming metrics and are used to raise issues or incidents depending on user impact.

Built-in events trigger issues or incidents based on failing health signatures on entities, and custom events trigger issues or incidents based on the thresholds of an individual metric of any given entity.

For information about built-events for PHP-FPM, see the Built-in events reference.

Apache with mod_php

Supports tracing. The generally tracked configuration will be included in the Apache dashboard.

PHP-CGI

Support tracing. The generally tracked configuration will be included in the used webserver's dashboard (if applicable).

CLI

Instana can provide tracing for CLI when the tracing extension is configured with the flag instana.enable_cli = 1. However, since CLI requests are usually ephemeral, Instana cannot connect them to the Dynamic Graph. This means, you will see the trace, but you won't have any information about connected services or infrastructure. Also, the tracing extension needs to installed manually. Please contact support if you need support with setting up CLI tracing.

Tracing

Instana instruments your PHP application at the PHP engine level, providing traces for selected function calls, in particular:

HTTP
cURL
fastcgi_finish_request
HTTP Streams
Sessions
Frameworks
Wordpress
Laravel
Symfony
Zend Framework
Databases
AMQP (pecl-amqp)
AMQP (php-amqp-lib)
Cassandra
Couchbase
Elasticsearch
Google Cloud Pub/Sub
IBM DB2
LDAP
Memcache
Memcached
MongoDB
Mysql
Mysqli
OCI8
CUBRID (PDO)
MS SQL Server (PDO)
Firebird (PDO)
IBM (PDO)
Informix (PDO)
MySQL (PDO)
MS SQL Server (PDO)
Oracle (PDO)
ODBC and DB2 (PDO)
PostgreSQL (PDO)
SQLite (PDO)
PostgreSQL (PDO, not ext-pgsql)
Redis (via predis or PECL redis)
Logging
Drupal logger
Kohana logger
Magento logger
Monolog
Yii logger
Zend_Log
Templating
Twig
Blade
Other
Shell calls
Compile time
OpCache metrics

Note that Stack Traces in Span details are only supported with PHP 5.4+.

The Instana Agent requires the PHP Tracing extension, which is automatically downloaded when the PHP sensor is enabled. The configuration is located at <agent_install_dir>/etc/instana/configuration.yml and the current version of the Instana Agent contains an example of the required configuration settings.

PHP tracing is active by default: Instructions to disable tracing

The PHP sensor is linked to a PHP SAPI sensor. This means tracing will only start when the Instana Agent detects a supported SAPI sensor (currently PHP-FPM, mod_php, and php-cgi).

The PHP sensor will gather information about the SAPI's configuration and download an appropriate Instana extension based on your version of PHP and your host's architecture. The PHP sensor will always download the latest version of the Instana extension. However, you can also pin/force a specific version via the configuration.yml

Required PHP extensions:

  • JSON

Once the Instana Tracing extension is downloaded, it will place a zzz_instana.ini file either into your "Additional ini" directory, or add it to the ini file used by the PHP SAPI.

The sensor will attempt to do a graceful restart of your PHP environment to load the tracing extension into memory. See the section titled Automatic Restarts as follows for additional details.

In addition, if you are using Plesk, you will need to run plesk bin php_handler --reread.

Fine tuning the extension:

The PHP tracing extension comes with sane defaults for most tracing scenarios in zzz_instana.ini. However, you can adjust settings to accommodate specific needs, such as sampling, batching or chunking. The PHP sensor will not overwrite the zzz-instana.ini as long as the tracing extension is loaded into the PHP environment. So while adding additional settings in there is safe, it can be inconvenient in containerized setups. A good practice in such scenarios is to add an additional zzz-instana-extras.ini and make that part of the container deployment.

The available settings are:

  • instana.socket: address of the Instana PHP Sensor's TCP socket. The socket address is determined during installation and defaults to tcp://127.0.0.1:16816.
  • instana.log_level: what to log. 0 = off, 1 = ERROR, 2 = WARN, 3 = INFO, 4 = DEBUG. Defaults to 0 (off).
  • instana.enable_cli: whether to enable tracing for the CLI SAPI. 1 = on. 0 = off. Defaults to 0 (off).
  • instana.batch_threshold_us: the length and distance threshold in which batching of spans happens. Defaults to 10000.
  • instana.backtrace_limit: controls the depth of recorded call stacks. Defaults and capped to 25 entries.
  • instana.span_chunk_size: the number of spans to keep in PHP's memory before sending to the agent. Note that this directly affects batching, e.g. chunks of one effectively disable batching.
  • instana.disable_userland_tracing: Disables all tracing for non-native extensions, e.g. frameworks and other PHP userland code. Defaults to 0 (off).
  • instana.segfault_error_log: whether to capture a backtrace to PHP's error log on segfaults. Defaults to 0 (off).
  • instana.disabled_instrumentation: Bitmask of instrumentations to disable. Default is 0 (none). Available flags are listed as follows.

Available flags:

  • STREAMS 1
  • PHP 2
  • PDO 4
  • CURL 8
  • REDIS 16
  • MONGODB 32
  • MYSQL 64
  • MEMCACHE 128
  • DB2 256
  • OCI 512
  • SHELL 1024
  • PECL_HTTP 2048
  • REQUEST_HEADERS 4096
  • RESPONSE_HEADERS 8192
  • SOAP 16384
  • WORDPRESS 32768
  • AMQP 65536 (applies to both pecl-amqp and php-amqp-lib)
  • ELASTICSEARCH 131072
  • EXCEPTIONS 262144
  • LOGGERS 524288
  • COUCHBASE 1048576
  • TWIG 2097152
  • SYMFONY 4194304
  • KOHANA 134217728
  • GOOGLE_PUBSUB 268435456

The flags are not exposed by name. You have to use their numeric values to disable an instrumentation.

Please contact support if you need help with these settings.

Uninstalling the Instana PHP Tracing extension

To uninstall the Instana PHP Tracing extension, you will first need to disable PHP sensor startup. Otherwise, it will install the extension again. Unlike installation, deinstallation is not automatic and requires further manual steps.

Disabling the PHP Tracing sensor

Open <agent_install_dir>/etc/instana/configuration.yml with a text editor. There should be an entry like the following:

com.instana.plugin.php:
  tracing:
    enabled: true

Change enabled: true to enabled: false. Note that tracing is enabled by default, so commenting this will not disable tracing.

As an alternative, you can also set installExtension: false to disable the installation of the PHP Tracing extension but keep the sensor listening for traces.

You need to restart the agent to apply the changes.

Note that disabling the sensor does not disable the tracing extension. Continue as follows if you also want to disable or fully remove the extension.

Disabling the PHP Tracing extension

When the PHP sensor installed the extension, it also enabled it for your PHP installation. This means it either placed a zzz_instana.ini into your "Additional Ini" files folder, or enabled it directly in your php.ini.

To find out where it was enabled, run the php binary for which you enabled tracing. So for a php-fpm (note that your binary name may differ):

    $> php-fpm7.0 -i | egrep "^(Scan|Loaded)"
    Loaded Configuration File => /etc/php/7.0/fpm/php.ini
    Scan this dir for additional .ini files => /etc/php/7.0/fpm/conf.d

In the example above, a file called zzz_instana.ini will be located in /etc/php/7.0/fpm/conf.d. If there is no "Additional Ini" files folder, or the zzz_instana.ini file does not exist at that location, check your php.ini instead. In the example above, this would be /etc/php/7.0/fpm/php.ini.

Note: For Apache with mod_php, put a php file with the content <?php phpinfo(); into a web accessible location on Apache and open it in a browser for the same information.

Open the appropriate ini file in an editor and change the line: extension=/path/to/instana.so

to be prefixed with ";" (this will comment out the line). ;extension=/path/to/instana.so

Alternatively, remove the line altogether (not recommended if you intend to enable the extension at a later point). If you have a zzz_instana.ini, you can also remove it completely:

$> sudo rm /etc/php/7.0/fpm/conf.d/zzz_instana.ini

Do not remove your entire php.ini file.

If you are using pre-forked workers, you will need to restart the PHP master process now. Otherwise, the extension will still be active in memory.

Note that disabling the extension does not remove it from your system. If you also want to remove the extension, continue as follows.

Removing the PHP Tracing extension

PHP will log startup errors when it cannot find an extension, so if you remove the extension you must also disable it (see above).

The PHP sensor will place the Instana PHP Tracing extension into the directory given in the extension_dir setting in your php.ini. To find out the setting, run the php binary for which you enabled tracing. So for a php-fpm (note that your binary name may differ):

$> php-fpm7.0 -i | egrep ^extension_dir
extension_dir => /usr/lib/php/20151012 => /usr/lib/php/ext

Note: For Apache with mod_php, put a php file with the content <?php phpinfo(); into a web accessible location on Apache and open it in a browser for the same information.

The PHP sensor will only use the first value, so in the example above, you can find the extension at/usr/lib/php/20151012. The path to the extension is also given in your php.ini or the instana.ini.

$> sudo rm /usr/lib/php/20151012/instana.so

If you are using pre-forked workers and did not already restart your PHP master process when disabling the extension, you need to do so now for the changes to take effect.

Automatic Restarts

The PHP sensor will automatically download and install the appropriate PHP tracing extension for your PHP setup. In addition, the sensor will attempt a graceful restart of your PHP environment to load the extension into memory. Automatic restarts are currently supported for Apache and PHP-FPM. PHP-CGI environments need manual or scripted handling (read on).

You can change how the PHP sensor attempts to restart your PHP environment via the notificationScript configuration setting. The setting takes an absolute path to an executable shell script. This script gets triggered whenever the currently installed tracing extension is a different version than the agent installed.

When this script is configured and executed successfully, it will override the default mechanism for automatic restarts. Unlike the default mechanism, the script will get executed for any SAPI, so it can be used to automate restarts for PHP-CGI environments. If you want to disable automatic restarts completely, just configure an empty script.

The PHP sensor will set the following environment variables for the script execution:

INSTANA_EXT_VERSION_OLD = the version of the tracing extension currently in memory
INSTANA_EXT_VERSION_NEW = the version of the tracing extension after a restart
INSTANA_PID_HOST = the PID of the process on the host, e.g. your Apache, PHP-FPM or PHP-CGI
INSTANA_PID_CONTAINER = the PID the host process has in a container (if applicable)
INSTANA_CONTAINER = the ID/name of the container the process is running in (if applicable)

The following is an example script that will log extension changes to a file and restart Apache:

    #!/bin/bash
    echo "Found new tracing extension." >> php_update.log;
    echo "INSTANA_EXT_VERSION_OLD=$INSTANA_EXT_VERSION_OLD" >> php_update.log;
    echo "INSTANA_EXT_VERSION_NEW=$INSTANA_EXT_VERSION_NEW" >> php_update.log;
    echo "INSTANA_PID_HOST=$INSTANA_PID_HOST" >> php_update.log;
    echo "INSTANA_PID_CONTAINER=$INSTANA_PID_CONTAINER" >> php_update.log;
    echo "INSTANA_CONTAINER=$INSTANA_CONTAINER" >> php_update.log;
    echo "restarting apache" >> php_update.log;
    apachectl -k graceful >> php_update.log;

If your Apache runs inside a container, replace the last line in the sample script above with:

docker exec $INSTANA_CONTAINER apachectl -k graceful;

For PHP-FPM, you can send a SIGUSR2 to gracefully restart it, e.g.

docker exec $INSTANA_CONTAINER kill -USR2 $INSTANA_PID_CONTAINER;

A graceful restart will load the PHP extension into memory without restarting the master process. So this will work even when the process runs as PID 1 inside the container. If you cannot or want not use the restart approach, you can also snapshot the running container instance, stop it and bring up a new instance easily:

    #!/bin/bash
    IMAGE_HASH=$(docker inspect --format='{{.Config.Image}}' $INSTANA_CONTAINER)
    IMAGE_NAME=$(docker images | grep $IMAGE_HASH | awk '{print $1}')
    IMAGE_TAG="instana-php-$INSTANA_EXT_VERSION_NEW"
    docker commit $INSTANA_CONTAINER $IMAGE_NAME:$IMAGE_TAG &&
    docker stop $INSTANA_CONTAINER &&
    docker run -d --rm $IMAGE_NAME:$IMAGE_TAG

This will use the container ID passed to the script to find the name of the container image. It will then commit the currently running container into a new image tagged with the new PHP extension version number. It will then stop the original container and start a container from the newly tagged image. While this will trigger the installation routine in the PHP sensor again, it will not trigger the notification script again, because the extension is already installed.

The above examples assume you are using Docker as your container engine. But since the triggered shell script is completely under your control, you can put any logic you need to make automatic restarts work for your setup.

PHP SDK

The PHP Tracing extension comes with a minimal SDK that allows manual instrumentation of code. Spans created via this SDK will be injected into the automatically generated traces. The SDK also allows to record exceptions manually to complement Instana's automatic recording of uncatched exceptions.

Installing the SDK

The stubs of the PHP SDK can be installed via Composer with the follwing command:

composer require instana/instana-php-sdk

The stubs ensure that, when the PHP process is not monitored with Instana, all calls to the SDK APIs result in a no-op, rather than errors.

Stubs of the PHP SDK to be used with your IDE are available on Packagist.

Example of SDK Usage

A typical usage example would be

$tracer = new \Instana\Tracer();
$tracer->setServiceName('my-service');
$span = $tracer->createSpan('foo');
$span->annotate('function', 'doSomething');
try {
    doSomething();
} catch (\Exception $e) {
    $tracer->logException($e);
    $span->markError();
} finally {
    $span->stop();
}

Create custom ENTRY and EXIT spans

Using PHP Tracing extension you are allowed to create custom spans of ENTRY or EXIT type.

// get the tracer
$tracer = new \Instana\Tracer();

$entry_span = $tracer->createSpan('entry', \Instana\SPAN_ENTRY);

$exit_span = $tracer->createSpan('exit', \Instana\SPAN_EXIT);

Setting parent span

When creating new span with PHP SDK it's possible to set the ID of parent span which can be useful in case of continuation traces created by other system. The relevant code snippet should look like:

// get the tracer
$tracer = new \Instana\Tracer();

$span = $tracer->createSpan('entry', \Instana\SPAN_INTERMEDIATE, $parentId);

Trace Continuation

The PHP Tracing extension allows continuing traces through messaging systems. To do so, you need to inject the trace context of the publisher into the message and extract it on the consumer side.

Publisher

// get the tracer
$tracer = new \Instana\Tracer();

// GENERIC: an artificial message you want to send to your queue
$message = ['task' => 'convert-image'];

// retrieve the current trace context
$context = $tracer->getActiveContext();

// GENERIC: inject the current active context into your message, so you can retrieve it in the worker later
$attributes = $message['X-INSTANA-S'] = $context->getSpanId();
$attributes = $message['X-INSTANA-T'] = $context->getTraceId();

// send your message to the queue
$queue->publish($message);

Consumer

// get the tracer
$tracer = new \Instana\Tracer();

// GENERIC: pull your message from the queue
$message = $queue->pull();

// GENERIC: extract trace context so we can continue the trace, assumes it's always present
$messageContext = new \Instana\TraceContext($message['X-INSTANA-T'], $message['X-INSTANA-S']);

// continue the trace that published the message
$tracer->continueTrace($messageContext);

// OPTIONAL: Create a span to wrap the unit of work
$span = $tracer->createSpan('work');
$span->annotate('job', 'my-important-job');

// do the actual work

// stop the optional span started above
$span->stop();

Google Cloud Pub/Sub

The PHP Tracing extension will automatically create EXIT spans for outgoing interactions with Google Cloud Pub/Sub.

For trace continuation, you will need to manually wrap the code that consumes the Pub/Sub messages.

use Google\Cloud\PubSub\PubSubClient;

$tracer = new \Instana\Tracer();

$pubSub = new PubSubClient([
    'projectId' => $myProjectname
]);

$topic = $pubSub->topic($myTopicName);
$subscription = $pubSub->subscription($mySubscriptionName, $myTopicName);

$messages = $subscription->pull();
foreach ($messages as $message) {
    $attributes = $message->attributes();

    // extract the trace continouation headers from your message, assumes it's always present
    $messageContext = new \Instana\TraceContext($attributes['x-instana-t'], $attributes['x-instana-s']);

    // continue the trace that published the message
    $tracer->continueTrace($messageContext);

    // convert the current span
    $span = $tracer->getEntrySpan();
    $span->asGCPubSubReceive($project, 'php-consumer');

    // OPTIONAL: Create a span to wrap the unit of work
    $span = $tracer->createSpan('work');
    $span->annotate('job', 'my-important-job');

    // do the actual work

    // stop the optional span started above
    $span->stop();

    $subscription->acknowledge($message);
}

Removing the SDK

Note that removing the PHP Tracing extension will also require to remove any manually added SDK code; otherwise, PHP will fail script execution due to missing functions.

OpenTracing

Instana provides a separate PHP SDK for tracing with OpenTracing. Unlike Instana's own PHP instrumentation, using the OpenTracing SDK requires you to manually instrument your code. Traces generated via the PHP OpenTracing SDK will be separate from traces generated by Instana's own tracing.

Service Naming

Instana will automatically try to determine a useful service name from the traces it collects. However, it is possible to force a service name manually. The PHP Tracer will look for the key INSTANA_SERVICE_NAME in PHP's $_SERVER and $_ENV arrays and use whatever is set for a value as the service name.

Setting the Process Name

Use the environment variable INSTANA_PROCESS_NAME to set a custom label for the infrastructure entity that represents the PHP process.