SlideShare ist ein Scribd-Unternehmen logo
1 von 90
Downloaden Sie, um offline zu lesen
The Art Of Application
       Logging
                 PHPNW 2012

             Ben Waine - @bwaine

http://github.com/benwaine/ApplicationLoggingTalk
Kicking Ass And
      Logging Names
                 PHPNW 2012

             Ben Waine - @bwaine

http://github.com/benwaine/ApplicationLoggingTalk
Ben Waine
Contractor / Co Founder
       Recensus

    PHP Developer

  Logs in spare time....
Roadmap

• Introduction - Why Is Logging Good?
• The Mechanics - Code / Examples / Live Demos (GULP)
• Logging Strategy - What to do with your logs
• Conclusion
Roadmap

• Introduction - Why Is Logging Good?
• The Mechanics - Code / Examples / Live Demos (GULP)
• Logging Strategy - What to do with your logs
• Conclusion
Name Some Logs.....
Name Some Logs.....
The Benefits Logs
    Provide
tail -f
• Insight into how a process is being
  executed
• Ability to analyse execution after the fact
• Ability to catch information about
  execution errors
• Look for patterns and trends
These are all
services......
What about application
      logging?
I




    SKYBET’s Log
Benefits For Beginners
• Provide direction when picking up an
  application for the first time.
• Well sign posted layers increases
  understanding of the request.
• Quick error isolation and context
• Times in logs keep performance prominent
Benefits For Everyone
Roadmap
• Introduction - Why Is Logging Good?
• The Mechanics - Code / Examples / Live
Demos (GULP)

• Logging Strategy - What to do with your logs
• Conclusion
Our Logging Goals
Log information about a script which creates users.

          User - Represents a user
    UserMapper - A class which saves users
    Scripts - Control User and UserMapper
1) The Basics


https://github.com/benwaine/ApplicationLoggingTalk/tree/master/
                                     examples/01-NativeLogging
error_log()
require_once __DIR__ . '/app/User.php';
require_once __DIR__ . '/app/UserMapper.php';
require_once __DIR__ . '/../../vendor/autoload.php';

// Create a mapper
$mapper = new UserMapper();

// Create Users and persist them
error_log('Beginning User Creation');

while(true)
{
    $user = new User(rand(1, 10000), 'Betty Boo');

    $mapper->save($user);

    sleep(1);

    unset($user);
}

                                               01-basic.php
class UserMapper {

    public function save(User $user)
    {

        error_log('Saving User: ' . $user->getId());

        // Code For Saving User

    }

}




                                                UserMapper.php
DEMO
require_once __DIR__ . '/app/User.php';
require_once __DIR__ . '/app/UserMapper.php';
require_once __DIR__ . '/../../vendor/autoload.php';

ini_set('error_log', '/tmp/user.log');

// Create a mapper
$mapper = new UserMapper();

// Create Users and persist them
error_log('Beginning User Creation');

while(true)
{
    $user = new User(rand(1, 10000), 'Betty Boo');

    $mapper->save($user);

    sleep(1);

    unset($user);
}
                                                 02-ToFile.php
Pros
• Native Functionality


Cons
• error_log, semantically correct?
• PHP errors mixed in with application logging
• Not very powerful compared to other tools
2) Logging Library


https://github.com/benwaine/ApplicationLoggingTalk/tree/master/
                          examples/02-LoggingAsADependency
PEARLog
Log4PHP

      Monolog

ZendLog         KLogger
Monolog
https://github.com/Seldaek/monolog
Monolog Architecture
Logger                                     use MonologLogger;
                                           use MonologHandlerStreamHandler;
                                           use MonologHandlerFirePHPHandler;

                                           // Create the logger
            Logger delegates to one        $logger = new Logger('my_logger');
               or more handlers            // Now add some handlers
                                           $logger->pushHandler(new
                                           StreamHandler(__DIR__.'/my_app.log',

Handler
                                           Logger::DEBUG));
                                           $logger->pushHandler(new FirePHPHandler());
FirePHPHandler
                                           // You can now use your logger
                                           $logger->addInfo('My logger is now ready');
             Handlers are placed in
                    a stack

                                                             Log formatting is changed
Handler                               Formatter              using supplied or custom
StreamHandler                           (optional)                  formatters.

Handlers can be used by multiple loggers. Formatters can be used by multiple handlers.
Fingers Crossed Logger
// ... Require Statements ...
use MonologLogger;
use MonologHandlerStreamHandler;

// Create a New MonoLog
$logger = new MonologLogger('Application Log');
// Add a handler (writer)
$logger->pushHandler(new StreamHandler('/tmp/user.log',
Logger::DEBUG));

// Create a mapper
$mapper = new UserMapper($logger);

// Create Users and persist them
$logger->notice('Beginning User Creation');

while(true)
{
    $user = new User(rand(1, 10000), 'Betty Boo');
    $mapper->save($user);
    sleep(1);
    unset($user);
}
                                                     01-basic.php
use MonologLogger;

class UserMapper {

    protected $logger;

    public function __construct(Logger $logger)
    {
        $this->logger = $logger;
    }

    public function save(User $user)
    {

        $this->logger->info('Saving User: ' . $user->getID());

        // Code For Saving User

    }

}

                                                  UserMapper.php
DEMO
Pros
• Object Oriented Logging
• Multiple Log Writers (File, Email, Firebug, StdOut)
• Log Levels (See Example)
Cons

• ‘Unwieldy’ instantiation
• Logging control code permeates application
  layer
