Support matrix

PHP versions

  • 5.2.x
  • 5.3.x
  • 5.4.x
  • 5.5.x
  • 5.6.x
  • 7.0.x

PHP frameworks

  • Drupal
    • version 6.x
    • version 7.x

PHP databases

  • mysql
  • mysqli
  • PDO
  • MongoDB (all versions)
  • PostGreSQL
  • Query privacy: ability to filter literals from MySQL fully supported; Postgres and Oracle “normal” quoting supported.

PHP caches

  • memcache
  • memcached
  • phpredis

Other PHP instrumentation

  • cURL – install optional libcurl instrumentation for multi-exec tracing
  • file_get_contents
  • error_log – for errors of types E_ERROR, E_WARNING, E_USER_ERROR, E_COMPILE_ERROR, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_WARNING, E_USER_WARNING, E_PARSE
  • fopen, file_get_contents, readfile, include, require, copy, file : web resource accesses are tracked

PHP 7 instrumentation: PHP 7 instrumentation is provided as a .so file. See installing binaries manually for the download location and installation instructions.

Minimum version required: From php instrumentation version 1.5.4 onwards, liboboe 1.2.1 or greater is required. This will be taken care of automatically by the php-oboe package dependency when installing instrumentation from packages. But when manually installing php instrumentation via the downloadable .so—which will be the case when instrumenting php 7, you’ll need to manually ensure liboboe is version 1.2.1 or greater. Follow the Tracelyzer upgrade instructions to check the current version and upgrade if necessary.

When you install language level instrumentation, here are the things you should be thinking about: first, install the instrumentation. Then, go back to your TraceView and take a look at your traces. Are you getting the level of detail you need? If you’re not getting a sufficient level of detail from out-of-box instrumented php, then you’ll want to consider configuration options.

Installing instrumentation

The TraceView php instrumentation is distributed as a native package for your distro or as a binary you can manually install. If your installation of php was provided as an official package from your operating system, then you can use your package manager to install php-oboe automatically. If you’ve installed php from source or via cpanel, you’ll need to manually install the module.

Installing from packages

  1. If your php installation was provided as an official package for your distro, then you can use your package manager to install php-oboe.
  2. Restart php. Usually this is accomplished by restarting the web server.
  3. Instrumentation customization API relies on methods defined in the extension. In order to make your code safe to run in all environments, you’ll want to include the api.php stub file in your code. Using that, any instrumentation calls that you add will simply do nothing if the oboe extension is not installed.

     # on debian/ubuntu
     sudo apt-get install php-oboe
     # on rhel/centos
     sudo yum install php-oboe
    

Installing binaries manually

  1. Find the .so for your php version on files.tv.solarwinds.com/php. You can discover your php API number (20151012, 20050922, 20060613, 20090626, or 20100525) by running php -i or phpinfo() and looking for ‘php extension build’. Only install the +zts version of the .so if your server is using a zend thread safety version of php.
  2. Download the appropriate .so file, change its name to ‘oboe.so’, and place it in your extensions directory. If you’re not sure where that is, you can find out by running php-config –extension-dir.
  3. Edit your php configs to load the module. You’ll need to add extension=oboe.so wherever you are loading your extensions—usually in php.ini.
  4. Restart php. For mod_php this is done by restarting apache. If php is running standalone restart php-fpm/cgi.

Upgrading instrumentation

rhel/centos

  1. To check for updates to our instrumented php-oboe package run:

     yum info php-oboe
    
  2. Pending releases will be listed under an ‘available packages’ heading. If you don’t see this you’re all up to date! If you there is a new version available it can be upgraded by running:

     yum -y update php-oboe
    

debian/ubuntu

  1. To check for updates to our instrumented php-oboe package run:

     apt-get update $ apt-cache policy php-oboe
    
  2. If the displayed latest version matches the current candidate version you’re all up to date! If there is a new version available it can be upgraded by running:

     apt-get install --only-upgrade php-oboe
    

Configuring instrumentation

The configuration files used by php can be listed by running php –ini. Note that this will give the command-line-specific files on some distributions, denoted by /cli/; web systems on the other hand use the /cgi/ configs. For most platforms, you’ll find an oboe.ini configuration file after installing the instrumentation module.

Report backtraces

All public API methods have a backtrace parameter, which is set to ‘true’ by default.

Suppress reporting for sensitive data

