Edson Horacio Junior
Edson Horacio Junior

Reputation: 3143

Show ZF2 request execution time

I want to print in every page of my site, which is in ZF2, the request execution time.

I have already defined a constant within the index.php (which is the first file the request access) with the request initial microtime(true).
Now, where should I get the request final microtime(true)?

My plan is to have something like this:

$executionTime = ($finalTime - $initialTime) / 1000000; // in seconds
$executionTime = number_format($executionTime, 2);

Upvotes: 1

Views: 537

Answers (5)

Alexander Goncharov
Alexander Goncharov

Reputation: 1662

You can capture time to variable in index.php and then use register_shutdown_function to print time difference between:

index.php

define('APP_START_TIME', microtime(true));

register_shutdown_function(function(){
 echo 'Request time(sec): ' . number_format(microtime(true) - APP_START_TIME, 3);
});

Upvotes: 0

Edson Horacio Junior
Edson Horacio Junior

Reputation: 3143

My solution is based on this answer.

Every view of mine has a footer.phtml attached to it, so if I print it there, there will be no need to change many files.

To print the time there, first I wrote something specific to that footer.phtml, for example Execution time:

Than in module/Application/Module.php I added this code to onBootstrap()

$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_FINISH, function($e) {
    $time = microtime(true) - REQUEST_MICROTIME;

    // formatting time to be more friendly
    if ($time <= 60) {
        $timeF = number_format($time, 2, ',', '.').'s'; // conversion to seconds

    } else {
        $resto  = fmod($time, 60);
        $minuto = number_format($time / 60, 0);
        $timeF = sprintf('%dm%02ds', $minuto, $resto); // conversion to minutes and seconds
    }

    // Search static content and replace for execution time
    $response = $e->getResponse();
    $response->setContent(str_replace(
        'Execution time:', 'Execution time: '.$timeF, $response->getContent()));

}, 100000);

Upvotes: 0

tasmaniski
tasmaniski

Reputation: 4898

If you want to be a really dirty, add in your index.php file at beginning:

$_GET['the_time'] = round(microtime(true) * 1000);

Wherever you want in the view or layout print:

echo round(microtime(true) * 1000) - $_GET['the_time'];
// Use $_GET as global variable 

Note: The rest of developers will probably hate you.

Upvotes: 0

Wilt
Wilt

Reputation: 44383

The problem is that you probably want to add this information to the view (so the user can see it) which would mean adding the time before you render the view (before MvcEvent::EVENT_RENDER). The problem is though that the view is rendered way before MvcEvent::EVENT_FINISH is triggered so the time would not be accurate. This won't be easy to solve...


You could consider adding some time related header inside your response. Here an interesting related question about adding your custom headers.

  • There is for example a $request_time variable for NGinx which you could use out-of-the-box:

    $request_time
    request processing time in seconds with a milliseconds resolution (1.3.9, 1.2.6); time elapsed since the first bytes were read from the client

    add_header X-Request-Time $request_time always;
    
  • There is also an Age response header field. You can find it here in the Header Field Definitions section 14.6 in RFC2616.

    The Age response-header field conveys the sender's estimate of the amount of time since the response (or its revalidation) was generated at the origin server. A cached response is "fresh" if its age does not exceed its freshness lifetime. Age values are calculated as specified in section 13.2.3.

    Maybe you could use it to calculate the time it took to process the request on the server.

You could also add a custom header in your ZF2 application by adding some code to your Module.php like this:

function onBootstrap(MvcEvent $event) {
    $application = $event->getApplication();
    $eventManager = $application->getEventManager();
    $eventManager->attach(MvcEvent::EVENT_FINISH, [$this, 'addTimeHeader']);

    //...
}

function addTimeHeader(MvcEvent $event) {
    $time = // get your time value
    $response = $event->getResponse();
    $response->getHeaders()->addHeaderLine('X-Request-Time', $time);
}

The issue will still be to get this data inside your view. If you use an AJAX request it will be easy to get the header from the response, but if you don't use AJAX it is a whole different story. Read more here in this answer.

Upvotes: 3

marcosh
marcosh

Reputation: 9008

To achieve what you ask, and some more, in a development environment, you could use the Zend Developer Tools modules, which will automatically give you some informations regarding your application.

In a production environment, you could instead listen to the MvcEvent::EVENT_FINISH, that is the last event emitted by the Zend framework MVC

Upvotes: 2

Related Questions