Log Levels
RFC: 5434
(The Syslog Protocol)
 0   Emergency: system is unusable
 1   Alert: action must be taken immediately
 2   Critical: critical conditions
 3   Error: error conditions
 4   Warning: warning conditions
 5   Notice: normal but significant condition
 6   Informational: informational messages
 7   Debug: debug-level messages
use MonologLogger;
use MonologHandlerStreamHandler;

$environment = getenv('ENVIRONMENT');
$level = ($environment == "live") ? Logger::NOTICE : Logger::DEBUG;

// Create a New MonoLog
$logger = new MonologLogger('Application Log');
// Add a handler (writer)
$logger->pushHandler(new StreamHandler('/tmp/user.log', $level));
// Create a mapper
$mapper = new UserMapper($logger);

// Create Users and persist them
$logger->notice('Beginning User Creation');

while(true)
{
    $user = new User(rand(1, 10000), 'Betty Boo');

    $mapper->save($user);

    sleep(1);

    unset($user);                                    02-LogLevels.php
}
use MonologLogger;

class UserMapper {

    protected $logger;

    public function __construct(Logger $logger)
    {
        $this->logger = $logger;
    }

    public function save(User $user)
    {

        $this->logger->info('Saving User: ' . $user->getID());

        // Code For Saving User

    }

}

                                                  UserMapper.php
DEMO
3) Your Application Logger


https://github.com/benwaine/ApplicationLoggingTalk/tree/master/
                          examples/03-YourApplicationLogClass
public function __construct(MLogger $application,
                            MLogger $security,
                            array $requestParams) {

    $this->application = $application;
    $this->security = $security;
    $this->requestParams = $requestParams;

    $this->requestId =
       md5(microtime() .
       $this->requestParams['REMOTE_ADDR']);
}




                             Logger.php - __constructor
/**
 * Adds a record to the application log.
 *
 * @param string $message
 * @param int $level
 *
 * @return void
 */
public function applicationLog($message, $level) {

    // Including a request identifier allows us to track a
    // users progress throughout the application by grepping the ID.

    $context = array('RID' => $this->requestId);

    $this->application->addRecord($level, $message, $context);
}




                                      Logger.php - applicationLog
// Create first logger (application)
$applicationLogger = new MonoLogger('Application');
// Add a handler (writer)
$applicationLogger->pushHandler(new StreamHandler('/tmp/
application.log', MonoLogger::DEBUG));

// Create second logger (security)
$securityLogger = new MonoLogger('Security');
$securityLogger->pushHandler(new StreamHandler('/tmp/security.log',
MonoLogger::DEBUG));

$logger = new Logger($applicationLogger, $securityLogger,
$requestParams);

// Create a mapper
$mapper = new UserMapper($logger);




                                                   01-basic.php 1/2
// Create Users and persist them
$logger->applicationLog('Beginning User Creation', Logger::INFO);

for($x = 0; $x <= 4; $x++)
{
    $user = new User(rand(1, 10000), 'Betty Boo');

    // The mapper generates some informational logs when the
    // the user record is 'saved'
    $mapper->save($user);
    unset($user);

    if($x % 2) {

        // Simulate some kind of security warning when creating some
        // of the users.
        $logger->securityLog('UNSAFE USER!', Logger::WARNING);
    }
}

$logger->applicationLog('Ending User Creation', Logger::INFO);

                                                     01-basic.php 2/2
DEMO
BEN TURN ON THE
OTHER EXAMPLE NOW.




               Thanks.
Pros
• Consolidated logging control logic
• Encapsulate common logging actions

Cons

• Still ‘Unwieldy’ instantiation
• Can be a little inflexible
4) Your Application Logger
         (DI’ed)

https://github.com/benwaine/ApplicationLoggingTalk/tree/master/
                             examples/04-DiConfiguredLogging
parameters:
    logger.class:      Logger
    logger.security.path: /tmp/security.log
    logger.security.name: security
    logger.security.level: 200
    logger.application.path: /tmp/application.log
    logger.application.name: application
    logger.application.level: 200
    logger.monolog.class: MonologLogger
    logger.monolog.handlerClass: MonologHandlerStreamHandler
    user.mapper.class: UserMapper
    request.params:
      REMOTE_ADDR:
        - 127.0.0.1




                                                 services.yml 1/2
services:
    logger:
        class: %logger.class%
        arguments: [@applog, @seclog, %request.params%]
    seclog:
        class: %logger.monolog.class%
        arguments: [%logger.security.name%]
        calls:
            - [ pushHandler, [ @seclogHandler ] ]
    applog:
        class: %logger.monolog.class%
        arguments: [%logger.application.name%]
        calls:
            - [ pushHandler, [ @applogHandler ] ]
    seclogHandler:
        class: %logger.monolog.handlerClass%
        arguments: [%logger.security.path%, %logger.security.level%]
    applogHandler:
        class: %logger.monolog.handlerClass%
        arguments: [%logger.application.path%, %logger.application.level%]
    UserMapper:
        class: %user.mapper.class%
        arguments: [@logger]

                                                        services.yml 2/2
// Set Up Container
$container = new ContainerBuilder;
$loader = new YamlFileLoader($container, new FileLocator(__DIR__));
$loader->load("services.yml");

// Get Mapper and Logger
$logger = $container->get('logger');




                                                   01-basic.php 1/2
Me
5) Event Logging


https://github.com/benwaine/ApplicationLoggingTalk/tree/master/
                                   examples/05-StatsDGraphite
Log Entries As Events
 That Occur In Your
      System
Graphite + StatsD
StatsD

• Buckets

• Values

