z-ray: a customizable development tool belt (zendcon 2016)
TRANSCRIPT
Zend Z-RayA Customizable PHP Development Toolbelt
2
Mathew Beane @aepod
Director of Systems Engineering - RobofirmZend Z-Team Volunteer – Magento Division
Family member – 3 Kids and a WifeMagento Master & Certified Developer
• Live debugging tool• Browser toolbar interface• Built into Zend Server• Display tons of under the hood details
Page Request Errors and Warnings Database Queries Functions
• Fully extensible – Write your own plugins
Zend Z-Ray
• Built into Zend Server – since version 7 http://www.zend.com/en/products/server/downloads
• Available as a separate download: http://www.zend.com/en/products/z-ray/z-ray-preview
• AWS Zend Server:http://www.zend.com/en/solutions/cloud-solutions/amazon-web-services-free-trial
• Docker Zend Server:https://hub.docker.com/_/php-zendserver/
• Demo Z-Ray:http://www.zend.com/en/products/server/z-ray-use-cases
How To Get Z-Ray
Z-RayA quick walkthrough
General Z-Ray Information – Response Overview
• Page Response Code / Response Times• Shows the number of DB queries on a response
A good un-cached response
A typical bad response
General Z-Ray Information - Statistics
• Execution Times• Overall Peak Memory Usage
A product page from a troubled Magento installation. Very high memory usage and slow response is evident from the statistics panel.
• Zend Server Events Configured in Zend Server Per error type configuration Can be set to do automatic Zend Server code traces
General Z-Ray Information – Monitor Events
• Errors and warnings at a glance• More detailed information than the default handler
General Z-Ray Information – Errors & Warnings
• Back trace of exceptions with more detailed information
General Z-Ray Information – Errors & Warnings
• See all information about every query. Order response called them in Full Query Time Rows Returned Result
• Sort and search in any field• See database back traces for every query
General Z-Ray Information - SQL Tab
Postgres, MariaDB and other Databases tabs available via plugins.
• Realtime Sortable/Searchable PHP function list• Great for exploring the real inner workings of the application• Easy to spot problems and can lead you to the solutions
General Z-Ray Information – Functions Tab
• PHP Super Global List: Includes all the data, can be very useful.• Request Headers: You have this in chrome, but its nice to see what PHP sees.• Raw POST Data: Again, nice to see from the PHP side, including pre-populating GLOBAL• Response Headers: This is before your webserver or proxy.• Response Body: What did PHP send back.
General Z-Ray Information– Request Info Tab
Z-Ray PluginsTodays Example Plugins
• Over 30 Extensions: http://www.zend.com/en/products/server/plugins• Most common frameworks and a few of the popular applications have Z-Ray toolbars
already• Redis, MongoDB, and other databases have plugins already.• Easy to create new ones, if your platform or framework of choice does not have one.
Z-Ray Community Extensions
Additional tab with Magento specific information Request and application details Events / Observers Layouts / Blocks / Templates Logs Modules (Extensions)
Z-Ray Magento Plugin
Additional tab with Wordpress specific information Application details Cache Objects Plugins Theme Profiler Hooks WP Query (ie post query) Crons
Z-Ray Wordpress Plugin
Additional tab with composer packages and mapping. Lists Composer packages and detailed information Provides a complete mapping of all the classes used on the
page, including class name and path
Z-Ray Composer Plugin
Z-Ray PluginsGeneral Architecture
• Runs as a PHP Extension• Autoloads Z-Ray plugins, which makes it very easy to add new plugins.• Requires some frontend webserver rules and static files• Zend Server has everything built in and ready to go *Including PHP 7 Support
• Tech Preview has been around for a while It expires after a couple months, Zend issues new versions Does not include PHP 7 support http://www.zend.com/en/products/z-ray/z-ray-preview
Z-Ray Internals
Plugins reside in /usr/local/zend/var/plugins/plugin-name/ LICENSE.txt – Needs one of these to get published README.txt – Document what you do in this file. logo.png – Extension logo, shown in tab. (50x50) deployment.json – Describes plugin contents, and dependancies route/route.php – Route plugins for Zend Server zray/zray.php – Main file for the plugin *only required file zray/Module.php – Controls tab display of search and other layout features zray/Panels/panelname.phtml – phtml template used to display data zray/Panels/panelname.css – css template used to render
Z-Ray Plugin Files
“A Zend Server plugin in an archive file that consists of a Z-Ray Extension and Routing Information.” - Zend Server Plugins Documentation• Typically contains the following directories: route, ui, zray• Deployments are provided by the deployment.json file
Z-Ray Plugin Structure
Z-Ray Extension API Features Zend Server Route API Features
• Implements tracing functionality• Collects and stores data• Services the Web API Calls for Display• Provides a set of Widgets for Display• Optional View scripts create custom display
• Used by Zend Server• Creates application route awareness for Zend Server• Provides better monitoring events• Can also be used to create Interceptors around
classes. ( setWatchedFunction )
• Class for declaring a Z-Ray extensions Serves as the main API for trace and metadata Instance as many as you like
• ZRayExtension must be enabled Call $zre->setEnabled() Or use $zre->setEnabledAfter()
• Magento uses later method• $zre->traceFunction() is used to add a trace
Z-Ray – ZRayExtension()
use ZRayExtension;$extension = new ZRayExtension(”composer”);$extension->setEnabledAfter('Composer\Autoload\ClassLoader::register');// [snip] Two trace functions after this.
The ZRayExtension initialization code from the composer zray plugin
ElePHPant From: http://afieldguidetoelephpants.net/
Creates Plugin via ZRayExtension
Enabled: this has to be set to collect data
onFunctionEnter() is called by the traceFunction call before test()
onFunctionExit() is called by the traceFunction call after test()
$zre->traceFunction sets the trace
Z-Ray – Example Test Plugin
<?phpuse ZRayExtension; // Create a default extension. $zre = new ZRayExtension('test');$zre->setEnabled();
function onFunctionEnter($context, &$storage) { $storage['test'][] = array('subject' => 'zendcon');}function onFunctionExit($context, &$storage) { $storage['test'][] = array('subject' => 'zray');}
$zre->traceFunction('test', 'onFunctionEnter', 'onFunctionExit');
Z-Ray module test/zray.php
test() is defined and called in a separate php file.
Z-Ray PluginsTracing
• $pattern – Typically a function or class name• $onEnter / $onLeave are Callables
Legitimate Callables are as follows:• array($storage,’method’)• anonymous functions• function($context, & $storage)• object that implements __invoke()
zray::traceFunction($pattern, $onEnter, $onLeave);
$extension->traceFunction( 'Composer\Autoload\ClassLoader::register', function(){}, [$composer, 'registerExit']);
Trace ClassLoader::register exit, on leave callback is the array type calling registerExit() on $composer
# Init – [snip – see original source]$zrayMagento = new Magento();$zrayMagento->setZRay(new ZRayExtension('magento'));$zrayMagento->getZRay()->setEnabledAfter('Mage::run');
# Traces$zrayMagento->getZRay()->traceFunction('Mage::app', function(){}, array($zrayMagento, 'mageAppExit'));$zrayMagento->getZRay()->traceFunction('Mage::log', function(){}, array($zrayMagento, 'logError'));$zrayMagento->getZRay()->traceFunction('Mage::run', function(){}, array($zrayMagento, 'mageRunExit'));$zrayMagento->getZRay()->traceFunction('Mage_Core_Model_App::_callObserverMethod', array($zrayMagento, 'appCallObserverMethodStart'), array($zrayMagento, 'appCallObserverMethodEnd'));$zrayMagento->getZRay()->traceFunction('Mage::dispatchEvent', array($zrayMagento, 'mageDispatchEventStart'), function(){});$zrayMagento->getZRay()->traceFunction('Mage_Core_Model_App::run', function(){},array($zrayMagento, 'createEvents'));
Magento Z-Ray Trace Functions
/usr/local/zend/var/plugins/magento/zray/zray.php
• $context will contain information about the trace• $storage is passed in as a reference
In this example:• Simple trace picks up the data for the Z-Ray Magento Request tab• Stored and parsed later• Un-tracing so this only fires once
Z-Ray Magento – App Exit Trace
public function mageAppExit($context, &$storage){ $this->requests = (array)Mage::app()->getRequest();
// Now that we got our requests, we can untrace 'Mage::app' (for performance reasons) $this->getZRay()->untraceFunction("Mage::app");}
Mage::app() is called to get Request information
• Later during mageRunExit trace Data is collected and formatted Initial and final values are calculated from the mageAppExit trace
Overview Tab – Request Information
Snippet from the zray.php Magento::getOverview()
//Requests$finalRequests = (array)Mage::app()->getRequest();$request[] = array(
'property' => 'Controller Name', 'init'=>Mage::app()->getRequest()->getControllerName(), 'final'=>Mage::app()->getRequest()->getControllerName()
);
• Later during mageRunExit trace Data is collected and formatted Initial and final values are calculated from the mageAppExit trace
Overview Tab – Request Information
Z-Ray Plugins$context and Data handling
Name DescriptionfunctionName The function or method's name
functionArgs An array of the arguments passed to the function. This will be a numbered array with the parameters in their order of appearance.
exceptionThrown Did the function throw an exception?exception the exception object that was thrown (can be NULL)
this The $this context of a method. Will be null for global or lambda functions that have no context
returnValue The function's return value
locals the functions variables, as they were at the end of the function execution. Variables can be accessed like this: $context['locals']['myLocalVariable'] (note the missing $ sign from the variable name)
timesCalled The number which the current function calleddurationInclusive The duration of the function include it's sub childrensdurationExclusive The duration of the function itselfCalledFromFile The filename from which the function was calledCalledFromLine The file line the function was called onextension The zrayExtension instance which allows you to store and reuse data
More about $context $context is an array of information about the traced function. It includes several keys that contain strings or arrays of data.
https://github.com/zend-server-plugins/Documentation/blob/master/DataCollection.md
Z-Ray - $context Example (Mage::log)
# The call that sets up the trace$zrayMagento->getZRay()->traceFunction('Mage::log', function(){}, array($zrayMagento, 'logError'));
# The logError function stores the data into _logs which would not be displayedpublic function logError($context, &$storage){ # This pulls in all the “local” internal vars to the function $this->_logs[] = $context['locals'];
# This could be done like this instead // $this->_logs[] = array( // 'Message' => $context['functionArgs'][0], // 'Level' => $context['functionArgs'][1], // 'File' => $context ['functionArgs'][2],; // );}
# Collected into the storage object in mageRunExit//Logs$storage['mlogs'][] = array('logs'=>$this->_logs,'devMode'=>Mage::getIsDeveloperMode());
From the Magento Z-Ray Extension
Mage::log(“captains log 69266.5”) called in application:
Logs Tab – Magento Log Files
public static function log($message, $level = null, $file = '', $forceLog = false)
Magento app/Mage.php
• Data must be passed as an array of rows• Each row can be one of the following:
Associative Array: This will make a grid table with columns from the names of the keys.
Multi-Level Associative: Creates a tree table.
Object: Creates a tree table
Z-Ray $storage – Expected Data formatting
$storage['myParams'][] = array('col1' => 'foo', 'col2' => 'bar', 'col3' => 'test');
$storage['myArray'][] = array('name' => 'foo', 'values' => array('col2' => 'bar', 'col3' => 'test'));
$objectOrClass = new ClassName();$storage['myObject']['firstObject'] = $objectOrClass;
Z-Ray $storage – Data to Grid Tables
// Create a default extension. $zre = new ZRayExtension('test');$zre->setEnabled();
function onFunctionEnter($context, &$storage) { $storage['test'][] = array( 'subject' => 'zendcon', 'value' => '2016', ); $storage['test'][] = array( 'subject' => 'zend', 'value' => 'zray', );}
$zre->traceFunction('test', 'onFunctionEnter', function(){});
Z-Ray module test/zray.php
$storage creates tabs in the Z-Ray display automatically
• Array or Associative array creates a Grid Table
• Object or Multi-Level array creates a Table Tree
• You can create custom panels, the sky is the limit
Z-Ray $storage - Data to Table Trees
$zre = new ZRayExtension('test', true);
class TestClass { var $subject; var $value; function __construct(){ $this->subject[] = ['zendcon','2016']; $this->subject[] = ['zray','testing toolkit']; $this->value = 'just some random string'; }};
function onFunctionEnter($context, &$storage) { $storage['test'][] = new Testclass();}
function onFunctionLeave($context, &$storage) {}$zre->traceFunction('test', 'onFunctionEnter', function(){});
Z-Ray module test/zray.php
To Debug Z-Ray Data Requests take a look in its XHR Callhttp://serverdemo.zend.com:10081/ZendServer/Api/zrayGetCustomData
Z-Ray – Debugging Data Flow
Z-Ray PluginWidgets & Panels
• Used for displaying and storage of data• Storage is also handled, and effectively backed by a
model that supplies the data in all widgets• Widgets are accessed through the zray javascript
object• Several Widgets exist to help display data
List of widgets:Table: Basic tableSummary Table: Used for filteringTree Table: Expandable TablePager: Pagification widgetSearch: A search bar
Z-Ray – Widgets
Further Reading: https://github.com/zend-server-plugins/Documentation/blob/master/Widgets.md
Z-Ray – The Tree Widget• Tree widgets show a tree structured view of the data• Two types of tree widgets are available:
Tree Widget: Simple key->value with the data shown with hierarchy.
General Tree Widget: Structured with column descriptors being homogenous across all rows• Could be used for lists of data, that would need a structure like folders• The Z-Ray Wordpress plugin has a great example of this in the Cache Objects panel.
var maintable = zray.createTreeTable(storage, jQuery('#<?php echo $tableParams['tableId']; ?>'));
Z-Ray – Declaring the columns in Panels
var storage = zray.getStorage('wordpressCacheObjectsTree');// create main tablevar maintable = zray.createGeneralTreeTable(storage, jQuery('#<?php echo $tableParams['tableId']; ?>'));maintable.setColumns([{
label: 'name',propertyName: 'name',width: '50%',sortable:"true",attributes: {'class': 'zdb-tree-table-cell-path zdb-ellipsis zdb-monospace'}
},[[snip]]
Wordpress zray plugin zray/Panels/cacheObjects.phtml
Original File: https://github.com/zend-server-plugins/WordPress/blob/master/zray/Panels/cacheObjects.phtml
The Magento Z-Ray plugin has custom panels for all tabs except the “modules tab”.
The modules tab is a list of extensions in Magento along with the status.
We will do the following to create a custom panel for the “modules tab” Modify Module.php add a Panels/modules.phtml file *this is will match the name of the top level array key in the $storage array
Module.php contains the descriptions of the panels and there are a few things to remember:• If you add a panel here, you must create a template for it in the Panels/ directory.• The order of the panels in Module.php is displayed in reverse.
Z-Ray – Customizing Panels Example
Further Reading: https://github.com/zend-server-plugins/Documentation/blob/master/DataDisplay.md
Z-Ray Extensions – Custom Panels (Module.php)
class Module extends \ZRay\ZRayModule {public function config() { return array( 'panels' => array( 'modules' => array( 'display' => true, 'logo' => 'logo.png', 'menuTitle' => 'Extensions', 'panelTitle'=> 'Extensions', 'searchId'=> 'mage-modules-search', ), 'logs' => array( [SNIP]
Snippet Module.php• Added the modules element to the panels array, renaming the tab to Extensions
• Take a look at the original file and the documentation for more details
• You can use this to hide tabs, you may not want them automatically display
• seachId must be unique, it is used for the filtering/searching
Original File: https://github.com/zend-server-plugins/Magento/blob/master/zray/Module.php
Z-Ray Extensions – Custom Panels (template)
<?php // Define the table HTML$tableParams = array( 'tableId' => 'mage-modules', 'tableWidth' => '4', );
?><?php echo $this->zrayTable($tableParams); //zrayTableHtml ?><!-– JAVASCRIPT GOES HERE -->
Panels/modules.phtml• zrayTable() Generates the HTML for the table• It is possible to create your own html skeleton
for the data, but requires more effort• $tableParams.tableId needs to be unique• Does not come with any data this is mapped
via javascript
More Examples: https://github.com/zend-server-plugins/Magento/tree/master/zray/Panels
Z-Ray Extensions – Custom Panels (template)
<script type="text/javascript">(function() { var storage = zray.getStorage('modules');
// create main table and bind it to the storage and HTML element var maintable = zray.createTable(storage, jQuery('#<?php echo $tableParams['tableId']; ?>')); maintable.setColumns([ { label: 'Name', propertyName: 'Name', }, // [snip] removed other fields – (active,code pool and version) ]); // create search zray.createSearch(storage, jQuery('#mage-modules-search'), maintable); // tie storage handler to data from storage zray.registerDataHandler('magento', 'modules', function(extensionData, requestData) { storage.setData(extensionData); });})();</script>
Panels/modules.phtml (continued)
• Tabs: These looks like sub-tabs and are just simple HTML <ul /> with proper class names• Summary Table: HTML skeleton with some javascript to tie the proper data filtering calls to
the checkboxes.• Search & Pagination: Live filtering of data is handled through the zray.createPager() and
zray.createSearch() javascript functions• Adding your own: Adding pie charts and other html widgets is easy. Take a look at the
wordpress plugin for a great example of the pie charts.
Z-Ray – Other Widgets
Get started today writing Z-Ray Plugins
• Simple to use trace functions• $context is a treasure trove• $storage displays data automatically• Easy to extend the way it displays• Community example plugins are plentiful
If you’re a _______ Developer and it has a plugin Start using Z-Ray if you don’t already. Contribute to the ________ plugin, as more can be added to it.
If you’re a _______ Developer and it doesn’t have a plugin Start using Z-Ray if you don’t already. My hope is that this presentation will have helped you start coding it today.
Z-Ray – Call to Action
Questions / Answers
• Rate this talk: It helps me improve it and my process.
https://joind.in/talk/a0d68
Thanks For Attending