PHP Application Performance Monitoring

The Atatus PHP Agent helps you in troubleshooting your PHP application problems and also identifies performance issues before it becomes apparent to your users. It also captures unhandled exceptions and HTTP failures in production to determine which part of your PHP application is slower or producing lots of errors.

Create a free account to start monitoring your PHP apps.

Installation & Setup

1. Install Atatus PHP agent:

Download and Install

// Download Debian tarball
wget https://s3.amazonaws.com/atatus-artifacts/atatus-php/downloads/atatus-php-1.3.0-x64-debian.tar.gz
// Download Redhat tarball
wget https://s3.amazonaws.com/atatus-artifacts/atatus-php/downloads/atatus-php-1.3.0-x64-redhat.tar.gz
// Download musl tarball
wget https://s3.amazonaws.com/atatus-artifacts/atatus-php/downloads/atatus-php-1.3.0-x64-musl.tar.gz
// Download OSX tarball
wget https://s3.amazonaws.com/atatus-artifacts/atatus-php/downloads/atatus-php-1.3.0-x64-osx.tar.gz

// Unzip and install the agent files
tar -xzvf atatus-php-1.3.0-ARCH-OS.tar.gz
cd atatus-php-1.3.0-ARCH-OS
sudo bash ./install.sh

2. Add your project api key to the Atatus configuration file: atatus.ini.
You can find the path of atatus.ini file by running php -i | grep atatus.ini command in the shell.

3. Stop and Start your servers such as nginx, php-fpm, apache, httpd, etc. Then you will see the performance data in few minutes.

Configuration options

Atatus has a number of setting to configure the way that you want to monitor your PHP application. These settings can be configured in atatus.ini. You can find the path of the "atatus.ini" as follows

In a command line, run the following command.
php -i | grep atatus.ini
In a browser, search through the output of following script for "atatus.ini"
<?php phpinfo(); ?>

You can modify following configurations in your atatus.ini file.

Name Description
atatus.api_keystring API Key of your PHP project. It is mandatory.
atatus.enabledboolean Enable/Disable the Atatus PHP agent.
atatus.frameworkstring Atatus automatically finds the framework of the application. Incase it fails to identify, then you can set them manually here.
Possible Values: Laravel, Symfony2, Yii2, Silex, Zend3, Slim3, Cake3
atatus.app_versionstring Version number of the PHP application.
atatus.release_stagestring Release stage of the application. E.g. production, development, staging.
atatus.tagsstring Tags can be added to provide extra information and to help filtering errors and performance metrics. You can provide multiple tags separated by comma.
E.g. us_east_1,php_queue_server
atatus.hostnamestring Custom hostname for your application server instead of default hostname.
atatus.collector.pathstring Path of the collector executable.
atatus.collector.pidfilestring Path of collector's process ID (PID) file.
atatus.collector.connectionstring Path of UNIX-domain socket through which Agent and Collect will communicate.
atatus.collector.notify_hoststring Atatus APM Endpoint. All data will be sent to this server.
atatus.collector.notify_sslboolean When set, all communication with Atatus server will be in secure HTTP connection.
atatus.collector.notify_proxystring Proxy server URL if any. Format: scheme://proxy_host:proxy_port
The scheme can be http, https, socks, socks4, or socks5.
e.g: http://localhost:3128, socks4://localhost:1080, socks5://localhost:1080
atatus.collector.log_levelstring Log level tells what detail to include in the collector log file.
It can be following values: error, warning, info, debug, none
atatus.collector.log_filestring Name of the file to send collector log messages to.
atatus.agent.log_levelstring Log level tells what detail to include in the agent log file.
It can be following values: error, warning, info, debug, none
atatus.agent.log_filestring Name of the file to send agent log messages to.
atatus.trace.enabledboolean When set, trace will be collected for critical transactions.
atatus.trace.response_timenumber Response Time Threshold for critical transactions. Trace will be collected for a transaction if the response time is greater than the given threshold. It should be milliseconds. By default, it is 2000 ms.
PHP Agent API

The API allows you to manage the instrumentations. All API calls must be enclosed with following conditional check to avoid error even if the agent is not available.

if (extension_loaded('atatus')) {
    // Atatus PHP Agent API call
}

Begin transaction

You can change the start of the transaction instrumentation as follows, for e.g. in your message queueing code so that the worker is not instrumented while it is waiting for a message to be published.

if (extension_loaded('atatus')) {
    atatus_begin_transaction();
}
End transaction

You can end the transaction instrumentation before the actual completion of the request, for e.g. when you would like to end the tasks in your job queue manager

if (extension_loaded('atatus')) {
    atatus_end_transaction();
}
Ignore transaction