• Flush
// Creating StatsD Client
$connection = new DomniklStatsdConnectionSocket('localhost', 8125);
$statsd = new DomniklStatsdClient($connection, "test.namespace");

// simple count
$statsd->increment("request");
public function logBusinessEvent($event) {

    if(!isset($this->events[$event]))
    {
        throw new Exception('Invalid Logging Event');
    }

    $this->statsd->increment($this->events[$event]);

}



public function logBusinessTime($event, $time)
{
    if(!isset($this->events[$event]))
    {
        throw new Exception('Invalid Logging Event');
    }

    $this->statsd->timing($this->events[$event], $time);
}
                                             Logger.php (extract)
while(true) {

    $number = rand(1, 10);

    for($x = 0; $x <= $number; $x++)
    {

           $user = new User(rand(1, 10000), 'Betty Boo');
           $mapper->save($user);
           $logger->logBusinessEvent(Logger::EVENT_USERCREATED);

           unset($user);

           if($x%2 === 0) {
               // Simulate some kind of security warning when
               // creating some of the users.
               $logger->logBusinessEvent(Logger::EVENT_USERWARNING);
           }
    }

        sleep(rand(1, 15));

}                                          02-example.php (extract)
5) Putting It All Together


https://github.com/benwaine/ApplicationLoggingTalk/tree/master/
                                       examples/06-AllTogether
Roadmap
• Introduction - Why Is Logging Good?
• The Mechanics - Code / Examples / Live Demos (GULP)
• Logging Strategy - What to do with your
logs

• Conclusion
Logging Strategy
                        Style
1) Choose a log format and be consistent

2) Make sure common tasks like formatting and filtering
are dealt with centrally.

3) Choose a set of rules / style around when to log and
be consistent.
Logging Strategy
                      Content
1) Request Start / End (with times and memory)

2) Transition between layers
Eg - Control > Model > DB < Model < Control > View

3) Database Queries

4) Business Events

5) Message Queue Activity

6) PHP Errors / PHP Notices
Logging Strategy
                     Volume
1) Request Start / End (with times and memory) Notice

2) Transition between layers
Eg - Control > Model > DB < Model < Control > View
                                               Info
3) Database Queries Info / Debug

4) Business Events   Separate Log

5) Message Queue Activity Debug

6) PHP Errors / PHP Notices Error
Logging Strategy
                     Audience
1) Make it easy to switch log levels (environment
variables).

2) Always think of your log consumers when adding log
lines.
Grep-able Content


                    Ideas


                            Blameable
Log Aggregation &
  Presentation
RSYSLOG +
LOGSTASH +
  STATSD +
 GRAPHITE
RSYSLOG
•Send Logs Via TCP / UDP To A Central Location
•Use Filters & Templates To Write Logs To Files / Database

     Web                     /var/log/web/%ip-address%/access.log
                             /var/log/web/%ip-address%/error.log
                      LOG    /var/log/db/%ip-address%/query.log
     DB                      /var/log/db/%ip-address%/slow-query.log
LOGSTASH
    input {
      file {
        path => "/var/log/apache/access.log"
        type => "apache-access"
      }
    }

    filter {
      grok {
        type => "apache-access"
        pattern => "%{COMBINEDAPACHELOG}"
      }
    }

    output {
      statsd {
        # Count one hit every event by response
        increment => "apache.response.%{response}"
      }
    }


http://logstash.net/docs/1.1.1/tutorials/metrics-from-logs
LOGSTASH
Inputs           Filters               Outputs

1    amqp         1    checksum        1    amqp                  23   nagios
2    eventlog     2    csv             2    boundary              24   nagios_nsca
3    exec         3    date            3    circonus              25   null
4    file          4    dns             4    datadog               26   opentsdb
5    ganglia      5    environment     5    elasticsearch         27   pagerduty
6    gelf         6    gelfify          6    elasticsearch_http    28   pipe
7    generator    7    grep            7    elasticsearch_river   29   redis
8    heroku       8    grok            8    email                 30   riak
9    irc          9    grokdiscovery   9    file                   31   riemann
10   log4j        10   json            10   ganglia               32   sns
11   pipe         11   multiline       11   gelf                  33   statsd
12   redis        12   mutate          12   graphite              34   stdout
13   stdin        13   noop            13   graphtastic           35   tcp
14   stomp        14   split           14   http                  36   websocket
15   syslog       15   syslog_pri      15   internal              37   xmpp
16   tcp          16   xml             16   irc                   38   zabbix
17   twitter      17   zeromq          17   juggernaut            39   zeromq
18   udp                               18   librato
19   xmpp                              19   loggly
20   zeromq                            20   metriccatcher
                                       21   mongodb
                                       22   stomp
DEMO
Hosted Services
Roadmap

• Introduction - Why Is Logging Good?
• The Mechanics - Code / Examples / Live Demos (GULP)
• Logging Strategy - What to do with your logs
• Conclusion
Fin - Questions?

Ask me to repeat the question. I ALWAYS forget.
Hiring Developers & Testers (Contract / Perm)

            ray.fawcett@orange.com

Weitere ähnliche Inhalte

Was ist angesagt?

Php in 2013 (Web-5 2013 conference)
Php in 2013 (Web-5 2013 conference)Php in 2013 (Web-5 2013 conference)
Php in 2013 (Web-5 2013 conference)julien pauli
 
Caching and tuning fun for high scalability @ FrOSCon 2011
Caching and tuning fun for high scalability @ FrOSCon 2011Caching and tuning fun for high scalability @ FrOSCon 2011
Caching and tuning fun for high scalability @ FrOSCon 2011Wim Godden
 
