SlideShare une entreprise Scribd logo
1  sur  136
Télécharger pour lire hors ligne
Error Reporting
in Zend Framework 2

Zend Framework Day – Turin, Italy – 07/02/2014
STEVE MARASPIN
@maraspin
http://www.mvlabs.it/
http://friuli.grusp.org/

5
WHY WORRY?
WE SCREW UP
WE ALL SCREW UP
Application Failures
Application Failures
User Mistakes
INCREASED SUPPORT COST
ABANDONMENT
THE BOTTOM LINE
User Input = Mistake Source
Validation Handling
User Privacy Concerns
• Over 40% of online shoppers are very
concerned over the use of personal
information
• Public opinion polls have revealed a
general desire among Internet users to
protect their privacy
Online Privacy: A Growing Threat. - Business Week, March 20, 2000, 96. Internet Privacy in ECommerce:
Framework, Review, and Opportunities for Future Research - Proceedings of the 41st Hawaii
International Conference on System Sciences - 2008
Validation Handling
Improved Error Message
+70% CONVERSIONS
21
Creating A Form in ZF2
<?php
namespace ApplicationForm;
use ZendFormForm;
class ContactForm extends Form
{
public function __construct() {
parent::__construct();
// ...
}
//...
}
Creating A Form in ZF2
<?php
namespace ApplicationForm;
use ZendFormForm;
class ContactForm extends Form
{
public function __construct() {
parent::__construct();
// ...
}
//...
}
Adding Form Fields
public function init() {
$this->setName('contact');
$this->setAttribute('method', 'post');
[…]..
$this->add(array('name' => 'email',
'type' => 'text',
'options' => array(
'label' => 'Name',
),
);
$this->add(array('name' => 'message',
'type' => 'textarea',
'options' => array(
'label' => 'Message',
),
);
//. […]..
}
Adding Form Fields
public function init() {
$this->setName('contact');
$this->setAttribute('method', 'post');
[…]..
$this->add(array('name' => 'email',
'type' => 'text',
'options' => array(
'label' => 'Name',
),
);
$this->add(array('name' => 'message',
'type' => 'textarea',
'options' => array(
'label' => 'Message',
),
);
//. […]..
}
VALIDATION
Form Validation: InputFilter
Validation: inputFilter
<?php
namespace ApplicationForm;
[…]
class ContactFilter extends InputFilter

{
public function __construct() {

// filters go here
}

}
Validation: inputFilter
<?php
namespace ApplicationForm;
[…]
class ContactFilter extends InputFilter

{
public function __construct() {

// filters go here
}

}
Required Field Validation
$this->add(array(
'name' => 'email',
'required' => true,
'filters' => array(
array(
'name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'EmailAddress',
)
)
));
Required Field Validation
$this->add(array(
'name' => 'email',
'required' => true,
'filters' => array(
array(
'name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'EmailAddress',
)
)
));
InputFilter Usage
<?php
namespace ApplicationController;

[…]
class IndexController extends AbstractActionController
{

public function contactAction()
{
$form = new Contact();
$filter = new ContactFilter();

$form->setInputFilter($filter);
return new ViewModel(array(
'form' => $form );

}
}
InputFilter Usage
<?php
namespace ApplicationController;

[…]
class IndexController extends AbstractActionController
{

public function contactAction()
{
$form = new Contact();
$filter = new ContactFilter();

$form->setInputFilter($filter);
return new ViewModel(array(
'form' => $form );

}
}
Standard Error Message
Improved Error Message
Error Message Customization
$this->add(array(
'name' => 'email',

'required' => true,
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(

array('name' =>'NotEmpty',
'options' => array(
'messages' => array(
NotEmpty::IS_EMPTY => 'We need an '.
'e-mail address to be able to get back to you'
),
),
),
array('name' => 'EmailAddress'),

)
));
Error Message Customization
$this->add(array(
'name' => 'email',

'required' => true,
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(

array('name' =>'NotEmpty',
'options' => array(
'messages' => array(
NotEmpty::IS_EMPTY => 'We need an '.
'e-mail address to be able to get back to you'
),
),
),
array('name' => 'EmailAddress'),

)
));
More than we need…
Check Chain
$this->add(array(
'name' => 'email',

'required' => true,
'filters' => array(
array('name' => 'StringTrim'),
),
'validators' => array(

array('name' =>'NotEmpty',
'options' => array(
'messages' => array(
NotEmpty::IS_EMPTY => 'We need an '.
'e-mail address to be able to get back to you'
),
),
'break_chain_on_failure' => true,
),

array('name' => 'EmailAddress'),
) ));
Ok, good…
…but, what if?
Words to Avoid

http://uxmovement.com/forms/how-to-make-your-form-error-messages-more-reassuring/
A few tips:
•

•

•

45

Provide the user with a solution to the
problem
Do not use technical jargon, use
terminology that your audience
understands
Avoid uppercase text and exclamation
points
Improved message
Condensing N messages into 1
$this->add(array(
'name' => 'email',

'required' => true,
'validators' => array(
array('name' =>'NotEmpty',
'options' => array(
'messages' => array(

NotEmpty::IS_EMPTY => 'We need an '.
'e-mail address to be able to get back to you'
)),
'break_chain_on_failure' => true,
),
array('name' => 'EmailAddress',
'options' => array(
'message' => 'E-Mail address does not seem to be valid.
Please make sure it contains the @ symbol

and a valid domain name.',
)));
Condensing N messages into 1
$this->add(array(
'name' => 'email',

'required' => true,
'validators' => array(
array('name' =>'NotEmpty',
'options' => array(
'messages' => array(

NotEmpty::IS_EMPTY => 'We need an '.
'e-mail address to be able to get back to you'
)),
'break_chain_on_failure' => true,
),
array('name' => 'EmailAddress',
'options' => array(
'message' => 'E-Mail address does not seem to be valid.
Please make sure it contains the @ symbol

and a valid domain name.',
)));
Messages VS message
$this->add(array(
'name' => 'email',

'required' => true,
'validators' => array(
array('name' =>'NotEmpty',
'options' => array(
'messages' => array(

NotEmpty::IS_EMPTY => 'We need an '.
'e-mail address to be able to get back to you'
)),
'break_chain_on_failure' => true,
),
array('name' => 'EmailAddress',
'options' => array(
'message' => 'E-Mail address does not seem to be valid.
Please make sure it contains the @ symbol

and a valid domain name.',
)));
Translated Error Messages
Default Message Translation
public function onBootstrap(MvcEvent $e)
{
$translator = $e->getApplication()
->getServiceManager()->get('translator');

$translator->addTranslationFile(
'phpArray', __DIR__ .
'/../../vendor/zendframework/zendframework/'.
'resources/languages/it/Zend_Validate.php',
'default',
'it_IT'
);
AbstractValidator::setDefaultTranslator($translator);
}
Custom Message Translation
$this->add(array(
'name' => 'email',
'required' => true,
'validators' => array(
array('name' =>'NotEmpty',
'options' => array(
'translator' => $translator,
'message' => $translator->translate(
'Make sure your e-mail address contains the @
symbol and a valid domain name.'
)),
'break_chain_on_failure' => true,
),
)));
Form Factory
$translator = $I_services->get('translator');
$I_form = new Contact();
$I_filter = new ContactFilter($translator);
$I_form->setInputFilter($I_filter);
return $I_form;
Translated Error Message
http://patterntap.com/pattern/funny-and-helpful-404-error-page-mintcom
56
Error Display Configuration
Skeleton Applicaton
Configuration
Hiding Exception Traces
'view_manager' => array(

'display_not_found_reason' => false,
'display_exceptions' => false,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => array(
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
'application/index/index'=> __DIR__ .
'/../view/application/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
Hiding Exception Traces
'view_manager' => array(

'display_not_found_reason' => false,
'display_exceptions' => false,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => array(
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
'application/index/index'=> __DIR__ .
'/../view/application/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
Custom Error Pages
'view_manager' => array(

'display_not_found_reason' => false,
'display_exceptions' => false,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => array(
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
'application/index/index'=> __DIR__ .
'/../view/application/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
How about PHP Errors?
class IndexController extends AbstractActionController
{
public function indexAction()
{

1/0;
return new ViewModel();
}
}
How about PHP Errors?
class IndexController extends AbstractActionController
{
public function indexAction()
{

1/0;
return new ViewModel();
}
}
Early error detection principle
What can we do?
Handling PHP Errors
public function onBootstrap(MvcEvent $I_e) {
[…]
set_error_handler(array('ApplicationModule','handlePhpErrors'));
}
public static function handlePhpErrors($i_type,
$s_message,
$s_file,
$i_line) {
if (!($i_type & error_reporting())) { return };

throw new Exception("Error: " . $s_message . " in file " . $s_file
. " at line " . $i_line);
}
What happens now?
class IndexController extends AbstractActionController
{
public function indexAction()
{

1/0;
return new ViewModel();
}
}
Now… what if?
class IndexController extends AbstractActionController
{
public function indexAction()
{
$doesNotExist->doSomething();
return new ViewModel();
}
}
Fatal error: Call to a member function doSomething() on a non-object in
/srv/apps/zfday/module/Application/src/Application/Controller/IndexController.php
on line 20
FATAL ERRORS
Fatal Error Handling
public function onBootstrap(MvcEvent $I_e) {
[…]
$am_config = $I_application->getConfig();
$am_environmentConf = $am_config['mvlabs_environment'];
// Fatal Error Recovery
if (array_key_exists('recover_from_fatal', $am_environmentConf) &&
$am_environmentConf['recover_from_fatal']) {
$s_redirectUrl = $am_environmentConf['redirect_url'];
}
$s_callback = null;
if (array_key_exists('fatal_errors_callback', $am_environmentConf)) {
$s_callback = $am_environmentConf['fatal_errors_callback'];
}
register_shutdown_function(array('ApplicationModule',
'handleFatalPhpErrors'),
$s_redirectUrl,
$s_callback);
}
Fatal Error Handling
/**
* Redirects user to nice page after fatal has occurred
*/
public static function handleFatalPhpErrors($s_redirectUrl,
$s_callback = null) {
if (php_sapi_name() != 'cli' && @is_Array($e = @get_last())) {
if (null != $s_callback) {
// This is the most stuff we can get.
// New context outside of framework scope
$m_code = isset($e['type']) ? $e['type'] : 0;
$s_msg = isset($e['message']) ? $e['message']:'';
$s_file = isset($e['file']) ? $e['file'] : '';
$i_line = isset($e['line']) ? $e['line'] : '';
$s_callback($s_msg, $s_file, $i_line);
}
header("location: ". $s_redirectUrl);
}
return false;
}
Fatal Error Handling
'mvlabs_environment' => array(
'exceptions_from_errors' => true,
'recover_from_fatal' => true,
'fatal_errors_callback' => function($s_msg, $s_file, $s_line) {
return false;
},
'redirect_url' => '/error',

'php_settings' => array(
'error_reporting' => E_ALL,
'display_errors' => 'Off',
'display_startup_errors' => 'Off',
),
),
PHP Settings Conf
'mvlabs_environment' => array(
'exceptions_from_errors' => true,
'recover_from_fatal' => true,
'fatal_errors_callback' => function($s_msg, $s_file, $s_line) {
return false;
},
'redirect_url' => '/error',

'php_settings' => array(
'error_reporting' => E_ALL,
'display_errors' => 'Off',
'display_startup_errors' => 'Off',
),
),
PHP Settings
public function onBootstrap(MvcEvent $I_e) {
[…]
foreach($am_phpSettings as $key => $value) {
ini_set($key, $value);
}
}
NICE PAGE!
CUSTOMER SUPPORT TEAM REACTION
http://www.flickr.com/photos/18548283@N00/8030280738
ENVIRONMENT
DEPENDANT
CONFIGURATION
During Deployment
Local/Global Configuration Files
During Deployment
Runtime
Index.php
// Application wide configuration
$am_conf = $am_originalConf = require 'config/application.config.php';

// Environment specific configuration
$s_environmentConfFile = 'config/application.'.$s_env.'.config.php';
if (file_exists($s_environmentConfFile) &&
is_readable($s_environmentConfFile)) {
// Specific environment configuration merge
$am_environmentConf = require $s_environmentConfFile;
$am_conf = ZendStdlibArrayUtils::merge($am_originalConf,
$am_environmentConf
);
}

// Additional Specific configuration files are also taken into account
$am_conf["module_listener_options"]["config_glob_paths"][] =
'config/autoload/{,*.}' . $s_env . '.php';
ZendMvcApplication::init($am_conf)->run();
application.config.php
'modules' => array(
'Application',
),
Application.dev.config.php
'modules' => array(
'Application',
'ZendDeveloperTools',
),
Enabling Environment Confs
// Application nominal environment
$am_conf = $am_originalConf = require 'config/application.config.php';

// Environment specific configuration
$s_environmentConfFile = 'config/application.'.$s_env.'.config.php';
// Do we have a specific configuration file?
if (file_exists($s_environmentConfFile) &&
is_readable($s_environmentConfFile)) {
// Specific environment configuration merge
$am_environmentConf = require $s_environmentConfFile;
$am_conf = ZendStdlibArrayUtils::merge($am_originalConf,
$am_environmentConf );
}

// Additional Specific configuration files are also taken into account
$am_conf["module_listener_options"]["config_glob_paths"][] =
'config/autoload/{,*.}' . $s_env . '.php';
ZendMvcApplication::init($am_conf)->run();
Env Dependant Conf Files
index.php Check
// What environment are we in?
$s_env = getenv('APPLICATION_ENV');
if (empty($s_env)) {
throw new Exception('Environment not set.'.
' Cannot continue. Too risky!');
}
Apache Config File
<VirtualHost *:80>
DocumentRoot /srv/apps/zfday/public
ServerName www.dev.zfday.it
SetEnv APPLICATION_ENV "dev"
<Directory /srv/apps/zfday/public>
AllowOverride FileInfo
</Directory>
</VirtualHost>
LOGGING

http://www.flickr.com/photos/otterlove/8154505388/
Why Log?

Troubleshooting
• Stats Generation
• Compliance
•

95
Zend Log
$logger = new ZendLogLogger;
$writer = new ZendLogWriterStream('/var/log/app.log');
$logger->addWriter($writer);
$logger->info('Informational message');
$logger->log(ZendLogLogger::EMERG, 'Emergency message');
Zend Log
$logger = new ZendLogLogger;
$writer = new ZendLogWriterStream('/var/log/app.log');
$logger->addWriter($writer);
$logger->info('Informational message');
$logger->log(ZendLogLogger::EMERG, 'Emergency message');
ZendLogLogger::registerErrorHandler($logger);
ZendLogLogger::registerExceptionHandler($logger);
Writers

98
Writers

99
Logrotate
/var/log/app.log {
missingok
rotate 7
daily
notifempty
copytruncate
compress
endscript
}
100
Writers

101
Writers

102
Writers

103
Zend Log Ecosystem

104
Filter Example
$logger = new ZendLogLogger;
$writer1 = new ZendLogWriterStream('/var/log/app.log');
$logger->addWriter($writer1);
$writer2 = new ZendLogWriterStream('/var/log/err.log');
$logger->addWriter($writer2);
$filter = new ZendLogFilterPriority(Logger::CRIT);
$writer2->addFilter($filter);
$logger->info('Informational message');
$logger->log(ZendLogLogger::CRIT, 'Emergency message');
Monolog
use MonologLogger;
use MonologHandlerStreamHandler;
$log = new Logger('name');
$log->pushHandler(new StreamHandler('/var/log/app.log',
Logger::WARNING));
$log->addWarning('Foo');
$log->addError('Bar');
Monolog Components

107
How to log?
class IndexController {

public function helloAction() {
return new ViewModel('msg' =>"Hello!");

}
}
Traditional Invokation
Logging Within Controller
class GreetingsController {
public function helloAction() {
$I_logger = new Logger();
$I_logger->log("We just said Hello!");
return new ViewModel('msg' =>"Hello!");
}
}
Single Responsability Violation
class GreetingsController {
public function helloAction() {
$I_logger = new Logger();
$I_logger->log("We just said Hello!");
return new ViewModel('msg' =>"Hello!");
}
}
Fat Controllers
class GreetingsController {

public function helloAction() {
$I_logger = new Logger();
$I_logger->log("We just said Hello!");
$I_mailer = new Mailer();
$I_mailer->mail($s_msg);
$I_queue = new Queue();
$I_queue->add($s_msg);
return new ViewModel('msg' =>"Hello!");
}
}
CROSS CUTTING CONCERNS
What can we do?
Handling Events
class Module {
public function onBootstrap(MvcEvent $e) {
$eventManager = $e->getApplication()
->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$logger = $sm->get('logger');
$eventManager->attach('wesaidHello',
function(MvcEvent $event) use
($logger) {
$logger->log($event->getMessage());
);
}
}
Triggering An Event
class GreetingsController {

public function helloAction() {
$this->eventManager
->trigger('wesaidHello',
$this,
array('greeting' => 'Hello!')
);
return new ViewModel('msg' => "Hello!");
}
}
Traditional Invokation
Event Manager
OBSERVER
http://www.flickr.com/photos/lstcaress/502606063/
Event Manager
Handling Framework Errors
class Module {
public function onBootstrap(MvcEvent $e) {
$eventManager = $e->getApplication()
->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);

$logger = $sm->get('logger');
$eventManager->attach(MvcEvent::EVENT_RENDER_ERROR,
function(MvcEvent $e) use ($logger) {
$logger->info('An exception has Happened ' .
$e->getResult()->exception->getMessage());
}, -200);
);
}
}
Event Manager
Stuff to take home
1.
2.
3.

123

When reporting errors, make sure to be
nice with users
Different error reporting strategies could
be useful for different environments
The event manager reduces coupling and
provides flexibility
2 min intro
https://xkcd.com/208/
Starting Things Up
input { stdin { } }
output { stdout { codec => rubydebug } }
Starting Things Up
input { stdin { } }
output { stdout { codec => rubydebug } }
java -jar logstash-1.3.3-flatjar.jar agent -f sample.conf
Integrated Elasticsearch
input {

file { path => ["/opt/logstash/example.log"] }
}
output {
stdout { codec => rubydebug }
elasticsearch { embedded => true }
}
java -jar logstash-1.3.3-flatjar.jar agent -f elastic.conf
Integrated Web Interface
input {

file { path => ["/opt/logstash/example.log"] }
}
output {
stdout { codec => rubydebug }
elasticsearch { embedded => true }
}
java -jar logstash.jar agent -f elastic.conf --web
Kibana
Thank you for your attention

Stefano Maraspin
@maraspin
@maraspin
Stefano Maraspin
@maraspin

Contenu connexe

Tendances

Php Security By Mugdha And Anish
Php Security By Mugdha And AnishPhp Security By Mugdha And Anish
Php Security By Mugdha And AnishOSSCube
 
Zend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolZend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolGordon Forsythe
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and youmarkstory
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsPHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsMichelangelo van Dam
 
Concern of Web Application Security
Concern of Web Application SecurityConcern of Web Application Security
Concern of Web Application SecurityMahmud Ahsan
 
Dealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsDealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsClinton Dreisbach
 
Proposed PHP function: is_literal()
Proposed PHP function: is_literal()Proposed PHP function: is_literal()
Proposed PHP function: is_literal()Craig Francis
 
SCULPT! YOUR! TESTS!
SCULPT! YOUR! TESTS!SCULPT! YOUR! TESTS!
SCULPT! YOUR! TESTS!Taras Oleksyn
 
Open Source Search: An Analysis
Open Source Search: An AnalysisOpen Source Search: An Analysis
Open Source Search: An AnalysisJustin Finkelstein
 
Php Security3895
Php Security3895Php Security3895
Php Security3895Aung Khant
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxMichelangelo van Dam
 
Jquery presentation
Jquery presentationJquery presentation
Jquery presentationguest5d87aa6
 

Tendances (19)

Php Security By Mugdha And Anish
Php Security By Mugdha And AnishPhp Security By Mugdha And Anish
Php Security By Mugdha And Anish
 
Zend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolZend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_Tool
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and you
 
PHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the testsPHPUnit Episode iv.iii: Return of the tests
PHPUnit Episode iv.iii: Return of the tests
 
Php Security
Php SecurityPhp Security
Php Security
 
PHPSpec BDD for PHP
PHPSpec BDD for PHPPHPSpec BDD for PHP
PHPSpec BDD for PHP
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Concern of Web Application Security
Concern of Web Application SecurityConcern of Web Application Security
Concern of Web Application Security
 
Dealing with Legacy PHP Applications
Dealing with Legacy PHP ApplicationsDealing with Legacy PHP Applications
Dealing with Legacy PHP Applications
 
PHP Security
PHP SecurityPHP Security
PHP Security
 
Extend sdk
Extend sdkExtend sdk
Extend sdk
 
Proposed PHP function: is_literal()
Proposed PHP function: is_literal()Proposed PHP function: is_literal()
Proposed PHP function: is_literal()
 
SCULPT! YOUR! TESTS!
SCULPT! YOUR! TESTS!SCULPT! YOUR! TESTS!
SCULPT! YOUR! TESTS!
 
Seam Glassfish Slidecast
Seam Glassfish SlidecastSeam Glassfish Slidecast
Seam Glassfish Slidecast
 
Building web APIs in PHP with Zend Expressive
Building web APIs in PHP with Zend ExpressiveBuilding web APIs in PHP with Zend Expressive
Building web APIs in PHP with Zend Expressive
 
Open Source Search: An Analysis
Open Source Search: An AnalysisOpen Source Search: An Analysis
Open Source Search: An Analysis
 
Php Security3895
Php Security3895Php Security3895
Php Security3895
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Jquery presentation
Jquery presentationJquery presentation
Jquery presentation
 

En vedette

ZF2 Modular Architecture - Taking advantage of it
ZF2 Modular Architecture - Taking advantage of itZF2 Modular Architecture - Taking advantage of it
ZF2 Modular Architecture - Taking advantage of itSteve Maraspin
 
Moduli su Zend Framework 2: come sfruttarli
Moduli su Zend Framework 2: come sfruttarliModuli su Zend Framework 2: come sfruttarli
Moduli su Zend Framework 2: come sfruttarliStefano Valle
 
Elegant Ways of Handling PHP Errors and Exceptions
Elegant Ways of Handling PHP Errors and ExceptionsElegant Ways of Handling PHP Errors and Exceptions
Elegant Ways of Handling PHP Errors and ExceptionsZendCon
 
Asset management with Zend Framework 2
Asset management with Zend Framework 2Asset management with Zend Framework 2
Asset management with Zend Framework 2Stefano Valle
 
Instant ACLs with Zend Framework 2
Instant ACLs with Zend Framework 2Instant ACLs with Zend Framework 2
Instant ACLs with Zend Framework 2Stefano Valle
 
Unit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitUnit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitMichelangelo van Dam
 
Into the ZF2 Service Manager
Into the ZF2 Service ManagerInto the ZF2 Service Manager
Into the ZF2 Service ManagerChris Tankersley
 
Zend Framework 2 : Dependency Injection
Zend Framework 2 : Dependency InjectionZend Framework 2 : Dependency Injection
Zend Framework 2 : Dependency InjectionAbdul Malik Ikhsan
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentationThanh Robi
 
Meet a parallel, asynchronous PHP world
Meet a parallel, asynchronous PHP worldMeet a parallel, asynchronous PHP world
Meet a parallel, asynchronous PHP worldSteve Maraspin
 
Clean Unit Test Patterns
Clean Unit Test PatternsClean Unit Test Patterns
Clean Unit Test PatternsFrank Appel
 
Understanding Unit Testing
Understanding Unit TestingUnderstanding Unit Testing
Understanding Unit Testingikhwanhayat
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitMichelangelo van Dam
 
Unit Testing Concepts and Best Practices
Unit Testing Concepts and Best PracticesUnit Testing Concepts and Best Practices
Unit Testing Concepts and Best PracticesDerek Smith
 
Zend Framework Workshop Parte2
Zend Framework Workshop Parte2Zend Framework Workshop Parte2
Zend Framework Workshop Parte2massimiliano.wosz
 
GAME ON! Integrating Games and Simulations in the Classroom
GAME ON! Integrating Games and Simulations in the Classroom GAME ON! Integrating Games and Simulations in the Classroom
GAME ON! Integrating Games and Simulations in the Classroom Brian Housand
 

En vedette (17)

ZF2 Modular Architecture - Taking advantage of it
ZF2 Modular Architecture - Taking advantage of itZF2 Modular Architecture - Taking advantage of it
ZF2 Modular Architecture - Taking advantage of it
 
Zend Framework 2 - PHPUnit
Zend Framework 2 - PHPUnitZend Framework 2 - PHPUnit
Zend Framework 2 - PHPUnit
 
Moduli su Zend Framework 2: come sfruttarli
Moduli su Zend Framework 2: come sfruttarliModuli su Zend Framework 2: come sfruttarli
Moduli su Zend Framework 2: come sfruttarli
 
Elegant Ways of Handling PHP Errors and Exceptions
Elegant Ways of Handling PHP Errors and ExceptionsElegant Ways of Handling PHP Errors and Exceptions
Elegant Ways of Handling PHP Errors and Exceptions
 
Asset management with Zend Framework 2
Asset management with Zend Framework 2Asset management with Zend Framework 2
Asset management with Zend Framework 2
 
Instant ACLs with Zend Framework 2
Instant ACLs with Zend Framework 2Instant ACLs with Zend Framework 2
Instant ACLs with Zend Framework 2
 
Unit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitUnit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnit
 
Into the ZF2 Service Manager
Into the ZF2 Service ManagerInto the ZF2 Service Manager
Into the ZF2 Service Manager
 
Zend Framework 2 : Dependency Injection
Zend Framework 2 : Dependency InjectionZend Framework 2 : Dependency Injection
Zend Framework 2 : Dependency Injection
 
PHPUnit best practices presentation
PHPUnit best practices presentationPHPUnit best practices presentation
PHPUnit best practices presentation
 
Meet a parallel, asynchronous PHP world
Meet a parallel, asynchronous PHP worldMeet a parallel, asynchronous PHP world
Meet a parallel, asynchronous PHP world
 
Clean Unit Test Patterns
Clean Unit Test PatternsClean Unit Test Patterns
Clean Unit Test Patterns
 
Understanding Unit Testing
Understanding Unit TestingUnderstanding Unit Testing
Understanding Unit Testing
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
 
Unit Testing Concepts and Best Practices
Unit Testing Concepts and Best PracticesUnit Testing Concepts and Best Practices
Unit Testing Concepts and Best Practices
 
Zend Framework Workshop Parte2
Zend Framework Workshop Parte2Zend Framework Workshop Parte2
Zend Framework Workshop Parte2
 
GAME ON! Integrating Games and Simulations in the Classroom
GAME ON! Integrating Games and Simulations in the Classroom GAME ON! Integrating Games and Simulations in the Classroom
GAME ON! Integrating Games and Simulations in the Classroom
 

Similaire à Error Reporting in ZF2: form messages, custom error pages, logging

Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11Michelangelo van Dam
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Shinya Ohyanagi
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From IusethisMarcus Ramberg
 
Data::FormValidator Simplified
Data::FormValidator SimplifiedData::FormValidator Simplified
Data::FormValidator SimplifiedFred Moyer
 
Building Better Applications with Data::Manager
Building Better Applications with Data::ManagerBuilding Better Applications with Data::Manager
Building Better Applications with Data::ManagerJay Shirley
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Michelangelo van Dam
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web servicesMichelangelo van Dam
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful softwareJorn Oomen
 
WordPress as an application framework
WordPress as an application frameworkWordPress as an application framework
WordPress as an application frameworkDustin Filippini
 
Digital Mayflower - Data Pilgrimage with the Drupal Migrate Module
Digital Mayflower - Data Pilgrimage with the Drupal Migrate ModuleDigital Mayflower - Data Pilgrimage with the Drupal Migrate Module
Digital Mayflower - Data Pilgrimage with the Drupal Migrate ModuleErich Beyrent
 
HTML::FormFu talk for Sydney PM
HTML::FormFu talk for Sydney PMHTML::FormFu talk for Sydney PM
HTML::FormFu talk for Sydney PMDean Hamstead
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Michelangelo van Dam
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Michelangelo van Dam
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of LithiumNate Abele
 

Similaire à Error Reporting in ZF2: form messages, custom error pages, logging (20)

Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2
 
Leveraging Symfony2 Forms
Leveraging Symfony2 FormsLeveraging Symfony2 Forms
Leveraging Symfony2 Forms
 
CakePHP workshop
CakePHP workshopCakePHP workshop
CakePHP workshop
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
 
Data::FormValidator Simplified
Data::FormValidator SimplifiedData::FormValidator Simplified
Data::FormValidator Simplified
 
Building Better Applications with Data::Manager
Building Better Applications with Data::ManagerBuilding Better Applications with Data::Manager
Building Better Applications with Data::Manager
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web services
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful software
 
WordPress as an application framework
WordPress as an application frameworkWordPress as an application framework
WordPress as an application framework
 
Digital Mayflower - Data Pilgrimage with the Drupal Migrate Module
Digital Mayflower - Data Pilgrimage with the Drupal Migrate ModuleDigital Mayflower - Data Pilgrimage with the Drupal Migrate Module
Digital Mayflower - Data Pilgrimage with the Drupal Migrate Module
 
HTML::FormFu talk for Sydney PM
HTML::FormFu talk for Sydney PMHTML::FormFu talk for Sydney PM
HTML::FormFu talk for Sydney PM
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 
Moodle Quick Forms
Moodle Quick FormsMoodle Quick Forms
Moodle Quick Forms
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
The new form framework
The new form frameworkThe new form framework
The new form framework
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 

Plus de Steve Maraspin

Architetture a Microservizi (con Kubernetes)
Architetture a Microservizi (con Kubernetes)Architetture a Microservizi (con Kubernetes)
Architetture a Microservizi (con Kubernetes)Steve Maraspin
 
How Agile changed Software Development
How Agile changed Software DevelopmentHow Agile changed Software Development
How Agile changed Software DevelopmentSteve Maraspin
 
Principi di Interaction Design
Principi di Interaction DesignPrincipi di Interaction Design
Principi di Interaction DesignSteve Maraspin
 
Customer Journey Mapping Workshop
Customer Journey Mapping WorkshopCustomer Journey Mapping Workshop
Customer Journey Mapping WorkshopSteve Maraspin
 
A (really) Quick Introduction to Event Storming
A (really) Quick Introduction to Event StormingA (really) Quick Introduction to Event Storming
A (really) Quick Introduction to Event StormingSteve Maraspin
 
Don't Make Me Think - There's no need (2014)
Don't Make Me Think - There's no need (2014)Don't Make Me Think - There's no need (2014)
Don't Make Me Think - There's no need (2014)Steve Maraspin
 
The Metaphor Fallacy (in Digital Product Development)
The Metaphor Fallacy (in Digital Product Development)The Metaphor Fallacy (in Digital Product Development)
The Metaphor Fallacy (in Digital Product Development)Steve Maraspin
 
Lean UX: Sviluppo Software Agile e Incentrato sull'Utente
Lean UX: Sviluppo Software Agile e Incentrato sull'UtenteLean UX: Sviluppo Software Agile e Incentrato sull'Utente
Lean UX: Sviluppo Software Agile e Incentrato sull'UtenteSteve Maraspin
 
La filosofia Lean nello sviluppo di prodotti digitali
La filosofia Lean nello sviluppo di prodotti digitaliLa filosofia Lean nello sviluppo di prodotti digitali
La filosofia Lean nello sviluppo di prodotti digitaliSteve Maraspin
 
Outcome not Output: A Story of Lean UX Adoption
Outcome not Output: A Story of Lean UX AdoptionOutcome not Output: A Story of Lean UX Adoption
Outcome not Output: A Story of Lean UX AdoptionSteve Maraspin
 
Don't Make me Think - There's no Need
Don't Make me Think - There's no NeedDon't Make me Think - There's no Need
Don't Make me Think - There's no NeedSteve Maraspin
 
Fare con Zend Framework 2 ciò che facevo con ZF1
Fare con Zend Framework 2 ciò che facevo con ZF1Fare con Zend Framework 2 ciò che facevo con ZF1
Fare con Zend Framework 2 ciò che facevo con ZF1Steve Maraspin
 
NoSQL Data Stores: Introduzione alle Basi di Dati Non Relazionali
NoSQL Data Stores: Introduzione alle Basi di Dati Non RelazionaliNoSQL Data Stores: Introduzione alle Basi di Dati Non Relazionali
NoSQL Data Stores: Introduzione alle Basi di Dati Non RelazionaliSteve Maraspin
 
Polyglot Persistance con PostgreSQL, CouchDB, MongoDB, Redis e OrientDB
Polyglot Persistance con PostgreSQL, CouchDB, MongoDB, Redis e OrientDBPolyglot Persistance con PostgreSQL, CouchDB, MongoDB, Redis e OrientDB
Polyglot Persistance con PostgreSQL, CouchDB, MongoDB, Redis e OrientDBSteve Maraspin
 
NoSQL, No Worries: Vecchi Problemi, Nuove Soluzioni
NoSQL, No Worries: Vecchi Problemi, Nuove SoluzioniNoSQL, No Worries: Vecchi Problemi, Nuove Soluzioni
NoSQL, No Worries: Vecchi Problemi, Nuove SoluzioniSteve Maraspin
 
Permettere al cliente di apprezzare l'approccio agile
Permettere al cliente di apprezzare l'approccio agilePermettere al cliente di apprezzare l'approccio agile
Permettere al cliente di apprezzare l'approccio agileSteve Maraspin
 
Let customers appreciate the agile workflow
Let customers appreciate the agile workflowLet customers appreciate the agile workflow
Let customers appreciate the agile workflowSteve Maraspin
 
Esempio di architettura distribuita basata su PHP, CouchDB e Mobile
Esempio di architettura distribuita basata su PHP, CouchDB e MobileEsempio di architettura distribuita basata su PHP, CouchDB e Mobile
Esempio di architettura distribuita basata su PHP, CouchDB e MobileSteve Maraspin
 
Striving towards better PHP code
Striving towards better PHP codeStriving towards better PHP code
Striving towards better PHP codeSteve Maraspin
 

Plus de Steve Maraspin (19)

Architetture a Microservizi (con Kubernetes)
Architetture a Microservizi (con Kubernetes)Architetture a Microservizi (con Kubernetes)
Architetture a Microservizi (con Kubernetes)
 
How Agile changed Software Development
How Agile changed Software DevelopmentHow Agile changed Software Development
How Agile changed Software Development
 
Principi di Interaction Design
Principi di Interaction DesignPrincipi di Interaction Design
Principi di Interaction Design
 
Customer Journey Mapping Workshop
Customer Journey Mapping WorkshopCustomer Journey Mapping Workshop
Customer Journey Mapping Workshop
 
A (really) Quick Introduction to Event Storming
A (really) Quick Introduction to Event StormingA (really) Quick Introduction to Event Storming
A (really) Quick Introduction to Event Storming
 
Don't Make Me Think - There's no need (2014)
Don't Make Me Think - There's no need (2014)Don't Make Me Think - There's no need (2014)
Don't Make Me Think - There's no need (2014)
 
The Metaphor Fallacy (in Digital Product Development)
The Metaphor Fallacy (in Digital Product Development)The Metaphor Fallacy (in Digital Product Development)
The Metaphor Fallacy (in Digital Product Development)
 
Lean UX: Sviluppo Software Agile e Incentrato sull'Utente
Lean UX: Sviluppo Software Agile e Incentrato sull'UtenteLean UX: Sviluppo Software Agile e Incentrato sull'Utente
Lean UX: Sviluppo Software Agile e Incentrato sull'Utente
 
La filosofia Lean nello sviluppo di prodotti digitali
La filosofia Lean nello sviluppo di prodotti digitaliLa filosofia Lean nello sviluppo di prodotti digitali
La filosofia Lean nello sviluppo di prodotti digitali
 
Outcome not Output: A Story of Lean UX Adoption
Outcome not Output: A Story of Lean UX AdoptionOutcome not Output: A Story of Lean UX Adoption
Outcome not Output: A Story of Lean UX Adoption
 
Don't Make me Think - There's no Need
Don't Make me Think - There's no NeedDon't Make me Think - There's no Need
Don't Make me Think - There's no Need
 
Fare con Zend Framework 2 ciò che facevo con ZF1
Fare con Zend Framework 2 ciò che facevo con ZF1Fare con Zend Framework 2 ciò che facevo con ZF1
Fare con Zend Framework 2 ciò che facevo con ZF1
 
NoSQL Data Stores: Introduzione alle Basi di Dati Non Relazionali
NoSQL Data Stores: Introduzione alle Basi di Dati Non RelazionaliNoSQL Data Stores: Introduzione alle Basi di Dati Non Relazionali
NoSQL Data Stores: Introduzione alle Basi di Dati Non Relazionali
 
Polyglot Persistance con PostgreSQL, CouchDB, MongoDB, Redis e OrientDB
Polyglot Persistance con PostgreSQL, CouchDB, MongoDB, Redis e OrientDBPolyglot Persistance con PostgreSQL, CouchDB, MongoDB, Redis e OrientDB
Polyglot Persistance con PostgreSQL, CouchDB, MongoDB, Redis e OrientDB
 
NoSQL, No Worries: Vecchi Problemi, Nuove Soluzioni
NoSQL, No Worries: Vecchi Problemi, Nuove SoluzioniNoSQL, No Worries: Vecchi Problemi, Nuove Soluzioni
NoSQL, No Worries: Vecchi Problemi, Nuove Soluzioni
 
Permettere al cliente di apprezzare l'approccio agile
Permettere al cliente di apprezzare l'approccio agilePermettere al cliente di apprezzare l'approccio agile
Permettere al cliente di apprezzare l'approccio agile
 
Let customers appreciate the agile workflow
Let customers appreciate the agile workflowLet customers appreciate the agile workflow
Let customers appreciate the agile workflow
 
Esempio di architettura distribuita basata su PHP, CouchDB e Mobile
Esempio di architettura distribuita basata su PHP, CouchDB e MobileEsempio di architettura distribuita basata su PHP, CouchDB e Mobile
Esempio di architettura distribuita basata su PHP, CouchDB e Mobile
 
Striving towards better PHP code
Striving towards better PHP codeStriving towards better PHP code
Striving towards better PHP code
 

Dernier

Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityWSO2
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Bhuvaneswari Subramani
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 

Dernier (20)

Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 

Error Reporting in ZF2: form messages, custom error pages, logging

  • 1. Error Reporting in Zend Framework 2 Zend Framework Day – Turin, Italy – 07/02/2014
  • 11.
  • 15. User Input = Mistake Source
  • 17. User Privacy Concerns • Over 40% of online shoppers are very concerned over the use of personal information • Public opinion polls have revealed a general desire among Internet users to protect their privacy Online Privacy: A Growing Threat. - Business Week, March 20, 2000, 96. Internet Privacy in ECommerce: Framework, Review, and Opportunities for Future Research - Proceedings of the 41st Hawaii International Conference on System Sciences - 2008
  • 21. 21
  • 22. Creating A Form in ZF2 <?php namespace ApplicationForm; use ZendFormForm; class ContactForm extends Form { public function __construct() { parent::__construct(); // ... } //... }
  • 23. Creating A Form in ZF2 <?php namespace ApplicationForm; use ZendFormForm; class ContactForm extends Form { public function __construct() { parent::__construct(); // ... } //... }
  • 24. Adding Form Fields public function init() { $this->setName('contact'); $this->setAttribute('method', 'post'); […].. $this->add(array('name' => 'email', 'type' => 'text', 'options' => array( 'label' => 'Name', ), ); $this->add(array('name' => 'message', 'type' => 'textarea', 'options' => array( 'label' => 'Message', ), ); //. […].. }
  • 25. Adding Form Fields public function init() { $this->setName('contact'); $this->setAttribute('method', 'post'); […].. $this->add(array('name' => 'email', 'type' => 'text', 'options' => array( 'label' => 'Name', ), ); $this->add(array('name' => 'message', 'type' => 'textarea', 'options' => array( 'label' => 'Message', ), ); //. […].. }
  • 28. Validation: inputFilter <?php namespace ApplicationForm; […] class ContactFilter extends InputFilter { public function __construct() { // filters go here } }
  • 29. Validation: inputFilter <?php namespace ApplicationForm; […] class ContactFilter extends InputFilter { public function __construct() { // filters go here } }
  • 30. Required Field Validation $this->add(array( 'name' => 'email', 'required' => true, 'filters' => array( array( 'name' => 'StringTrim'), ), 'validators' => array( array( 'name' => 'EmailAddress', ) ) ));
  • 31. Required Field Validation $this->add(array( 'name' => 'email', 'required' => true, 'filters' => array( array( 'name' => 'StringTrim'), ), 'validators' => array( array( 'name' => 'EmailAddress', ) ) ));
  • 32. InputFilter Usage <?php namespace ApplicationController; […] class IndexController extends AbstractActionController { public function contactAction() { $form = new Contact(); $filter = new ContactFilter(); $form->setInputFilter($filter); return new ViewModel(array( 'form' => $form ); } }
  • 33. InputFilter Usage <?php namespace ApplicationController; […] class IndexController extends AbstractActionController { public function contactAction() { $form = new Contact(); $filter = new ContactFilter(); $form->setInputFilter($filter); return new ViewModel(array( 'form' => $form ); } }
  • 36. Error Message Customization $this->add(array( 'name' => 'email', 'required' => true, 'filters' => array( array('name' => 'StringTrim'), ), 'validators' => array( array('name' =>'NotEmpty', 'options' => array( 'messages' => array( NotEmpty::IS_EMPTY => 'We need an '. 'e-mail address to be able to get back to you' ), ), ), array('name' => 'EmailAddress'), ) ));
  • 37. Error Message Customization $this->add(array( 'name' => 'email', 'required' => true, 'filters' => array( array('name' => 'StringTrim'), ), 'validators' => array( array('name' =>'NotEmpty', 'options' => array( 'messages' => array( NotEmpty::IS_EMPTY => 'We need an '. 'e-mail address to be able to get back to you' ), ), ), array('name' => 'EmailAddress'), ) ));
  • 38. More than we need…
  • 39. Check Chain $this->add(array( 'name' => 'email', 'required' => true, 'filters' => array( array('name' => 'StringTrim'), ), 'validators' => array( array('name' =>'NotEmpty', 'options' => array( 'messages' => array( NotEmpty::IS_EMPTY => 'We need an '. 'e-mail address to be able to get back to you' ), ), 'break_chain_on_failure' => true, ), array('name' => 'EmailAddress'), ) ));
  • 42.
  • 43.
  • 45. A few tips: • • • 45 Provide the user with a solution to the problem Do not use technical jargon, use terminology that your audience understands Avoid uppercase text and exclamation points
  • 47. Condensing N messages into 1 $this->add(array( 'name' => 'email', 'required' => true, 'validators' => array( array('name' =>'NotEmpty', 'options' => array( 'messages' => array( NotEmpty::IS_EMPTY => 'We need an '. 'e-mail address to be able to get back to you' )), 'break_chain_on_failure' => true, ), array('name' => 'EmailAddress', 'options' => array( 'message' => 'E-Mail address does not seem to be valid. Please make sure it contains the @ symbol and a valid domain name.', )));
  • 48. Condensing N messages into 1 $this->add(array( 'name' => 'email', 'required' => true, 'validators' => array( array('name' =>'NotEmpty', 'options' => array( 'messages' => array( NotEmpty::IS_EMPTY => 'We need an '. 'e-mail address to be able to get back to you' )), 'break_chain_on_failure' => true, ), array('name' => 'EmailAddress', 'options' => array( 'message' => 'E-Mail address does not seem to be valid. Please make sure it contains the @ symbol and a valid domain name.', )));
  • 49. Messages VS message $this->add(array( 'name' => 'email', 'required' => true, 'validators' => array( array('name' =>'NotEmpty', 'options' => array( 'messages' => array( NotEmpty::IS_EMPTY => 'We need an '. 'e-mail address to be able to get back to you' )), 'break_chain_on_failure' => true, ), array('name' => 'EmailAddress', 'options' => array( 'message' => 'E-Mail address does not seem to be valid. Please make sure it contains the @ symbol and a valid domain name.', )));
  • 51. Default Message Translation public function onBootstrap(MvcEvent $e) { $translator = $e->getApplication() ->getServiceManager()->get('translator'); $translator->addTranslationFile( 'phpArray', __DIR__ . '/../../vendor/zendframework/zendframework/'. 'resources/languages/it/Zend_Validate.php', 'default', 'it_IT' ); AbstractValidator::setDefaultTranslator($translator); }
  • 52. Custom Message Translation $this->add(array( 'name' => 'email', 'required' => true, 'validators' => array( array('name' =>'NotEmpty', 'options' => array( 'translator' => $translator, 'message' => $translator->translate( 'Make sure your e-mail address contains the @ symbol and a valid domain name.' )), 'break_chain_on_failure' => true, ), )));
  • 53. Form Factory $translator = $I_services->get('translator'); $I_form = new Contact(); $I_filter = new ContactFilter($translator); $I_form->setInputFilter($I_filter); return $I_form;
  • 56. 56
  • 57.
  • 58. Error Display Configuration Skeleton Applicaton Configuration
  • 59. Hiding Exception Traces 'view_manager' => array( 'display_not_found_reason' => false, 'display_exceptions' => false, 'doctype' => 'HTML5', 'not_found_template' => 'error/404', 'exception_template' => 'error/index', 'template_map' => array( 'layout/layout' => __DIR__ . '/../view/layout/layout.phtml', 'application/index/index'=> __DIR__ . '/../view/application/index/index.phtml', 'error/404' => __DIR__ . '/../view/error/404.phtml', 'error/index' => __DIR__ . '/../view/error/index.phtml', ), 'template_path_stack' => array( __DIR__ . '/../view', ), ),
  • 60. Hiding Exception Traces 'view_manager' => array( 'display_not_found_reason' => false, 'display_exceptions' => false, 'doctype' => 'HTML5', 'not_found_template' => 'error/404', 'exception_template' => 'error/index', 'template_map' => array( 'layout/layout' => __DIR__ . '/../view/layout/layout.phtml', 'application/index/index'=> __DIR__ . '/../view/application/index/index.phtml', 'error/404' => __DIR__ . '/../view/error/404.phtml', 'error/index' => __DIR__ . '/../view/error/index.phtml', ), 'template_path_stack' => array( __DIR__ . '/../view', ), ),
  • 61.
  • 62. Custom Error Pages 'view_manager' => array( 'display_not_found_reason' => false, 'display_exceptions' => false, 'doctype' => 'HTML5', 'not_found_template' => 'error/404', 'exception_template' => 'error/index', 'template_map' => array( 'layout/layout' => __DIR__ . '/../view/layout/layout.phtml', 'application/index/index'=> __DIR__ . '/../view/application/index/index.phtml', 'error/404' => __DIR__ . '/../view/error/404.phtml', 'error/index' => __DIR__ . '/../view/error/index.phtml', ), 'template_path_stack' => array( __DIR__ . '/../view', ), ),
  • 63.
  • 64. How about PHP Errors? class IndexController extends AbstractActionController { public function indexAction() { 1/0; return new ViewModel(); } }
  • 65. How about PHP Errors? class IndexController extends AbstractActionController { public function indexAction() { 1/0; return new ViewModel(); } }
  • 66.
  • 68. What can we do?
  • 69. Handling PHP Errors public function onBootstrap(MvcEvent $I_e) { […] set_error_handler(array('ApplicationModule','handlePhpErrors')); } public static function handlePhpErrors($i_type, $s_message, $s_file, $i_line) { if (!($i_type & error_reporting())) { return }; throw new Exception("Error: " . $s_message . " in file " . $s_file . " at line " . $i_line); }
  • 70. What happens now? class IndexController extends AbstractActionController { public function indexAction() { 1/0; return new ViewModel(); } }
  • 71.
  • 72. Now… what if? class IndexController extends AbstractActionController { public function indexAction() { $doesNotExist->doSomething(); return new ViewModel(); } }
  • 73. Fatal error: Call to a member function doSomething() on a non-object in /srv/apps/zfday/module/Application/src/Application/Controller/IndexController.php on line 20
  • 75. Fatal Error Handling public function onBootstrap(MvcEvent $I_e) { […] $am_config = $I_application->getConfig(); $am_environmentConf = $am_config['mvlabs_environment']; // Fatal Error Recovery if (array_key_exists('recover_from_fatal', $am_environmentConf) && $am_environmentConf['recover_from_fatal']) { $s_redirectUrl = $am_environmentConf['redirect_url']; } $s_callback = null; if (array_key_exists('fatal_errors_callback', $am_environmentConf)) { $s_callback = $am_environmentConf['fatal_errors_callback']; } register_shutdown_function(array('ApplicationModule', 'handleFatalPhpErrors'), $s_redirectUrl, $s_callback); }
  • 76. Fatal Error Handling /** * Redirects user to nice page after fatal has occurred */ public static function handleFatalPhpErrors($s_redirectUrl, $s_callback = null) { if (php_sapi_name() != 'cli' && @is_Array($e = @get_last())) { if (null != $s_callback) { // This is the most stuff we can get. // New context outside of framework scope $m_code = isset($e['type']) ? $e['type'] : 0; $s_msg = isset($e['message']) ? $e['message']:''; $s_file = isset($e['file']) ? $e['file'] : ''; $i_line = isset($e['line']) ? $e['line'] : ''; $s_callback($s_msg, $s_file, $i_line); } header("location: ". $s_redirectUrl); } return false; }
  • 77. Fatal Error Handling 'mvlabs_environment' => array( 'exceptions_from_errors' => true, 'recover_from_fatal' => true, 'fatal_errors_callback' => function($s_msg, $s_file, $s_line) { return false; }, 'redirect_url' => '/error', 'php_settings' => array( 'error_reporting' => E_ALL, 'display_errors' => 'Off', 'display_startup_errors' => 'Off', ), ),
  • 78. PHP Settings Conf 'mvlabs_environment' => array( 'exceptions_from_errors' => true, 'recover_from_fatal' => true, 'fatal_errors_callback' => function($s_msg, $s_file, $s_line) { return false; }, 'redirect_url' => '/error', 'php_settings' => array( 'error_reporting' => E_ALL, 'display_errors' => 'Off', 'display_startup_errors' => 'Off', ), ),
  • 79. PHP Settings public function onBootstrap(MvcEvent $I_e) { […] foreach($am_phpSettings as $key => $value) { ini_set($key, $value); } }
  • 81. CUSTOMER SUPPORT TEAM REACTION http://www.flickr.com/photos/18548283@N00/8030280738
  • 82.
  • 87. Index.php // Application wide configuration $am_conf = $am_originalConf = require 'config/application.config.php'; // Environment specific configuration $s_environmentConfFile = 'config/application.'.$s_env.'.config.php'; if (file_exists($s_environmentConfFile) && is_readable($s_environmentConfFile)) { // Specific environment configuration merge $am_environmentConf = require $s_environmentConfFile; $am_conf = ZendStdlibArrayUtils::merge($am_originalConf, $am_environmentConf ); } // Additional Specific configuration files are also taken into account $am_conf["module_listener_options"]["config_glob_paths"][] = 'config/autoload/{,*.}' . $s_env . '.php'; ZendMvcApplication::init($am_conf)->run();
  • 90. Enabling Environment Confs // Application nominal environment $am_conf = $am_originalConf = require 'config/application.config.php'; // Environment specific configuration $s_environmentConfFile = 'config/application.'.$s_env.'.config.php'; // Do we have a specific configuration file? if (file_exists($s_environmentConfFile) && is_readable($s_environmentConfFile)) { // Specific environment configuration merge $am_environmentConf = require $s_environmentConfFile; $am_conf = ZendStdlibArrayUtils::merge($am_originalConf, $am_environmentConf ); } // Additional Specific configuration files are also taken into account $am_conf["module_listener_options"]["config_glob_paths"][] = 'config/autoload/{,*.}' . $s_env . '.php'; ZendMvcApplication::init($am_conf)->run();
  • 92. index.php Check // What environment are we in? $s_env = getenv('APPLICATION_ENV'); if (empty($s_env)) { throw new Exception('Environment not set.'. ' Cannot continue. Too risky!'); }
  • 93. Apache Config File <VirtualHost *:80> DocumentRoot /srv/apps/zfday/public ServerName www.dev.zfday.it SetEnv APPLICATION_ENV "dev" <Directory /srv/apps/zfday/public> AllowOverride FileInfo </Directory> </VirtualHost>
  • 95. Why Log? Troubleshooting • Stats Generation • Compliance • 95
  • 96. Zend Log $logger = new ZendLogLogger; $writer = new ZendLogWriterStream('/var/log/app.log'); $logger->addWriter($writer); $logger->info('Informational message'); $logger->log(ZendLogLogger::EMERG, 'Emergency message');
  • 97. Zend Log $logger = new ZendLogLogger; $writer = new ZendLogWriterStream('/var/log/app.log'); $logger->addWriter($writer); $logger->info('Informational message'); $logger->log(ZendLogLogger::EMERG, 'Emergency message'); ZendLogLogger::registerErrorHandler($logger); ZendLogLogger::registerExceptionHandler($logger);
  • 105. Filter Example $logger = new ZendLogLogger; $writer1 = new ZendLogWriterStream('/var/log/app.log'); $logger->addWriter($writer1); $writer2 = new ZendLogWriterStream('/var/log/err.log'); $logger->addWriter($writer2); $filter = new ZendLogFilterPriority(Logger::CRIT); $writer2->addFilter($filter); $logger->info('Informational message'); $logger->log(ZendLogLogger::CRIT, 'Emergency message');
  • 106. Monolog use MonologLogger; use MonologHandlerStreamHandler; $log = new Logger('name'); $log->pushHandler(new StreamHandler('/var/log/app.log', Logger::WARNING)); $log->addWarning('Foo'); $log->addError('Bar');
  • 108. How to log? class IndexController { public function helloAction() { return new ViewModel('msg' =>"Hello!"); } }
  • 110. Logging Within Controller class GreetingsController { public function helloAction() { $I_logger = new Logger(); $I_logger->log("We just said Hello!"); return new ViewModel('msg' =>"Hello!"); } }
  • 111. Single Responsability Violation class GreetingsController { public function helloAction() { $I_logger = new Logger(); $I_logger->log("We just said Hello!"); return new ViewModel('msg' =>"Hello!"); } }
  • 112. Fat Controllers class GreetingsController { public function helloAction() { $I_logger = new Logger(); $I_logger->log("We just said Hello!"); $I_mailer = new Mailer(); $I_mailer->mail($s_msg); $I_queue = new Queue(); $I_queue->add($s_msg); return new ViewModel('msg' =>"Hello!"); } }
  • 114. What can we do?
  • 115. Handling Events class Module { public function onBootstrap(MvcEvent $e) { $eventManager = $e->getApplication() ->getEventManager(); $moduleRouteListener = new ModuleRouteListener(); $moduleRouteListener->attach($eventManager); $logger = $sm->get('logger'); $eventManager->attach('wesaidHello', function(MvcEvent $event) use ($logger) { $logger->log($event->getMessage()); ); } }
  • 116. Triggering An Event class GreetingsController { public function helloAction() { $this->eventManager ->trigger('wesaidHello', $this, array('greeting' => 'Hello!') ); return new ViewModel('msg' => "Hello!"); } }
  • 121. Handling Framework Errors class Module { public function onBootstrap(MvcEvent $e) { $eventManager = $e->getApplication() ->getEventManager(); $moduleRouteListener = new ModuleRouteListener(); $moduleRouteListener->attach($eventManager); $logger = $sm->get('logger'); $eventManager->attach(MvcEvent::EVENT_RENDER_ERROR, function(MvcEvent $e) use ($logger) { $logger->info('An exception has Happened ' . $e->getResult()->exception->getMessage()); }, -200); ); } }
  • 123. Stuff to take home 1. 2. 3. 123 When reporting errors, make sure to be nice with users Different error reporting strategies could be useful for different environments The event manager reduces coupling and provides flexibility
  • 124.
  • 125.
  • 126.
  • 129. Starting Things Up input { stdin { } } output { stdout { codec => rubydebug } }
  • 130. Starting Things Up input { stdin { } } output { stdout { codec => rubydebug } } java -jar logstash-1.3.3-flatjar.jar agent -f sample.conf
  • 131. Integrated Elasticsearch input { file { path => ["/opt/logstash/example.log"] } } output { stdout { codec => rubydebug } elasticsearch { embedded => true } } java -jar logstash-1.3.3-flatjar.jar agent -f elastic.conf
  • 132. Integrated Web Interface input { file { path => ["/opt/logstash/example.log"] } } output { stdout { codec => rubydebug } elasticsearch { embedded => true } } java -jar logstash.jar agent -f elastic.conf --web
  • 133. Kibana
  • 134. Thank you for your attention Stefano Maraspin @maraspin