PHP instrumentation has the ability to sanitize sql database queries in case you don’t want query parameters displayed in your account. By default this functionality is disabled, but you can use the sanitize_sql flag to configure the instrumentation to stop collecting and reporting query parameters.

oboe.enable_sanitize_sql = 1

Trace command-line or cronjob php

PHP uses separate configuration files for web-based requests and command-line/cron jobs. By default, our instrumentation only traces web-based requests. However, it’s easy to enable for CLI jobs as well. Simply change oboe.tracing to ‘always’ in your command line config, usually /etc/php5/cli/conf.d/oboe.ini.

oboe.tracing = always

Complete config options

The following is the complete list of php instrumentation configuration options.


    oboe.tracing

    config option
    oboe.tracing
    description
    Specify when traces should be initiated for incoming requests. This should be set to ‘always’ when you don’t have an instrumented webserver in front of your app.
    possible values
    always
    Continue existing traces, otherwise attempt to start a new one.
    through
    (Default) Continue existing traces, but never start them. This mode assumes that a higher layer makes the decision about whether to trace.
    never
    Never continue existing traces or start new ones.
    history
    Introduced with the original instrumentation.
    example
    oboe.tracing = through

    oboe.enable_sanitize_sql

    config option
    oboe.enable_sanitize_sql
    description
    Instrumentation has the ability to sanitize query literals from sql statements. By default this is disabled. Set to one of the other options to avoid collecting and reporting query literals to TraceView.
    possible values
    0
    (Default) Disable SQL sanitizing.
    1
    Enable SQL sanitizing and attempt to automatically determine which quoting form is used.
    2
    Enable SQL sanitizing and drop double quoted characters.
    4
    enable SQL sanitizing and retain double quoted characters.
    history
    Introduced in version 0.4.7.
    example
    oboe.enable_sanitize_sql = 0

    oboe.enable_error_callback

    config option
    oboe.enable_error_callback
    description
    By default the extension reports all errors to TraceView, obeys the ‘@’ suppression operator, and uses the oboe default error reporting level. To direct php-oboe not to send any error data at all to TraceView set this ini directive to 0.
    possible values
    0
    Disable error reporting.
    1
    (Default) Report all errors to TraceView.
    history
    Introduced in version 1.3.2.
    example
    oboe.enable_error_callback = 0

    oboe.report_suppressed_errors

    config option
    oboe.report_suppressed_errors
    description
    PHP features the @ operator which overrides the global error reporting settings and suppresses errors for any expression it precedes. By default php-oboe also ignores these suppressed errors. To report them—as long as they occur at the current error reporting level—set the following ini directive to 1.
    possible values
    0
    (Default) Honor the @ operator, which suppresses errors.
    1
    Report suppressed errors.
    history
    Introduced in version 1.3.2.
    example
    oboe.report_suppressed_errors = 1

    oboe.use_error_reporting

    config option
    oboe.use_error_reporting
    description
    PHP error reporting levels are controlled in two ways, by altering the error_reporting directive in php ini files, or at run time via the error_reporting() function. By default these have no effect on how php-oboe reports errors to TraceView. By default php-oboe reports all errors except E_STRICT and E_DEPRECATED, regardless of the aforementioned settings that your application honors. To make php-oboe follow the same error reporting settings as your app set the following ini directive to 1.
    possible values
    0
    (Default) Report all errors except E_STRICT and E_DEPRECATED.
    1
    Follow the same error reporting settings as your app.
    history
    Introduced in version 1.3.2.
    example
    oboe.use_error_reporting = 1

    oboe.enable_wrap_error_log

    config option
    oboe.enable_wrap_error_log
    description
    Completely aside from the level of error reporting in php or php-oboe, php also offers a logging function called error_log(), which can be used to write arbitrary log data to a file. By default php-oboe reports these lines of log text to TraceView. To disable this set the following ini directive to 0.
    possible values
    0
    Do not report logging text generated by error_log().
    1
    (Default) Report logging text generated by error_log().
    history
    Introduced in version 1.3.2.
    example
    oboe.enable_wrap_error_log = 0

    oboe.enable_drupal_tracing

    config option
    oboe.enable_drupal_tracing
    description
    Enable/disable tracing for drupal.
    possible values
    0 (disable), 1 (enable). Default: 1.
    history
    Introduced in version 2.0.0.
    example
    oboe.enable_drupal_tracing = 1

    oboe.enable_drupal_profiling


    oboe.enable_drupal_profiling

    config option
    oboe.enable_drupal_profiling
    description
    Enable/disable function profiling of views and panels.
    possible values
    0 (disable), 1 (enable). Default: 0.
    history
    Introduced in version 2.0.0.
    example
    oboe.enable_drupal_profiling = 0
    related configs
    oboe.enable_drupal_tracing

    Customizing instrumentation

    Customization involves adding hooks from our public API to your code so that you can to take advantage of additional filtering capabilities on the dashboard, change how requests are traced, or capture additional information during the trace.

    PHP custom layers

    By default, the php instrumentation creates a ‘php’ layer, and then creates a layer for each non-php service that it is instrumenting, e.g., php_mysql, memcache, phpredis, curl. If these layers don’t provide enough visibility, you can further divide your code into sub-layers. How you segment your application into layers is entirely up to you. For example the out-of-box instrumentation might not recognize calls to external processes; or, maybe there’s a discrete subsection of your code that is worth calling out on its own. In any case, a layer is started by calling oboe_log_entry() and ended by calling oboe_log_exit(). Follow the links to the API documentation for complete syntax and usage information.

    1 oboe_log_entry('sayhello');
    2 ...
    3 oboe_log_exit('sayhello');

    PHP function profiling

    For most situations where you want to analyze a specific region of code, it will be easiest and more informative to use our function profiling interface. The alternative is custom layers, which should generally be reserved for calls to external services that our instrumentation would not normally recognize as needing their own layer.

    Function profiles allows you to drill down on the performance of specific regions of code within the language layers of your apps, seeing how often they are hit, in what calls and traces, and how long they take.

    Adding profiling information to php functions requires using the oboe_log function to manually report specific keys. Follow the link to the API documentation for complete syntax and usage information.

    1 oboe_log(NULL, 'profile_entry', array('ProfileName' => 'this_code_block', 'Language' => 'PHP')); 
    2 ...
    3 oboe_log(NULL, 'profile_exit', array('ProfileName' => 'this_code_block', 'Language' => 'PHP'));

    Add info events

    There are two reasons you might want to create an info event: the first is to simply to attach any metadata that may be of interest to you during later analysis of a trace. The other reason is to take full advantage of TraceView filtering capability. In short, you can classify extents by attaching a pre-defined set of specified key/value pairs as a third parameter. Then from TraceView, you can filter for traces with that extent type. See special interpretation, for more on this.

    To add info to an extent, call oboe_log anywhere within it, as shown. You may do this at multiple points if necessary. The information events are displayed on the raw span data tab on the trace details page. If all of the key/value pairs for special interpretation are present, the extent type is reflected in the span details tab. Follow the link to the API documentation for complete syntax and usage information.

    1 oboe_log('layer-name', 'info', array('key' => $variable));

    PHP partitions

    With hundreds of traces flowing into TraceView, you need a way to keep them organized. For this, TraceView provides ‘partitions’, a programmatic way of classifying traces. For example, you can place traces into the following classes: anonymous, authenticated, and administrator. In TraceView, partitions appear as a filter on the same level as urls and controller/action pairs, so in this example you could choose to limit the display to just requests of authenticated users. Traces are not assigned to any partition by default, and you are free to partition requests however you need to feel that your app is logically arranged. To assign a trace to a partition, just fire an info event anywhere within the trace and attach the partition key/value pair. Partition names may have a maximum length of 40 characters, anything longer is truncated to 40. They’re also limited to alphanumeric characters, or underscores. Any characters that don’t fit this criteria are silently converted to underscores. Follow the link to the API documentation for complete syntax and usage information.

    1 oboe_log(null, 'info', array( 'Partition' => 'your_partition_name'));

    PHP controllers filter

    PHP instrumentation supports these frameworks. If we don’t support your framework add controller/action instrumentation by reporting an info event with the ‘controller’ and ‘action’ keys. Even if your framework doesn’t have a conventional notion of controllers and actions, you can still take advantage of this filtering capability by simply attaching whatever values that make sense to you.

    1 oboe_log ('info', array( 'Controller' => 'your_controller', 'Action' => 'do_something'));

    Report errors and exceptions

    Errors automatically generate error events in a trace if the oboe.enable_error_callback ini setting is not set to zero. When enabled, the default error handling is further configured by the oboe.report_suppressed_errors and oboe.use_error_reporting ini settings. If you disable the default oboe error callback handler then you’re probably providing your own error handler. Whatever the case, if you want to manually record an error in a trace then you’ll need to call oboe_log_error() as shown, where ‘E_NOTICE’ is the php error code. Follow the link to the API documentation for complete syntax and usage information.

    1 oboe_log_error('layer-name', 'something is wrong', E_NOTICE);

    Like errors, exceptions are automatically recorded in a trace if the oboe.enable_error_callback ini setting is not set to zero. Otherwise you’ll need to manually create an exception error event using a call to oboe_log_exception(). Here the exception object is passed instead of an error message key values have been added in a hash table. A stack trace is also explicitly passed the stack trace from the exception object so that it doesn’t create a stack trace from the exception handler.

    1 oboe_log_exception('myexcept', $e, array('test' => 'tripleInteger($int)', 'result' => 'InvalidArgumentException generated'), $e->getTrace());

    Add CodeIgniter instrumentation

    Controller and action information for the CodeIgniter framework can be collected by adding a hook to your app.

    1. Enable hooks in application/config/config.php by adding the following line.

      $config['enable_hooks'] = TRUE;
      
    2. Add the following content to a new file called tracelytics.php to the hooks directory system/application/hooks/.

      <?php if (!defined('BASEPATH')) exit('No direct script access allowed');
      // Retrieve the codeigniter class and method used for this request and log it to traceview
      class TraceViewHooks {
          public function post_controller() {
              if (is_callable('oboe_log')) {
                  $CI =& get_instance();
                  oboe_log(null, "info", array(
               	   "Controller" => $CI->router->class,
               	   "Action" => $CI->router->method
               	   ));
              }
          }
      }
      ?>
      
    3. Add the hook definition to system/application/config/hooks.php.

      $hook['post_controller'] = array(
          'class'    => 'TraceViewHooks',
          'function' => 'post_controller',
          'filename' => 'tracelytics.php',
          'filepath' => 'hooks'
          );
      

    Add kohana 2.x instrumentation

    Controller and action information for the kohana framework can be collected by adding a hook to your app.

    1. Enable hooks in application/config/config.php by adding the following line, which enables all hooks in the application/hooks directory.

      $config['enable_hooks'] = TRUE;
      
    2. Add a new file called tracelytics to the application/hooks/ directory, and paste in the following contents.

      <?php 
      if (! class_exists ('TraceViewCallbacks', false)) {
          class TraceViewCallbacks {
              function addControllerAction() {
                  $info = array('Controller' =&gt; router::$controller,
                      'Action' =&gt; router::$method,
                      'Partition' =&gt; defined('APPLICATION_NAME') ? APPLICATION_NAME : '' );
                  if (function_exists('oboe_log')) {
                      oboe_log('info', $info);
                  }
                  // print_r($info);
              }
          } 
          Event::add('system.post_routing', array('TraceViewCallbacks', 'addControllerAction'));
      } 
      ?>
      </pre>
      

    Add kohana 3.0 instrumentation

    In this version of kohana, bootstrap.php wraps the execution of the request. Look for the block of code that calls Request::instance(), and add our hook before it.

     1 if ( ! defined('SUPPRESS_REQUEST'))
     2 {
     3 	/**
     4 	* Register the controller and action with tracelytics, if it exists.
     5 	*/
     6 	$request = Request::instance();
     7 	$info = array('HTTP-Host' => $_SERVER['HTTP_HOST'],
     8 	   'URL' => '/' . Request::instance()-&gt;uri,
     9 	   'Method' => $_SERVER['REQUEST_METHOD'],
    10 	   'Controller' => $request-&gt;controller,
    11 	   'Action' => $request-&gt;action);
    12 	if (function_exists('oboe_log')) {
    13 	   oboe_log('info', $info);
    14 	}
    15 	/**
    16 	* Execute the main request. A source of the URI can be passed, eg: $_SERVER['PATH_INFO'].
    17 	* If no source is specified, the URI will be automatically detected.
    18 	*/
    19 	echo Request::instance()
    20 	->execute()
    21 	->send_headers()
    22 	->response;
    23 }

    Add kohana 3.1+ instrumentation

    In this version of kohana, index.php controls the execution of the environment. Append the following to index.php. Note that they must happen after the request itself.

    1 $controller = Request::initial()->controller();
    2 $action = Request::initial()->action();
    3 if (function_exists('oboe_log')) {
    4 	oboe_log('info', array(
    5 		'Controller' => $controller,
    6 		'Action' => $action
    7 		));
    8 }

    Add zend instrumentation

    You can extend your zend app to collect controller and action information by adding the following to bootstrap.php.

     1 class TraceView_Logging_Plugin extends Zend_Controller_Plugin_Abstract
     2 {
     3 	public function preDispatch()
     4 	{
     5 		$request = Zend_Controller_Front::getInstance()->getRequest();
     6 		$controller = $request->getControllerName();
     7 		$action = $request->getActionName();
     8 		if (function_exists('oboe_log')) {
     9 			oboe_log('info', array(
    10 				'Controller' => $controller,
    11 				'Action' => $action
    12 				));
    13 		}
    14 	}
    15 }
    16 $front = Zend_Controller_Front::getInstance();
    17 $front->registerPlugin(new Traceltyics_Logging_Plugin());

    Add wordpress instrumentation

    To get some basic controller/action data from wordpress you’ll need to add one line to the following files in your current theme: archive.php, index.php, page.php, and single.php. In each file, find the line <?php get_footer(); ?>, and add just below it the matching line from below.

    1 <?php if (extension_loaded("oboe")) { oboe_log("info", array("Controller" => "wordpress", "Action" => "archive")); }?>
    2 <?php if (extension_loaded("oboe")) { oboe_log("info", array("Controller" => "wordpress", "Action" => "index")); }?>
    3 <?php if (extension_loaded("oboe")) { oboe_log("info", array("Controller" => "wordpress", "Action" => "page")); }?>
    4 <?php if (extension_loaded("oboe")) { oboe_log("info", array("Controller" => "wordpress", "Action" => "single")); }?>

    Add drupal instrumentation

    Our php module provides instrumentation for drupal 6 and 7 natively, and drupal tracing is enabled by default. This instrumentation offers the same capability and should supplant the legacy TraceView drupal module. This means that standard rum, partitioning, and controller/actions are available and configured in the same way as you would for any other php app. An additional config is required to profile layers and panels.

    Drupal 6 expected extents

    • entry-exit (enable_drupal_profiling = 0)
      • drupal_hook_init
      • drupal_hook_exit
      • drupal_hook_footer
      • drupal_hook_boot
      • drupal_hook_form_alter
      • drupal_hook_node_load
      • drupal_views
      • drupal_panels
    • profile entry-exit (enable_drupal_profiling = 1)
      • views
        • pre_build
        • post_build
        • pre_execute
        • post_execute
        • pre_render
        • post_render
      • panels
        • pre_render
        • post_render

    Drupal 7 expected extents

    • entry-exit (enable_drupal_profiling = 0)
      • drupal_hook_init
      • drupal_hook_exit
      • drupal_hook_boot
      • drupal_hook_form_alter
      • drupal_page_callback
      • drupal_http_request
      • drupal_views
      • drupal_panels
    • profile entry-exit (enable_drupal_profiling = 1)
      • views
      • pre_build
      • post_build
      • pre_execute
      • post_execute
      • pre_render
      • post_render
    • panels
      • pre_render
      • post_render

    Add php data objects instrumentation

    PDO instrumentation enables you to collect performance data relating to query and database usage in php applications.

    1. Explicitly enable the pdo instrumentation by adding this line to your php.ini settings. Alternatively, you might find it more convenient to add this line to the oboe-specific ini settings, which are in oboe.ini. On debian/ubuntu oboe.ini is in /etc/php5/conf.d/; on rhel/centos it’s in /etc/php.d/.

      oboe.enable_wrap_pdo = 1
      
    2. Verify that this ini value has been successfully set, you can run php -i or call phpinfo().

    PHP API reference

    See this gist.

    Real user monitoring for php

    Do you have an instrumented webserver? These instructions involve enabling RUM via your page template files. If apache or nginx sits in front of your app, you don’t need to enable RUM here. It’s already provided at the web server level via our auto-rum support.

    TraceView provides optional javascript-based client-side performance data via real user monitoring (RUM). In order to gather real user timing data from the browser, you’ll need to insert two scripts into your page templates via helper methods that automatically generate the required javascript.

    1. Insert the results of oboe_get_rum_header() just after any <meta> tags in your <head> block. It should be the first non-meta tag inside <head>.
    2. Insert the results of oboe_get_rum_footer() immediately before the closing _</body> tag.
     1 <head>
     2 <meta ... >
     3 <?php if (extension_loaded("oboe")) { echo oboe_get_rum_header(); } ?>
     4 ...
     5 </head>
     6 
     7 <body>
     8 ...
     9 <?php if (extension_loaded("oboe")) { echo oboe_get_rum_footer(); } ?>
    10 </body>