Ansible loves Python, Python Philadelphia meetup
Ansible loves Python, Python Philadelphia meetupAnsible loves Python, Python Philadelphia meetup
Ansible loves Python, Python Philadelphia meetupGreg DeKoenigsberg
 
Mysqlnd, an unknown powerful PHP extension
Mysqlnd, an unknown powerful PHP extensionMysqlnd, an unknown powerful PHP extension
Mysqlnd, an unknown powerful PHP extensionjulien pauli
 
PHP 5.6 New and Deprecated Features
PHP 5.6  New and Deprecated FeaturesPHP 5.6  New and Deprecated Features
PHP 5.6 New and Deprecated FeaturesMark Niebergall
 
Ansible tips & tricks
Ansible tips & tricksAnsible tips & tricks
Ansible tips & tricksbcoca
 
The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6Wim Godden
 
LSA2 - 03 Http apache nginx
LSA2 - 03 Http apache nginxLSA2 - 03 Http apache nginx
LSA2 - 03 Http apache nginxMarian Marinov
 
The why and how of moving to php 5.4
The why and how of moving to php 5.4The why and how of moving to php 5.4
The why and how of moving to php 5.4Wim Godden
 
Fluentd v1.0 in a nutshell
Fluentd v1.0 in a nutshellFluentd v1.0 in a nutshell
Fluentd v1.0 in a nutshellN Masahiro
 
PHP BASIC PRESENTATION
PHP BASIC PRESENTATIONPHP BASIC PRESENTATION
PHP BASIC PRESENTATIONkrutitrivedi
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterZendCon
 
PHP & Performance
PHP & PerformancePHP & Performance
PHP & Performance毅 吕
 
An introduction to Laravel Passport
An introduction to Laravel PassportAn introduction to Laravel Passport
An introduction to Laravel PassportMichael Peacock
 
A History of PHP
A History of PHPA History of PHP
A History of PHPXinchen Hui
 

Was ist angesagt? (20)

Php in 2013 (Web-5 2013 conference)
Php in 2013 (Web-5 2013 conference)Php in 2013 (Web-5 2013 conference)
Php in 2013 (Web-5 2013 conference)
 
Caching and tuning fun for high scalability @ FrOSCon 2011
Caching and tuning fun for high scalability @ FrOSCon 2011Caching and tuning fun for high scalability @ FrOSCon 2011
Caching and tuning fun for high scalability @ FrOSCon 2011
 
PHP 7 new engine
PHP 7 new enginePHP 7 new engine
PHP 7 new engine
 
Ansible loves Python, Python Philadelphia meetup
Ansible loves Python, Python Philadelphia meetupAnsible loves Python, Python Philadelphia meetup
Ansible loves Python, Python Philadelphia meetup
 
Mysqlnd, an unknown powerful PHP extension
Mysqlnd, an unknown powerful PHP extensionMysqlnd, an unknown powerful PHP extension
Mysqlnd, an unknown powerful PHP extension
 
PHP 5.6 New and Deprecated Features
PHP 5.6  New and Deprecated FeaturesPHP 5.6  New and Deprecated Features
PHP 5.6 New and Deprecated Features
 
Ansible tips & tricks
Ansible tips & tricksAnsible tips & tricks
Ansible tips & tricks
 
The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6
 
LSA2 - 03 Http apache nginx
LSA2 - 03 Http apache nginxLSA2 - 03 Http apache nginx
LSA2 - 03 Http apache nginx
 
extending-php
extending-phpextending-php
extending-php
 
The why and how of moving to php 5.4
The why and how of moving to php 5.4The why and how of moving to php 5.4
The why and how of moving to php 5.4
 
Fluentd v1.0 in a nutshell
Fluentd v1.0 in a nutshellFluentd v1.0 in a nutshell
Fluentd v1.0 in a nutshell
 
How PHP works
How PHP works How PHP works
How PHP works
 
Lumberjack XPath 101
Lumberjack XPath 101Lumberjack XPath 101
Lumberjack XPath 101
 
PHP BASIC PRESENTATION
PHP BASIC PRESENTATIONPHP BASIC PRESENTATION
PHP BASIC PRESENTATION
 
Phinx talk
Phinx talkPhinx talk
Phinx talk
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life better
 
PHP & Performance
PHP & PerformancePHP & Performance
PHP & Performance
 
An introduction to Laravel Passport
An introduction to Laravel PassportAn introduction to Laravel Passport
An introduction to Laravel Passport
 
A History of PHP
A History of PHPA History of PHP
A History of PHP
 

Ähnlich wie The Art Of Application Logging PHPNW12

Rein_in_the_ability_of_log4j
Rein_in_the_ability_of_log4jRein_in_the_ability_of_log4j
Rein_in_the_ability_of_log4jRazorsight
 
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiGrâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiJérémy Derussé
 
HTTP Middlewares in PHP by Eugene Dounar
HTTP Middlewares in PHP by Eugene DounarHTTP Middlewares in PHP by Eugene Dounar
HTTP Middlewares in PHP by Eugene DounarMinsk PHP User Group
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)arcware
 
Using and reusing CakePHP plugins
Using and reusing CakePHP pluginsUsing and reusing CakePHP plugins
Using and reusing CakePHP pluginsPierre MARTIN
 
TYPO3 Flow 2.0 (International PHP Conference 2013)
TYPO3 Flow 2.0 (International PHP Conference 2013)TYPO3 Flow 2.0 (International PHP Conference 2013)
TYPO3 Flow 2.0 (International PHP Conference 2013)Robert Lemke
 
