Add Custom Timespans to Timeline
There are three APIs to collect additional timespans from your application to feed into the Timeline Profiler.
Additionally you can add dynamic instrumentation for functions from the UI.
#[WithSpan] attribute on functions and methods
Available since Tideways PHP Extension 5.6.4 or later. |
By adding a PHP 8 attribute #[WithSpan]
to a userland function or method you
can directly create a span that represents the function call. This is useful on
functions and methods that are called only a few times each request and signify
which high-level / service-level algorithms take the most time during the
request.
<?php
namespace App\Model;
use Tideways\Profiler\WithSpan;
class RegistrationService
{
#[WithSpan]
public function registerNewUser(array $data): User
{
}
#[WithSpan]
public function sendRegistrationEmail(User $user)
{
}
}
We recommend to put them on services and functions that are called either directly from the controller or just a level below in a service.
Using the attribute is safe even when the "tideways" extension is not installed, because PHP does not require the attribute class to be present. However note that individual frameworks could potentially force the loading of attributes via the autoloader. |
Explicitly create, start and stop timespans
Tideways collects a single root timespan for every request by default. These time spans are used to calculate the response time charts. You can add more spans to a trace that represent SQL, HTTP or any other kind of operation and see a full trace timeline inside the Tideways UI.
This is the code to create spans during PHP requests which you want to trace:
<?php
function insertUser($name) {
// this span represents the insertUser function, being the parent for two sql statements
$span = \Tideways\Profiler::createSpan('php');
$span->annotate(['title' => 'insertUsers']);
try {
$stmt = $pdo->prepare('INSERT INTO users (name) values (?)');
$stmt->bindValue(1, $name);
$stmt->execute();
$id = $pdo->lastInsertId();
$stmt = $pdo->prepare('INSERT INTO users_log (user_id, message, log_date) VALUES (?, ?, NOW())');
$stmt->bindValue(1, $id);
$stmt->bindValue(2, 'User with name ' . $name . ' created.');
$stmt->execute();
} finally {
$span->finish();
}
}
To avoid cluttering your codebase with Tideways Span code you should integrate this deep into your libraries and abstractions for database and HTTP clients.
Annotations are key/value pairs of additional information that we can display in the Tideways UI for each span.
Only the Standard and Pro plans include custom spans. For the Starter and Basic plans you need to use either #[WithSpan] or Profiler::watch() .
|
Watching Function Calls
Sometimes you can’t or want to deeply integrate into a library.
The Tideways extension offers a simple method to wrap spans around function calls by calling the method watch()
:
<?php
\Tideways\Profiler::start();
\Tideways\Profiler::watch('Acme\Library::doSomething');
Watches are only triggered in Tracing mode of Tideways and not in monitoring mode. |
Watching function calls with callback
If you have more special needs there is a more powerful function that allows creating spans using a PHP callback:
<?php
\Tideways\Profiler::start();
\Tideways\Profiler::watchCallback(
'MyTemplateEngine::render',
function($context) {
$span = \Tideways\Profiler::createSpan('view');
$templateName = $context['object']->getTemplateName();
$span->annotate(['title' => $templateName]);
return $span;
}
);
The $context
variable has the following keys:
-
$context['fn']
contains the string of the function being called, in the above exampleMyTemplateEngine::render
. -
$context['object']
is set to the current instance where the method is being called on. -
$context['args']
contains a list of arguments passed to the called function.
Only the Standard and Pro plans include custom spans. For the Starter and Basic plans you need to use either #[WithSpan] or Profiler::watch() .
|
Watches are only triggered in Tracing mode of Tideways and not in monitoring mode. Using a watch callback to set the transaction or service name is therefore not reliable. |