Using Zend Z-Ray offers PHP developers a very powerful suite of tools out-of-the-box. Extending Z-Ray is easy and allows for nearly limitless customizable development tools. An exploration of Z-Ray plugin features will give attendees a foundation for creating their own Z-Ray extensions.
This session will show how to develop Z-Ray plugins for your applications and frameworks. Covering the Z-Ray plugins structure, storing and displaying data, tracing functions and files, utilizing the tree widget, how to format your data for use in Z-Ray, and modifying the way data is displayed in Z-Ray.
2. 2
Mathew Beane
@aepod
Director of Systems Engineering - Robofirm
Zend Z-Team Volunteer – Magento Division
Family member – 3 Kids and a Wife
Magento Master & Certified Developer
3. • 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
4. • 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
6. 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
7. 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.
8. • 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
9. • Errors and warnings at a glance
• More detailed information than the default handler
General Z-Ray Information – Errors & Warnings
10. • Back trace of exceptions with more detailed information
General Z-Ray Information – Errors & Warnings
11. • 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.
12. • 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
13. • 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
15. • 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
16. Additional tab with Magento specific information
Request and application details
Events / Observers
Layouts / Blocks / Templates
Logs
Modules (Extensions)
Z-Ray Magento Plugin
17. Additional tab with Wordpress specific information
Application details
Cache Objects
Plugins
Theme Profiler
Hooks
WP Query (ie post query)
Crons
Z-Ray Wordpress Plugin
18. 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
20. • 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
21. 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
22. “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 )
23. • 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('ComposerAutoloadClassLoader::register');
// [snip] Two trace functions after this.
The ZRayExtension initialization code from the composer zray plugin
ElePHPant From: http://afieldguidetoelephpants.net/
24. 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
<?php
use 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.
26. • $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(
'ComposerAutoloadClassLoader::register',
function(){},
[$composer, 'registerExit']
);
Trace ClassLoader::register exit, on leave callback is the array type calling registerExit() on $composer
28. • $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
29. • 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()
);
30. • Later during mageRunExit trace
Data is collected and formatted
Initial and final values are calculated from the mageAppExit trace
Overview Tab – Request Information
32. Name Description
functionName 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 called
durationInclusive The duration of the function include it's sub childrens
durationExclusive The duration of the function itself
CalledFromFile The filename from which the function was called
CalledFromLine The file line the function was called on
extension 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
33. 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 displayed
public 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
34. 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
35. • 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;
36. 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
37. 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
38. To Debug Z-Ray Data Requests take a look in its XHR Call
http://serverdemo.zend.com:10081/ZendServer/Api/zrayGetCustomData
Z-Ray – Debugging Data Flow
40. • 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 table
Summary Table: Used for filtering
Tree Table: Expandable Table
Pager: Pagification widget
Search: A search bar
Z-Ray – Widgets
Further Reading: https://github.com/zend-server-plugins/Documentation/blob/master/Widgets.md
41. 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']; ?>'));
42. Z-Ray – Declaring the columns in Panels
var storage = zray.getStorage('wordpressCacheObjectsTree');
// create main table
var 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
43. 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
44. Z-Ray Extensions – Custom Panels (Module.php)
class Module extends ZRayZRayModule {
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
45. 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
46. 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)
47. • 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
48. 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
49. 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
Link to IDE, see full path info on all files and a debug backtraceThese are also REALLY handy for catching errors in your zray extension.
We are going to look at three today.
Detailed information about Magento’s complex machinations.
A proton collides with a lead nucleus, sending a shower of particles through the ALICE detector. LHC
Dashboard: provides useful information about the WordPress installation, including version, whether debug mode is enabled, the used template, and crons status.
Plugins: helps you understand which plugin is consuming the most resources by specifying all the different plugins enabled on the page, together with the time they took to load.
Theme Profiler: helps profile the WordPress theme loaded on the page by breaking down the functions and classes and the time they took to execute
Hooks: outlines all the WordPress hooks triggered during execution. See the name of the hook, it’s type (action/filter), the file path, and the time it took to execute.
WP Query: displays the current main WordPress query (e.g. the post query).
Crons: gives insight into the WordPress cron system. View the hooked functions used, their schedule, any defined arguments for the cron event, and the time of the next execution.
Can be used at the same time as other plugins, just adds another tab.
Path may vary, but the relative path to the zend install will be the same
Really you only need zray directory and zray.php
There is another API Component(directory), UI which is ties into Zend Server UIsee the magento plugin for an example of the setWatchedFunctions in route/route.php
3 parts to instancing a zray plugin:1) declare the class extending ZRayExtensio
2) Enable Z-Ray
3) Add a trace function
Composer is the storage object in this case, and if you look at the extension it has a few methods to help format the data in the classmap etc.
There is a second trace for ClassLoader::findFileWithExtension this populates the data array while the exit finalizes it and puts into the data storage
$this->requests is parsed into overview->requests panel by getOverview()
We will come back to $context in a few minutes.Magento Will finish running Mage::App(bootstrapper) before finishing Mage::Run(Mage Application) , this is part of the architecture of Magento
Initially data is stored from the mageAppExit later after mageRunExit it uses the grabbed data again and creates the data array.
Data can be persisted through the traces, but you also have a lot of data that comes in from the $context array.
Initially data is stored from the mageAppExit later after mageRunExit it grabs the same data again and creates the data array.
Data can be persisted through the traces, but you also have a lot of data that comes in from the $context object.
There is a lot of data here, most of which is NOT displayed or used, but would be very useful from a debugging or platform/framework point of view.
Drupal – Called Functions is a good example of a basic tree table from multi-level assoc
Empty function is used for null passes.Storage is passed around as a reference and can really be added to anytime after you have init’d zray
Note autoenable bad idea, use the enableAfter function.
All data is passed in a single call across all Z-Ray extensions. Take a look here to see how your data is flowing.
2 types of tree tables (general tree has homogenous columns)
Normal tree table typically shows rows of nested (key->value)
Non-general tree widgets show data across rows instead of columns (almost like a form view)
WP Chart uses Canvas w/ Chart.js (cool feature!)
Grabs storage
Use the javascript zray object to map to the table
You have to specify columns etc.
Next you have the “search” which needs to match the search in the Modules.php definition
Last it populates the table rp, the proper data array.