Porting Rails Apps to High Availability Systems
Porting Rails Apps to High Availability SystemsPorting Rails Apps to High Availability Systems
Porting Rails Apps to High Availability SystemsMarcelo Pinheiro
 
Symfony2 for Midgard Developers
Symfony2 for Midgard DevelopersSymfony2 for Midgard Developers
Symfony2 for Midgard DevelopersHenri Bergius
 
Dive into Play Framework
Dive into Play FrameworkDive into Play Framework
Dive into Play FrameworkMaher Gamal
 
Do you know what your Drupal is doing_ Observe it!
Do you know what your Drupal is doing_ Observe it!Do you know what your Drupal is doing_ Observe it!
Do you know what your Drupal is doing_ Observe it!sparkfabrik
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkBo-Yi Wu
 
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
 
TDC 2015 - POA - Trilha PHP - Shit Happens
TDC 2015 - POA - Trilha PHP - Shit HappensTDC 2015 - POA - Trilha PHP - Shit Happens
TDC 2015 - POA - Trilha PHP - Shit HappensJackson F. de A. Mafra
 
Lean Php Presentation
Lean Php PresentationLean Php Presentation
Lean Php PresentationAlan Pinstein
 
TYPO3 Flow 2.0 (T3CON13 San Francisco)
TYPO3 Flow 2.0 (T3CON13 San Francisco)TYPO3 Flow 2.0 (T3CON13 San Francisco)
TYPO3 Flow 2.0 (T3CON13 San Francisco)Robert Lemke
 

Ähnlich wie The Art Of Application Logging PHPNW12 (20)

Rein_in_the_ability_of_log4j
Rein_in_the_ability_of_log4jRein_in_the_ability_of_log4j
Rein_in_the_ability_of_log4j
 
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiGrâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
 
HTTP Middlewares in PHP by Eugene Dounar
HTTP Middlewares in PHP by Eugene DounarHTTP Middlewares in PHP by Eugene Dounar
HTTP Middlewares in PHP by Eugene Dounar
 
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
10 Things Every Plugin Developer Should Know (WordCamp Atlanta 2013)
 
Using and reusing CakePHP plugins
Using and reusing CakePHP pluginsUsing and reusing CakePHP plugins
Using and reusing CakePHP plugins
 
TYPO3 Flow 2.0 (International PHP Conference 2013)
TYPO3 Flow 2.0 (International PHP Conference 2013)TYPO3 Flow 2.0 (International PHP Conference 2013)
TYPO3 Flow 2.0 (International PHP Conference 2013)
 
Porting Rails Apps to High Availability Systems
Porting Rails Apps to High Availability SystemsPorting Rails Apps to High Availability Systems
Porting Rails Apps to High Availability Systems
 
Symfony2 for Midgard Developers
Symfony2 for Midgard DevelopersSymfony2 for Midgard Developers
Symfony2 for Midgard Developers
 
Php
PhpPhp
Php
 
Logging
LoggingLogging
Logging
 
Dive into Play Framework
Dive into Play FrameworkDive into Play Framework
Dive into Play Framework
 
Pluggin creation
Pluggin creationPluggin creation
Pluggin creation
 
Do you know what your Drupal is doing_ Observe it!
Do you know what your Drupal is doing_ Observe it!Do you know what your Drupal is doing_ Observe it!
Do you know what your Drupal is doing_ Observe it!
 
Mojolicious
MojoliciousMojolicious
Mojolicious
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
 
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
 
TDC 2015 - POA - Trilha PHP - Shit Happens
TDC 2015 - POA - Trilha PHP - Shit HappensTDC 2015 - POA - Trilha PHP - Shit Happens
TDC 2015 - POA - Trilha PHP - Shit Happens
 
Lean Php Presentation
Lean Php PresentationLean Php Presentation
Lean Php Presentation
 
TYPO3 Flow 2.0 (T3CON13 San Francisco)
TYPO3 Flow 2.0 (T3CON13 San Francisco)TYPO3 Flow 2.0 (T3CON13 San Francisco)
TYPO3 Flow 2.0 (T3CON13 San Francisco)
 
Laravel 5
Laravel 5Laravel 5
Laravel 5
 

Mehr von benwaine

DPC 2016 - 53 Minutes or Less - Architecting For Failure
DPC 2016 - 53 Minutes or Less - Architecting For FailureDPC 2016 - 53 Minutes or Less - Architecting For Failure
DPC 2016 - 53 Minutes or Less - Architecting For Failurebenwaine
 
The Road To Technical Team Lead
The Road To Technical Team LeadThe Road To Technical Team Lead
The Road To Technical Team Leadbenwaine
 
PHPNW14 - Getting Started With AWS
PHPNW14 - Getting Started With AWSPHPNW14 - Getting Started With AWS
PHPNW14 - Getting Started With AWSbenwaine
 
Application Logging With The ELK Stack
Application Logging With The ELK StackApplication Logging With The ELK Stack
Application Logging With The ELK Stackbenwaine
 
Application Logging With Logstash
Application Logging With LogstashApplication Logging With Logstash
Application Logging With Logstashbenwaine
 
Business selectors
Business selectorsBusiness selectors
Business selectorsbenwaine
 
Behat dpc12
Behat dpc12Behat dpc12
Behat dpc12benwaine
 
Acceptance & Integration Testing With Behat (PBC11)
Acceptance & Integration Testing With Behat (PBC11)Acceptance & Integration Testing With Behat (PBC11)
Acceptance & Integration Testing With Behat (PBC11)benwaine
 
