Example #1
0
 /**
  * Start production profiling for the application.
  *
  * There are three modes for profiling:
  *
  * 1. Wall-time only profiling of the complete request (no overhead)
  * 2. Full profile/trace using xhprof (depending of # function calls
  *    significant overhead)
  * 3. Whitelist-profiling mode only interesting functions.
  *    (5-40% overhead, requires custom xhprof version >= 0.95)
  *
  * Decisions to profile are made based on a sample-rate and random picks.
  * You can influence the sample rate and pick a value that suites your
  * application. Applications with lower request rates need a much higher
  * transaction rate (25-50%) than applications with high load (<= 1%).
  *
  * Factors that influence sample rate:
  *
  * 1. Second parameter $sampleRate to start() method.
  * 2. _qprofiler Query Parameter (string key is deprecated or array)
  * 3. Cookie TIDEWAYS_SESSION
  * 4. TIDEWAYS_SAMPLERATE environment variable.
  *
  * start() automatically invokes a register shutdown handler that stops and
  * transmits the profiling data to the local daemon for further processing.
  *
  * @param array|string      $options Either options array or api key (when string)
  * @param int               $sampleRate Deprecated, use "sample_rate" key in options instead.
  *
  * @return void
  */
 public static function start($options = array(), $sampleRate = null)
 {
     if (self::$mode !== self::MODE_NONE) {
         return;
     }
     if (!is_array($options)) {
         $options = array('api_key' => $options);
     }
     if ($sampleRate !== null) {
         $options['sample_rate'] = $sampleRate;
     }
     $defaults = array('api_key' => isset($_SERVER['TIDEWAYS_APIKEY']) ? $_SERVER['TIDEWAYS_APIKEY'] : ini_get("tideways.api_key"), 'sample_rate' => isset($_SERVER['TIDEWAYS_SAMPLERATE']) ? intval($_SERVER['TIDEWAYS_SAMPLERATE']) : ini_get("tideways.sample_rate"), 'collect' => isset($_SERVER['TIDEWAYS_COLLECT']) ? $_SERVER['TIDEWAYS_COLLECT'] : (ini_get("tideways.collect") ?: self::MODE_TRACING), 'monitor' => isset($_SERVER['TIDEWAYS_MONITOR']) ? $_SERVER['TIDEWAYS_MONITOR'] : (ini_get("tideways.monitor") ?: self::MODE_BASIC), 'distributed_tracing_hosts' => isset($_SERVER['TIDEWAYS_ALLOWED_HOSTS']) ? $_SERVER['TIDEWAYS_ALLOWED_HOSTS'] : (ini_get("tideways.distributed_tracing_hosts") ?: '127.0.0.1'), 'distributed_trace' => null);
     $options = array_merge($defaults, $options);
     if (strlen((string) $options['api_key']) === 0) {
         return;
     }
     self::init($options['api_key'], $options['distributed_trace'], $options['distributed_tracing_hosts']);
     self::$mode = self::decideProfiling($options['sample_rate'], $options);
     if (self::$extension === self::EXTENSION_TIDEWAYS) {
         switch (self::$mode) {
             case self::MODE_FULL:
                 $flags = 0;
                 break;
             case self::MODE_PROFILING:
                 $flags = TIDEWAYS_FLAGS_NO_SPANS;
                 break;
             case self::MODE_TRACING:
                 $flags = TIDEWAYS_FLAGS_NO_HIERACHICAL;
                 break;
             default:
                 $flags = TIDEWAYS_FLAGS_NO_COMPILE | TIDEWAYS_FLAGS_NO_USERLAND | TIDEWAYS_FLAGS_NO_BUILTINS;
                 break;
         }
         self::$currentRootSpan = new \Tideways\Traces\TwExtensionSpan(0);
         tideways_enable($flags, self::$defaultOptions);
         if (($flags & TIDEWAYS_FLAGS_NO_SPANS) === 0) {
             foreach (self::$defaultOptions['watches'] as $watch => $category) {
                 tideways_span_watch($watch, $category);
             }
             foreach (self::$defaultOptions['callbacks'] as $function => $callback) {
                 tideways_span_callback($function, $callback);
             }
         }
     } elseif (self::$extension === self::EXTENSION_XHPROF && (self::$mode & self::MODE_PROFILING) > 0) {
         \Tideways\Traces\PhpSpan::clear();
         self::$currentRootSpan = new \Tideways\Traces\PhpSpan(0, 'app');
         self::$currentRootSpan->startTimer();
         xhprof_enable(0, self::$defaultOptions);
     } else {
         \Tideways\Traces\PhpSpan::clear();
         self::$currentRootSpan = new \Tideways\Traces\PhpSpan(0, 'app');
         self::$currentRootSpan->startTimer();
     }
 }
Example #2
0
 /**
  * Enable the profiler in the given $mode.
  *
  * @param string $mode
  * @return void
  */
 private static function enableProfiler($mode)
 {
     self::$mode = $mode;
     if (self::$extension === self::EXTENSION_TIDEWAYS && self::$mode !== self::MODE_NONE) {
         switch (self::$mode) {
             case self::MODE_FULL:
                 $flags = 0;
                 break;
             case self::MODE_PROFILING:
                 $flags = TIDEWAYS_FLAGS_NO_SPANS;
                 break;
             case self::MODE_TRACING:
                 $flags = TIDEWAYS_FLAGS_NO_HIERACHICAL;
                 break;
             default:
                 $flags = TIDEWAYS_FLAGS_NO_COMPILE | TIDEWAYS_FLAGS_NO_USERLAND | TIDEWAYS_FLAGS_NO_BUILTINS;
                 break;
         }
         self::$currentRootSpan = new \Tideways\Traces\TwExtensionSpan(0);
         tideways_enable($flags, self::$defaultOptions);
         if (($flags & TIDEWAYS_FLAGS_NO_SPANS) === 0) {
             foreach (self::$defaultOptions['watches'] as $watch => $category) {
                 tideways_span_watch($watch, $category);
             }
             foreach (self::$defaultOptions['callbacks'] as $function => $callback) {
                 tideways_span_callback($function, $callback);
             }
         }
         self::log(2, "Starting tideways extension for " . self::$trace['apiKey'] . " with mode: " . $mode);
     } elseif (self::$extension === self::EXTENSION_XHPROF && (self::$mode & self::MODE_PROFILING) > 0) {
         \Tideways\Traces\PhpSpan::clear();
         self::$currentRootSpan = new \Tideways\Traces\PhpSpan(0, 'app');
         self::$currentRootSpan->startTimer();
         xhprof_enable(0, self::$defaultOptions);
         self::log(2, "Starting xhprof extension for " . self::$trace['apiKey'] . " with mode: " . $mode);
     } else {
         \Tideways\Traces\PhpSpan::clear();
         self::$currentRootSpan = new \Tideways\Traces\PhpSpan(0, 'app');
         self::$currentRootSpan->startTimer();
         self::log(2, "Starting non-extension based tracing for " . self::$trace['apiKey'] . " with mode: " . $mode);
     }
 }