You can exclude particular transaction with atatus_ignore_transaction function. You can invoke this function inside any route that you don't want to monitor.

if (extension_loaded('atatus')) {
    atatus_ignore_transaction();
}
Set transaction name

You can change the transaction name instead of default route name. You can do it as follows

if (extension_loaded('atatus')) {
    atatus_set_transaction_name("custom_transaction_name");
}

The argument of the function is the name of the transaction.

Instrument custom function

If you want to instrument specific function and see it in the transaction's layer, then you can do it as follows

if (extension_loaded('atatus')) {
    atatus_add_custom_layer("function_name");
}

// OR

if (extension_loaded('atatus')) {
    atatus_add_custom_layer("SampleClass::some_method");
}

The argument is the name of the function to be monitored.

Notify Exception and Error

Atatus automatically captures all unhandled exceptions and HTTP failures from your PHP app. If you want to send error manually, you can do it by atatus_notify_exception function. The accepts an error as either a string or an Exception object as an argument.

try {
  // Your code
} catch (Exception $ex) {
  if (extension_loaded('atatus')) {
    atatus_notify_exception($ex);
  }
}


Multiple PHP Apps in a Single Server.

The default Atatus PHP installation treats entire PHP deployment as a single PHP application with a single node. Incase if you have multiple PHP application running in the same Nginx or Apache server, you might want to monitor them as different PHP project in Atatus.

You can set separate API key for each and every PHP application running on the same server through function call or Apache/Nginx configuration.

1. Set API Key through function call

When you have multiple PHP application in a single server and want to set different API key for each app, then you can invoke atatus_set_api_key function with corresponding API key in the start of the application code.

if (extension_loaded('atatus')) {
    atatus_set_api_key("PROJECT_API_KEY");
}
2. Apache

There are two ways you can set application specific API key in Apache. You can do them through:

  1. httpd.conf file
  2. .htaccess file
httpd.conf file

You can set Atatus configuration either in httpd.conf file or one of its included files as follows

<VirtualHost *:80>
  ServerName www.myserver.com
  DocumentRoot "/path/to/app/"
  ...
  <IfModule php7_module>
    php_value atatus.api_key "Your API Key"
  </IfModule>
</VirtualHost>

Similar to API key setting, you can set all other Atatus agent configurations specific to the application. For example, if you want to disable Atatus agent for specific application, then you can do as follows

<VirtualHost *:80>
  ...
  <IfModule php7_module>
    php_value atatus.enabled off
  </IfModule>
</VirtualHost>

Note: All string values should have double quotes. Any boolean value is either on or off.

.htaccess file

The .htaccess file must be in the top-level directory for that application. You can set the API key inside an .htaccess file. An example would be:

php_value atatus.api_key "PROJECT_API_KEY"
3. Nginx

There are two ways you can set the API key in Nginx. You can do them through:

  1. Nginx config file
  2. .user.ini file
Nginx config file

Below is a sample section from the Nginx config file, where you can pass atatus api key value to FastCGI with respect to the location in Nginx.

location /app {
  ...
  fastcgi_param PHP_VALUE "atatus.api_key=APP_PROJECT_API_KEY";
  ...
}

location /api {
  ...
  fastcgi_param PHP_VALUE "atatus.api_key=API_PROJECT_API_KEY";
  ...
}
.user.ini file

You should create .user.ini file within your project home folder. A sample file content would be:

atatus.api_key = "PROJECT_API_KEY"
Uninstall PHP Agent

You can uninstall the Atatus PHP agent by running below command. It will remove all agent files from your system.

sudo atatus-php-installer uninstall

After uninstalling the agent, you must restart your web servers (Apache, Nginx, PHP-FPM, etc.)

Enable debug log level

In case if you are facing any issue with PHP APM (e.g. no data is coming, crashing the server, etc), you can enable the debug log level in both agent and collector.

Open your atatus.ini file. You can find the path of atatus.ini file by running php -i | grep atatus.ini command in the shell.

* Change agent log level to verbose_all

atatus.agent.log_level = "verbose_all"

* Change collector log level to debug

atatus.collector.log_level = "debug"

Restart your server and access your server until you reproduce the issue. The debug log messages will be saved in /var/log/atatus/agent.log and /var/log/atatus/collector.log. Please send us an mail with these files to "hello@atatus.com"

Important: Don't forget to change the log_level back to warning after this.
Exception handling in a single PHP file

Atatus captures exceptions automatically in all major PHP frameworks. But it won't capture exceptions during single PHP file execution. e.g php index.php. You have to add following lines at start of your PHP script to capture exceptions.

function exception_handler($ex) {
  if (extension_loaded('atatus')) {
    atatus_notify_exception($ex);
  }
}
set_exception_handler('exception_handler');
Document Sections