Vegas CMF Guide

Profiler library

This is a module to vegas-cmf-core which provides various so-called data collectors.
Each of data collectors is attached to specific events to grab data about the request. After the request, the information collected is stored inside a temporary file.
Finally, an AJAX call is triggered which retrieves the data, unlinks the file and renders appropriate information.

Requirements

Profiler module relies on vegas-cmf-core lib. Requires php 5.4+ with phalcon 1.3.x installed as well.
Library consists only the backend of the profiler - all event listeners & data collectors.
Developers need to provide custom frontend implementation. By default it works only in non-production environments.

Installation

Add vegas-cmf-profiler to your composer.json. Run:
php composer.phar update

Copy /vegas-cmf/profiler/assets from your composer vendor to your project public directory.

If you have vegas-cmf-core with CLI installed, you can copy those files automaticaly by using command:
php /path/to/cli.php vegas:assets publish

Setup

First we need to enter profiler module inside dependency injection container. Add following code into app/config/config.php file:

return [
    // other application settings
    // ...

    'profiler'  => [
        // Put all used profiler classes here
        '\Vegas\Profiler\DataCollector\Time',
        '\Vegas\Profiler\DataCollector\Components',
        '\Vegas\Profiler\DataCollector\Exception',
        '\Vegas\Profiler\DataCollector\Memory',
        '\Vegas\Profiler\DataCollector\Query',
        '\Vegas\Profiler\DataCollector\Request',
        '\Vegas\Profiler\DataCollector\Response',
        '\Vegas\Profiler\DataCollector\Superglobals',
    ]
];

... and following to the app/Bootstrap.php file:


use Vegas\Profiler\Manager as ProfilerManager;
use Vegas\Profiler\DataCollector\DataCollectorInterface as ProfilerDataCollector;

// ...

public function setup()
{
    parent::setup();
    $this->initProfiler();

    return $this;
}

// ...

protected function initProfiler()
{
    if (isset($this->config->profiler)) {
        $dataCollectors = (array)$this->config->profiler;
    } else {
        $dataCollectors = [];
    }

    $di = $this->di;
    $di->set(ProfilerDataCollector::DI_NAME, function() use ($di) {
        return (new ProfilerManager)
            ->setEventsManager($di->getShared('eventsManager'));
    }, true);
    $di->get(ProfilerDataCollector::DI_NAME)->enable($dataCollectors);
}

After successful installation, we need to provide frontend module.
The module should be named, of course, Profiler which is the default. See \Vegas\Profiler\Manager constructor.
This is in order to prevent looping the dumpfile procedure. Perhaps in the future there will be introduced a better solution for this.
Instructions below show how to create a sample profiler which dumps information about the previous request inside a table at the bottom of the page.
The module needs only one action. In this description we assume it will be show action inside frontend section.

  1. Create a module named Profiler with standard directory structure:
    Profiler
    ├── config
    |   ├── config.php
    |   └── routes.php
    ├── controllers
    |   └── frontend
    |       └── ProfilerController.php
    ├── views
    |   └── frontend
    |       └── profiler
    |           └── show.php
    └── Module.php
    
  2. Fill controller with following code:
    namespace Profiler\Controllers\Frontend;
    
    use Vegas\Mvc\Controller\ControllerAbstract,
        Vegas\Profiler\DataCollector\DataCollectorInterface as ProfilerDataCollector,
        Vegas\Mvc\View;
    
    class ProfilerController extends ControllerAbstract
    {
        public function showAction($requestId)
        {
            $this->request->isAjax() && $this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
            $data = $this->di->getShared(ProfilerDataCollector::DI_NAME)->getData($requestId);
            // $data is just an associative array of data collected by profilers
            $this->view->setVar('profiler', $data);
        }
    }
    
  3. Fill show.php with following code:
    <table class="table table-bordered table-hover">
        <thead>
            <tr>
                <th>Profiler</th>
                <th class="options">Data collected</th>
            </tr>
        </thead>
        <tbody>
        {% for name, data in profiler %}
        <tr>
            <td>{{ name }}</td>
            <td class="options">{{ dump(data) }}</td>
        </tr>
        {% endfor %}
        </tbody>
    </table>
    
  4. Add appropriate route inside routes.php:
    return [
        'profiler' => [
            'route' => '/profiler/{requestId}',
            'paths' => [
                'module' => 'Profiler',
                'controller' => 'Frontend\Profiler',
                'action' => 'show'
            ],
            'params' => []
        ],
    ];
    
  5. Create a partial view profiler.volt inside app/layouts/partials dir using newly created route:
    <div id="vegas-profiler" data-request="{{ profilerRequestId }}"></div>
    
    <script type="text/javascript">
        $(document).ready(function(){
            var profilerUrl = "{{ url.get(['for':'profiler', 'requestId':'__REQ__']) }}"
                    .replace(/__REQ__/, $('#vegas-profiler').data('request'));
            
            $('#vegas-profiler').load(profilerUrl);
        });
    </script>
    
  6. Finally, include the partial inside our layout file at the bottom of body section:
    {{ partial('../../../layouts/partials/profiler') }}