Acceptance & Integration Testing With Behat (PHPNw2011)
Acceptance & Integration Testing With Behat (PHPNw2011)Acceptance & Integration Testing With Behat (PHPNw2011)
Acceptance & Integration Testing With Behat (PHPNw2011)benwaine
 
Say no to var_dump
Say no to var_dumpSay no to var_dump
Say no to var_dumpbenwaine
 

Mehr von benwaine (10)

DPC 2016 - 53 Minutes or Less - Architecting For Failure
DPC 2016 - 53 Minutes or Less - Architecting For FailureDPC 2016 - 53 Minutes or Less - Architecting For Failure
DPC 2016 - 53 Minutes or Less - Architecting For Failure
 
The Road To Technical Team Lead
The Road To Technical Team LeadThe Road To Technical Team Lead
The Road To Technical Team Lead
 
PHPNW14 - Getting Started With AWS
PHPNW14 - Getting Started With AWSPHPNW14 - Getting Started With AWS
PHPNW14 - Getting Started With AWS
 
Application Logging With The ELK Stack
Application Logging With The ELK StackApplication Logging With The ELK Stack
Application Logging With The ELK Stack
 
Application Logging With Logstash
Application Logging With LogstashApplication Logging With Logstash
Application Logging With Logstash
 
Business selectors
Business selectorsBusiness selectors
Business selectors
 
Behat dpc12
Behat dpc12Behat dpc12
Behat dpc12
 
Acceptance & Integration Testing With Behat (PBC11)
Acceptance & Integration Testing With Behat (PBC11)Acceptance & Integration Testing With Behat (PBC11)
Acceptance & Integration Testing With Behat (PBC11)
 
Acceptance & Integration Testing With Behat (PHPNw2011)
Acceptance & Integration Testing With Behat (PHPNw2011)Acceptance & Integration Testing With Behat (PHPNw2011)
Acceptance & Integration Testing With Behat (PHPNw2011)
 
Say no to var_dump
Say no to var_dumpSay no to var_dump
Say no to var_dump
 

Kürzlich hochgeladen

Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
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
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 

Kürzlich hochgeladen (20)

Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
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
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 

The Art Of Application Logging PHPNW12

  • 1. The Art Of Application Logging PHPNW 2012 Ben Waine - @bwaine http://github.com/benwaine/ApplicationLoggingTalk
  • 2. Kicking Ass And Logging Names PHPNW 2012 Ben Waine - @bwaine http://github.com/benwaine/ApplicationLoggingTalk
  • 3. Ben Waine Contractor / Co Founder Recensus PHP Developer Logs in spare time....
  • 4.
  • 5.
  • 6. Roadmap • Introduction - Why Is Logging Good? • The Mechanics - Code / Examples / Live Demos (GULP) • Logging Strategy - What to do with your logs • Conclusion
  • 7. Roadmap • Introduction - Why Is Logging Good? • The Mechanics - Code / Examples / Live Demos (GULP) • Logging Strategy - What to do with your logs • Conclusion
  • 12. • Insight into how a process is being executed • Ability to analyse execution after the fact • Ability to catch information about execution errors • Look for patterns and trends
  • 15. I SKYBET’s Log
  • 16.
  • 17.
  • 18.
  • 19.
  • 20. Benefits For Beginners • Provide direction when picking up an application for the first time. • Well sign posted layers increases understanding of the request. • Quick error isolation and context • Times in logs keep performance prominent
  • 22.
  • 23. Roadmap • Introduction - Why Is Logging Good? • The Mechanics - Code / Examples / Live Demos (GULP) • Logging Strategy - What to do with your logs • Conclusion
  • 24. Our Logging Goals Log information about a script which creates users. User - Represents a user UserMapper - A class which saves users Scripts - Control User and UserMapper
  • 27. require_once __DIR__ . '/app/User.php'; require_once __DIR__ . '/app/UserMapper.php'; require_once __DIR__ . '/../../vendor/autoload.php'; // Create a mapper $mapper = new UserMapper(); // Create Users and persist them error_log('Beginning User Creation'); while(true) { $user = new User(rand(1, 10000), 'Betty Boo'); $mapper->save($user); sleep(1); unset($user); } 01-basic.php
  • 28. class UserMapper { public function save(User $user) { error_log('Saving User: ' . $user->getId()); // Code For Saving User } } UserMapper.php
  • 29. DEMO
  • 30. require_once __DIR__ . '/app/User.php'; require_once __DIR__ . '/app/UserMapper.php'; require_once __DIR__ . '/../../vendor/autoload.php'; ini_set('error_log', '/tmp/user.log'); // Create a mapper $mapper = new UserMapper(); // Create Users and persist them error_log('Beginning User Creation'); while(true) { $user = new User(rand(1, 10000), 'Betty Boo'); $mapper->save($user); sleep(1); unset($user); } 02-ToFile.php
  • 31. Pros • Native Functionality Cons • error_log, semantically correct? • PHP errors mixed in with application logging • Not very powerful compared to other tools
  • 33. PEARLog Log4PHP Monolog ZendLog KLogger
  • 35. Monolog Architecture Logger use MonologLogger; use MonologHandlerStreamHandler; use MonologHandlerFirePHPHandler; // Create the logger Logger delegates to one $logger = new Logger('my_logger'); or more handlers // Now add some handlers $logger->pushHandler(new StreamHandler(__DIR__.'/my_app.log', Handler Logger::DEBUG)); $logger->pushHandler(new FirePHPHandler()); FirePHPHandler // You can now use your logger $logger->addInfo('My logger is now ready'); Handlers are placed in a stack Log formatting is changed Handler Formatter using supplied or custom StreamHandler (optional) formatters. Handlers can be used by multiple loggers. Formatters can be used by multiple handlers.
  • 37. // ... Require Statements ... use MonologLogger; use MonologHandlerStreamHandler; // Create a New MonoLog $logger = new MonologLogger('Application Log'); // Add a handler (writer) $logger->pushHandler(new StreamHandler('/tmp/user.log', Logger::DEBUG)); // Create a mapper $mapper = new UserMapper($logger); // Create Users and persist them $logger->notice('Beginning User Creation'); while(true) { $user = new User(rand(1, 10000), 'Betty Boo'); $mapper->save($user); sleep(1); unset($user); } 01-basic.php
  • 38. use MonologLogger; class UserMapper { protected $logger; public function __construct(Logger $logger) { $this->logger = $logger; } public function save(User $user) { $this->logger->info('Saving User: ' . $user->getID()); // Code For Saving User } } UserMapper.php
  • 39. DEMO
  • 40. Pros • Object Oriented Logging • Multiple Log Writers (File, Email, Firebug, StdOut) • Log Levels (See Example) Cons • ‘Unwieldy’ instantiation • Logging control code permeates application layer
  • 42. RFC: 5434 (The Syslog Protocol) 0 Emergency: system is unusable 1 Alert: action must be taken immediately 2 Critical: critical conditions 3 Error: error conditions 4 Warning: warning conditions 5 Notice: normal but significant condition 6 Informational: informational messages 7 Debug: debug-level messages
  • 43. use MonologLogger; use MonologHandlerStreamHandler; $environment = getenv('ENVIRONMENT'); $level = ($environment == "live") ? Logger::NOTICE : Logger::DEBUG; // Create a New MonoLog $logger = new MonologLogger('Application Log'); // Add a handler (writer) $logger->pushHandler(new StreamHandler('/tmp/user.log', $level)); // Create a mapper $mapper = new UserMapper($logger); // Create Users and persist them $logger->notice('Beginning User Creation'); while(true) { $user = new User(rand(1, 10000), 'Betty Boo'); $mapper->save($user); sleep(1); unset($user); 02-LogLevels.php }
  • 44. use MonologLogger; class UserMapper { protected $logger; public function __construct(Logger $logger) { $this->logger = $logger; } public function save(User $user) { $this->logger->info('Saving User: ' . $user->getID()); // Code For Saving User } } UserMapper.php
  • 45. DEMO
  • 46. 3) Your Application Logger https://github.com/benwaine/ApplicationLoggingTalk/tree/master/ examples/03-YourApplicationLogClass
  • 47. public function __construct(MLogger $application, MLogger $security, array $requestParams) { $this->application = $application; $this->security = $security; $this->requestParams = $requestParams; $this->requestId = md5(microtime() . $this->requestParams['REMOTE_ADDR']); } Logger.php - __constructor
  • 48. /** * Adds a record to the application log. * * @param string $message * @param int $level * * @return void */ public function applicationLog($message, $level) { // Including a request identifier allows us to track a // users progress throughout the application by grepping the ID. $context = array('RID' => $this->requestId); $this->application->addRecord($level, $message, $context); } Logger.php - applicationLog
  • 49. // Create first logger (application) $applicationLogger = new MonoLogger('Application'); // Add a handler (writer) $applicationLogger->pushHandler(new StreamHandler('/tmp/ application.log', MonoLogger::DEBUG)); // Create second logger (security) $securityLogger = new MonoLogger('Security'); $securityLogger->pushHandler(new StreamHandler('/tmp/security.log', MonoLogger::DEBUG)); $logger = new Logger($applicationLogger, $securityLogger, $requestParams); // Create a mapper $mapper = new UserMapper($logger); 01-basic.php 1/2
  • 50. // Create Users and persist them $logger->applicationLog('Beginning User Creation', Logger::INFO); for($x = 0; $x <= 4; $x++) { $user = new User(rand(1, 10000), 'Betty Boo'); // The mapper generates some informational logs when the // the user record is 'saved' $mapper->save($user); unset($user); if($x % 2) { // Simulate some kind of security warning when creating some // of the users. $logger->securityLog('UNSAFE USER!', Logger::WARNING); } } $logger->applicationLog('Ending User Creation', Logger::INFO); 01-basic.php 2/2
  • 51. DEMO
  • 52. BEN TURN ON THE OTHER EXAMPLE NOW. Thanks.
  • 53. Pros • Consolidated logging control logic • Encapsulate common logging actions Cons • Still ‘Unwieldy’ instantiation • Can be a little inflexible
  • 54. 4) Your Application Logger (DI’ed) https://github.com/benwaine/ApplicationLoggingTalk/tree/master/ examples/04-DiConfiguredLogging
  • 55. parameters: logger.class: Logger logger.security.path: /tmp/security.log logger.security.name: security logger.security.level: 200 logger.application.path: /tmp/application.log logger.application.name: application logger.application.level: 200 logger.monolog.class: MonologLogger logger.monolog.handlerClass: MonologHandlerStreamHandler user.mapper.class: UserMapper request.params: REMOTE_ADDR: - 127.0.0.1 services.yml 1/2
  • 56. services: logger: class: %logger.class% arguments: [@applog, @seclog, %request.params%] seclog: class: %logger.monolog.class% arguments: [%logger.security.name%] calls: - [ pushHandler, [ @seclogHandler ] ] applog: class: %logger.monolog.class% arguments: [%logger.application.name%] calls: - [ pushHandler, [ @applogHandler ] ] seclogHandler: class: %logger.monolog.handlerClass% arguments: [%logger.security.path%, %logger.security.level%] applogHandler: class: %logger.monolog.handlerClass% arguments: [%logger.application.path%, %logger.application.level%] UserMapper: class: %user.mapper.class% arguments: [@logger] services.yml 2/2
  • 57. // Set Up Container $container = new ContainerBuilder; $loader = new YamlFileLoader($container, new FileLocator(__DIR__)); $loader->load("services.yml"); // Get Mapper and Logger $logger = $container->get('logger'); 01-basic.php 1/2
  • 58. Me
  • 59.
  • 61. Log Entries As Events That Occur In Your System
  • 62.
  • 63.
  • 66. // Creating StatsD Client $connection = new DomniklStatsdConnectionSocket('localhost', 8125); $statsd = new DomniklStatsdClient($connection, "test.namespace"); // simple count $statsd->increment("request");
  • 67. public function logBusinessEvent($event) { if(!isset($this->events[$event])) { throw new Exception('Invalid Logging Event'); } $this->statsd->increment($this->events[$event]); } public function logBusinessTime($event, $time) { if(!isset($this->events[$event])) { throw new Exception('Invalid Logging Event'); } $this->statsd->timing($this->events[$event], $time); } Logger.php (extract)
  • 68. while(true) { $number = rand(1, 10); for($x = 0; $x <= $number; $x++) { $user = new User(rand(1, 10000), 'Betty Boo'); $mapper->save($user); $logger->logBusinessEvent(Logger::EVENT_USERCREATED); unset($user); if($x%2 === 0) { // Simulate some kind of security warning when // creating some of the users. $logger->logBusinessEvent(Logger::EVENT_USERWARNING); } } sleep(rand(1, 15)); } 02-example.php (extract)
  • 69. 5) Putting It All Together https://github.com/benwaine/ApplicationLoggingTalk/tree/master/ examples/06-AllTogether
  • 70. Roadmap • Introduction - Why Is Logging Good? • The Mechanics - Code / Examples / Live Demos (GULP) • Logging Strategy - What to do with your logs • Conclusion
  • 71. Logging Strategy Style 1) Choose a log format and be consistent 2) Make sure common tasks like formatting and filtering are dealt with centrally. 3) Choose a set of rules / style around when to log and be consistent.
  • 72. Logging Strategy Content 1) Request Start / End (with times and memory) 2) Transition between layers Eg - Control > Model > DB < Model < Control > View 3) Database Queries 4) Business Events 5) Message Queue Activity 6) PHP Errors / PHP Notices
  • 73. Logging Strategy Volume 1) Request Start / End (with times and memory) Notice 2) Transition between layers Eg - Control > Model > DB < Model < Control > View Info 3) Database Queries Info / Debug 4) Business Events Separate Log 5) Message Queue Activity Debug 6) PHP Errors / PHP Notices Error
  • 74. Logging Strategy Audience 1) Make it easy to switch log levels (environment variables). 2) Always think of your log consumers when adding log lines.
  • 75. Grep-able Content Ideas Blameable
  • 76. Log Aggregation & Presentation
  • 77. RSYSLOG + LOGSTASH + STATSD + GRAPHITE
  • 78. RSYSLOG •Send Logs Via TCP / UDP To A Central Location •Use Filters & Templates To Write Logs To Files / Database Web /var/log/web/%ip-address%/access.log /var/log/web/%ip-address%/error.log LOG /var/log/db/%ip-address%/query.log DB /var/log/db/%ip-address%/slow-query.log
  • 79. LOGSTASH input { file { path => "/var/log/apache/access.log" type => "apache-access" } } filter { grok { type => "apache-access" pattern => "%{COMBINEDAPACHELOG}" } } output { statsd { # Count one hit every event by response increment => "apache.response.%{response}" } } http://logstash.net/docs/1.1.1/tutorials/metrics-from-logs
  • 80. LOGSTASH Inputs Filters Outputs 1 amqp 1 checksum 1 amqp 23 nagios 2 eventlog 2 csv 2 boundary 24 nagios_nsca 3 exec 3 date 3 circonus 25 null 4 file 4 dns 4 datadog 26 opentsdb 5 ganglia 5 environment 5 elasticsearch 27 pagerduty 6 gelf 6 gelfify 6 elasticsearch_http 28 pipe 7 generator 7 grep 7 elasticsearch_river 29 redis 8 heroku 8 grok 8 email 30 riak 9 irc 9 grokdiscovery 9 file 31 riemann 10 log4j 10 json 10 ganglia 32 sns 11 pipe 11 multiline 11 gelf 33 statsd 12 redis 12 mutate 12 graphite 34 stdout 13 stdin 13 noop 13 graphtastic 35 tcp 14 stomp 14 split 14 http 36 websocket 15 syslog 15 syslog_pri 15 internal 37 xmpp 16 tcp 16 xml 16 irc 38 zabbix 17 twitter 17 zeromq 17 juggernaut 39 zeromq 18 udp 18 librato 19 xmpp 19 loggly 20 zeromq 20 metriccatcher 21 mongodb 22 stomp
  • 81. DEMO
  • 83.
  • 84.
  • 85.
  • 86. Roadmap • Introduction - Why Is Logging Good? • The Mechanics - Code / Examples / Live Demos (GULP) • Logging Strategy - What to do with your logs • Conclusion
  • 87.
  • 88.
  • 89. Fin - Questions? Ask me to repeat the question. I ALWAYS forget.
  • 90. Hiring Developers & Testers (Contract / Perm) ray.fawcett@orange.com