SlideShare une entreprise Scribd logo
1  sur  22
Télécharger pour lire hors ligne
DashProfiler
Lightweight Code Instrumentation




Tim.Bunce@pobox.com - October 2009
A Problem

A web application ~100K lines of code
Using many external services
If response time goes up... what’s causing it?

Continuous monitoring in production
Must have very low CPU and I/O cost
Minimal code changes
A Typical Approach
 package MyNetIO;



 sub send_request {
    my ($hostname, $request) = @_


     ...send to $hostname...


 }



How much time was spent sending the request?
A Typical Approach
               package MyNetIO;

               use Time::Hires qw(time);

               sub send_request {
                  my ($hostname, $request) = @_
                  my $start = time();

                   ...send to $hostname...

                   $durations->{MyNetIO}{$hostname} = time() - $start;
               }

          •   Doesn’t record count so can’t produce averages.
          •   Two lines of code. Worse if multiple return statements.
          •   Doesn’t record time if function exits via an exception.


Still need to write code to flush
A Solution: DashProfiler

        Simple
        Flexible
      Lightweight
DashProfiler

• Can group samples into granular time units

• Can measure exclusive time in a period

• Can flush to disk at intervals

• Just needs one line of code per sample
DashProfiler Internals

Built on DBI::Profile, part of the DBI

Aggregates measurements into a data tree

Two-level tree by default:

  $root->{ $key1 }->{ $key2 }->[ ...leaf node... ]

  $root->{ ‘MyNetIO’ }->{ $hostname }->[ ...leaf node... ]
DashProfiler Data
    Each leaf node in the tree is a reference to an array:

    $root->{ $key1 }->{ $key2      }   = [
        106,                       #   0: count of samples at this node
        0.0312958955764771,        #   1: total duration
        0.000490069389343262,      #   2: first duration
        0.000176072120666504,      #   3: shortest duration
        0.00140702724456787,       #   4: longest duration
        1023115819.83019,          #   5: time of first sample
        1023115819.86576,          #   6: time of last sample
      ]




First sample populates all
Later samples always update 0, 1, and 6
and may update 3 or 4
DashProfiler By-Time

Optional extra time level in the data tree

  $time = int(time() / $granularity) * $granularity;

  $root->{ $time }->{ ‘MyNetIO’ }->{ $hostname }->[ ... ]


So a new sub-tree is grown each granularity seconds
DashProfiler Config
           use DashProfiler;

           DashProfiler->add_profile( foo => { } );

           DashProfiler->add_profile( foo => {
              granularity => 10,
              flush_interval => 600,
              flush_hook => sub { ... },
              sample_class => ‘DashProfiler::Sample’,
              dbi_profile_class => ‘DBI::Profile’,
              period_exclusive => ...,
              period_summary => ...,
              ...
              });




Create named profiles

Lots of features
Without DashProfiler

package MyNetIO;

use Time::Hires qw(time);

sub send_request {
   my ($hostname, $request) = @_
   my $start = time();

    ...send to $hostname...

    $durations->{MyNetIO}{$hostname} = time() - $start;
}
Without DashProfiler

    package MyNetIO;

    use DashProfiler::Import foo_profiler => [ ‘MyNetIO’ ];

    sub send_request {
       my ($hostname, $request) = @_
       my $sample = foo_profiler( $hostname );

        ...send to $hostname...


    }




-                      imports a pre-curried profiler code ref
    DashProfiler::Import

- Profilers return bless object containing timestamp
- Object destruction triggers accumulation of sample
With DashProfiler
                   Name of profile created with add_profile()

                                      Value to use for ‘key1’
package MyNetIO;

use DashProfiler::Import foo_profiler => [ ‘MyNetIO’ ];

sub send_request {
                                      Value to use for ‘key2’
   my ($hostname, $request) = @_
   my $sample = foo_profiler( $hostname );

    ...send to $hostname...


}
       Duration is measured when
       $sample goes out of scope
With DashProfiler

package MyNetIO;

use DashProfiler::Import foo_profiler => [ ‘MyNetIO’ ];

sub send_request {
   my ($hostname, $request) = @_
   my $sample = foo_profiler( $hostname )
       if foo_profiler_enabled();

    ...send to $hostname...
                                   Automatically imported
                                   compile-time constant
}                                    reduces cost to zero
                                    if profile is disabled
DashProfiler Flush
Data is written to STDERR on exit, by default
Regular flushing is enabled by specifying a flush_interval
The dbi_profile_class handles the flush. Choices include:
  DBI::Profile
  DBI::ProfileData
  DBI::ProfileData::Apache

DashProfiler->add_profile( foo => {
   ...,
   flush_interval => 600,
   dbi_profile_class => ‘DBI::ProfileData’,
   flush_hook => sub { ... },
   ...
});
DashProfiler Periods
•   Group samples into periods
    - e.g. http request to response
    -   start_sample_period()   and end_sample_period()
    - counted, to enable averages and totals per period
    - can output period counts instead of sample counts


•   Measure ‘exclusive’ time
    - time from period start to end that’s not been
      accounted for by other samples
    - enabled via period_exclusive option
Example Data
Average response times over 24 hours




           DashProfiler doesn’t generate graphs itself, but the
                 data can be used to create graphs like these
Example Data
Worst case response times over 24 hours
DashProfiler Perspectives
•   Each DashProfiler can have multiple DBI
    Profile objects attached
•   Samples accumulate in all attached profiles
•   Each profile can have a different Path
•   giving different ‘perspectives’ or level of detail
    -   key1 + key2
    -   key1 + country + browser type
    -   key2 + browser type
    -   ... etc.
DashProfiler Per-Period
•   Optional extra ‘per-period’ DBI profile
•   Enabled via period_summary option
•   Automatically attached and reset by
    start_sample_period()

•   Gives current totals for this period
•   Great for ‘debug footers’ on web page showing
    how much time was spent generating this page
DashProfiler Cost

          Time cost of taking a sample:

                  0.000021s


-   Time to create sample object, destroy it, accumulate the counts
-   In hot code can be 0.000015s
-   (Timings made on a 2GHz MacBook Pro Intel Core Duo)
-   (Could be made much faster by porting sampler class to C)
Questions?

 Tim.Bunce@pobox.com
  @timbunce on twitter
 http://blog.timbunce.org

Contenu connexe

Tendances

Study of aloha protocol using ns2 network java proram
Study of aloha protocol using ns2 network java proramStudy of aloha protocol using ns2 network java proram
Study of aloha protocol using ns2 network java proramMeenakshi Devi
 
Python在豆瓣的应用
Python在豆瓣的应用Python在豆瓣的应用
Python在豆瓣的应用Qiangning Hong
 
Groovy Fly Through
Groovy Fly ThroughGroovy Fly Through
Groovy Fly Throughniklal
 
Caching and tuning fun for high scalability
Caching and tuning fun for high scalabilityCaching and tuning fun for high scalability
Caching and tuning fun for high scalabilityWim Godden
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous phpWim Godden
 
PHP 7 – What changed internally?
PHP 7 – What changed internally?PHP 7 – What changed internally?
PHP 7 – What changed internally?Nikita Popov
 
PHP Language Trivia
PHP Language TriviaPHP Language Trivia
PHP Language TriviaNikita Popov
 
Generated Power: PHP 5.5 Generators
Generated Power: PHP 5.5 GeneratorsGenerated Power: PHP 5.5 Generators
Generated Power: PHP 5.5 GeneratorsMark Baker
 
Cs757 ns2-tutorial-exercise
Cs757 ns2-tutorial-exerciseCs757 ns2-tutorial-exercise
Cs757 ns2-tutorial-exercisePratik Joshi
 
Fluency - Yet another fluent logger
Fluency - Yet another fluent loggerFluency - Yet another fluent logger
Fluency - Yet another fluent loggerMitsunori Komatsu
 
Creating Reusable Puppet Profiles
Creating Reusable Puppet ProfilesCreating Reusable Puppet Profiles
Creating Reusable Puppet ProfilesBram Vogelaar
 
Migrating to Puppet 4.0
Migrating to Puppet 4.0Migrating to Puppet 4.0
Migrating to Puppet 4.0Puppet
 
PL/Perl - New Features in PostgreSQL 9.0
PL/Perl - New Features in PostgreSQL 9.0PL/Perl - New Features in PostgreSQL 9.0
PL/Perl - New Features in PostgreSQL 9.0Tim Bunce
 
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, ItalyPHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, ItalyPatrick Allaert
 

Tendances (20)

Study of aloha protocol using ns2 network java proram
Study of aloha protocol using ns2 network java proramStudy of aloha protocol using ns2 network java proram
Study of aloha protocol using ns2 network java proram
 
Python在豆瓣的应用
Python在豆瓣的应用Python在豆瓣的应用
Python在豆瓣的应用
 
Groovy Fly Through
Groovy Fly ThroughGroovy Fly Through
Groovy Fly Through
 
Caching and tuning fun for high scalability
Caching and tuning fun for high scalabilityCaching and tuning fun for high scalability
Caching and tuning fun for high scalability
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous php
 
PHP 7 – What changed internally?
PHP 7 – What changed internally?PHP 7 – What changed internally?
PHP 7 – What changed internally?
 
Automazione quotidiana in php
Automazione quotidiana in phpAutomazione quotidiana in php
Automazione quotidiana in php
 
PHP Language Trivia
PHP Language TriviaPHP Language Trivia
PHP Language Trivia
 
XQuery in the Cloud
XQuery in the CloudXQuery in the Cloud
XQuery in the Cloud
 
Not your Grandma's XQuery
Not your Grandma's XQueryNot your Grandma's XQuery
Not your Grandma's XQuery
 
Generated Power: PHP 5.5 Generators
Generated Power: PHP 5.5 GeneratorsGenerated Power: PHP 5.5 Generators
Generated Power: PHP 5.5 Generators
 
Cs757 ns2-tutorial-exercise
Cs757 ns2-tutorial-exerciseCs757 ns2-tutorial-exercise
Cs757 ns2-tutorial-exercise
 
Fluency - Yet another fluent logger
Fluency - Yet another fluent loggerFluency - Yet another fluent logger
Fluency - Yet another fluent logger
 
XQuery Rocks
XQuery RocksXQuery Rocks
XQuery Rocks
 
Creating Reusable Puppet Profiles
Creating Reusable Puppet ProfilesCreating Reusable Puppet Profiles
Creating Reusable Puppet Profiles
 
High Performance tDiary
High Performance tDiaryHigh Performance tDiary
High Performance tDiary
 
Migrating to Puppet 4.0
Migrating to Puppet 4.0Migrating to Puppet 4.0
Migrating to Puppet 4.0
 
Everything as Code with Terraform
Everything as Code with TerraformEverything as Code with Terraform
Everything as Code with Terraform
 
PL/Perl - New Features in PostgreSQL 9.0
PL/Perl - New Features in PostgreSQL 9.0PL/Perl - New Features in PostgreSQL 9.0
PL/Perl - New Features in PostgreSQL 9.0
 
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, ItalyPHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
PHP data structures (and the impact of php 7 on them), phpDay Verona 2015, Italy
 

En vedette

Eremkin Cboss Smsc Hl2009
Eremkin Cboss Smsc Hl2009Eremkin Cboss Smsc Hl2009
Eremkin Cboss Smsc Hl2009HighLoad2009
 
архитектура новой почты рамблера
архитектура новой почты рамблераархитектура новой почты рамблера
архитектура новой почты рамблераHighLoad2009
 

En vedette (6)

Nyt Prof 200910
Nyt Prof 200910Nyt Prof 200910
Nyt Prof 200910
 
Eremkin Cboss Smsc Hl2009
Eremkin Cboss Smsc Hl2009Eremkin Cboss Smsc Hl2009
Eremkin Cboss Smsc Hl2009
 
Kosmodemiansky
KosmodemianskyKosmodemiansky
Kosmodemiansky
 
архитектура новой почты рамблера
архитектура новой почты рамблераархитектура новой почты рамблера
архитектура новой почты рамблера
 
Ddos
DdosDdos
Ddos
 
Krizhanovsky Vm
Krizhanovsky VmKrizhanovsky Vm
Krizhanovsky Vm
 

Similaire à Dash Profiler 200910

Session Server - Maintaing State between several Servers
Session Server - Maintaing State between several ServersSession Server - Maintaing State between several Servers
Session Server - Maintaing State between several ServersStephan Schmidt
 
Stack kicker devopsdays-london-2013
Stack kicker devopsdays-london-2013Stack kicker devopsdays-london-2013
Stack kicker devopsdays-london-2013Simon McCartney
 
fog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the Cloudfog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the CloudWesley Beary
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot CampTroy Miles
 
Learning Puppet basic thing
Learning Puppet basic thing Learning Puppet basic thing
Learning Puppet basic thing DaeHyung Lee
 
Advanced Php - Macq Electronique 2010
Advanced Php - Macq Electronique 2010Advanced Php - Macq Electronique 2010
Advanced Php - Macq Electronique 2010Michelangelo van Dam
 
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)Wesley Beary
 
Getting Started with Couchbase Ruby
Getting Started with Couchbase RubyGetting Started with Couchbase Ruby
Getting Started with Couchbase RubySergey Avseyev
 
Tools for Solving Performance Issues
Tools for Solving Performance IssuesTools for Solving Performance Issues
Tools for Solving Performance IssuesOdoo
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8Alexei Gorobets
 
DBIx::Skinnyと仲間たち
DBIx::Skinnyと仲間たちDBIx::Skinnyと仲間たち
DBIx::Skinnyと仲間たちRyo Miyake
 
Php on the desktop and php gtk2
Php on the desktop and php gtk2Php on the desktop and php gtk2
Php on the desktop and php gtk2Elizabeth Smith
 
Mojo – Simple REST Server
Mojo – Simple REST ServerMojo – Simple REST Server
Mojo – Simple REST Serverhendrikvb
 
Filesystem abstractions and msg queue sergeev - symfony camp 2018
Filesystem abstractions and msg queue   sergeev - symfony camp 2018Filesystem abstractions and msg queue   sergeev - symfony camp 2018
Filesystem abstractions and msg queue sergeev - symfony camp 2018Юлия Коваленко
 
Building Cloud Castles - LRUG
Building Cloud Castles - LRUGBuilding Cloud Castles - LRUG
Building Cloud Castles - LRUGBen Scofield
 
Facebook的缓存系统
Facebook的缓存系统Facebook的缓存系统
Facebook的缓存系统yiditushe
 
Ajax Performance Tuning and Best Practices
Ajax Performance Tuning and Best PracticesAjax Performance Tuning and Best Practices
Ajax Performance Tuning and Best PracticesDoris Chen
 
How I Learned to Stop Worrying and Love the Cloud - Wesley Beary, Engine Yard
How I Learned to Stop Worrying and Love the Cloud - Wesley Beary, Engine YardHow I Learned to Stop Worrying and Love the Cloud - Wesley Beary, Engine Yard
How I Learned to Stop Worrying and Love the Cloud - Wesley Beary, Engine YardSV Ruby on Rails Meetup
 
How to use the new Domino Query Language
How to use the new Domino Query LanguageHow to use the new Domino Query Language
How to use the new Domino Query LanguageTim Davis
 
Automation with Ansible and Containers
Automation with Ansible and ContainersAutomation with Ansible and Containers
Automation with Ansible and ContainersRodolfo Carvalho
 

Similaire à Dash Profiler 200910 (20)

Session Server - Maintaing State between several Servers
Session Server - Maintaing State between several ServersSession Server - Maintaing State between several Servers
Session Server - Maintaing State between several Servers
 
Stack kicker devopsdays-london-2013
Stack kicker devopsdays-london-2013Stack kicker devopsdays-london-2013
Stack kicker devopsdays-london-2013
 
fog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the Cloudfog or: How I Learned to Stop Worrying and Love the Cloud
fog or: How I Learned to Stop Worrying and Love the Cloud
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
 
Learning Puppet basic thing
Learning Puppet basic thing Learning Puppet basic thing
Learning Puppet basic thing
 
Advanced Php - Macq Electronique 2010
Advanced Php - Macq Electronique 2010Advanced Php - Macq Electronique 2010
Advanced Php - Macq Electronique 2010
 
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
fog or: How I Learned to Stop Worrying and Love the Cloud (OpenStack Edition)
 
Getting Started with Couchbase Ruby
Getting Started with Couchbase RubyGetting Started with Couchbase Ruby
Getting Started with Couchbase Ruby
 
Tools for Solving Performance Issues
Tools for Solving Performance IssuesTools for Solving Performance Issues
Tools for Solving Performance Issues
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8
 
DBIx::Skinnyと仲間たち
DBIx::Skinnyと仲間たちDBIx::Skinnyと仲間たち
DBIx::Skinnyと仲間たち
 
Php on the desktop and php gtk2
Php on the desktop and php gtk2Php on the desktop and php gtk2
Php on the desktop and php gtk2
 
Mojo – Simple REST Server
Mojo – Simple REST ServerMojo – Simple REST Server
Mojo – Simple REST Server
 
Filesystem abstractions and msg queue sergeev - symfony camp 2018
Filesystem abstractions and msg queue   sergeev - symfony camp 2018Filesystem abstractions and msg queue   sergeev - symfony camp 2018
Filesystem abstractions and msg queue sergeev - symfony camp 2018
 
Building Cloud Castles - LRUG
Building Cloud Castles - LRUGBuilding Cloud Castles - LRUG
Building Cloud Castles - LRUG
 
Facebook的缓存系统
Facebook的缓存系统Facebook的缓存系统
Facebook的缓存系统
 
Ajax Performance Tuning and Best Practices
Ajax Performance Tuning and Best PracticesAjax Performance Tuning and Best Practices
Ajax Performance Tuning and Best Practices
 
How I Learned to Stop Worrying and Love the Cloud - Wesley Beary, Engine Yard
How I Learned to Stop Worrying and Love the Cloud - Wesley Beary, Engine YardHow I Learned to Stop Worrying and Love the Cloud - Wesley Beary, Engine Yard
How I Learned to Stop Worrying and Love the Cloud - Wesley Beary, Engine Yard
 
How to use the new Domino Query Language
How to use the new Domino Query LanguageHow to use the new Domino Query Language
How to use the new Domino Query Language
 
Automation with Ansible and Containers
Automation with Ansible and ContainersAutomation with Ansible and Containers
Automation with Ansible and Containers
 

Plus de HighLoad2009

Hl++2009 Ayakovlev Pochta
Hl++2009 Ayakovlev PochtaHl++2009 Ayakovlev Pochta
Hl++2009 Ayakovlev PochtaHighLoad2009
 
Dz Java Hi Load 0.4
Dz Java Hi Load 0.4Dz Java Hi Load 0.4
Dz Java Hi Load 0.4HighLoad2009
 
Highload Perf Tuning
Highload Perf TuningHighload Perf Tuning
Highload Perf TuningHighLoad2009
 
особенности использования Times Ten In Memory Database в высоконагруженной среде
особенности использования Times Ten In Memory Database в высоконагруженной средеособенности использования Times Ten In Memory Database в высоконагруженной среде
особенности использования Times Ten In Memory Database в высоконагруженной средеHighLoad2009
 
High Load 2009 Dimaa Rus Ready
High Load 2009 Dimaa Rus ReadyHigh Load 2009 Dimaa Rus Ready
High Load 2009 Dimaa Rus ReadyHighLoad2009
 
High Load 2009 Dimaa Rus Ready 16 9
High Load 2009 Dimaa Rus Ready 16 9High Load 2009 Dimaa Rus Ready 16 9
High Load 2009 Dimaa Rus Ready 16 9HighLoad2009
 
температура мира
температура миратемпература мира
температура мираHighLoad2009
 
м.токовинин компромиссная производительность
м.токовинин   компромиссная производительностьм.токовинин   компромиссная производительность
м.токовинин компромиссная производительностьHighLoad2009
 

Plus de HighLoad2009 (20)

Scalaxy
ScalaxyScalaxy
Scalaxy
 
Hl++2009 Ayakovlev Pochta
Hl++2009 Ayakovlev PochtaHl++2009 Ayakovlev Pochta
Hl++2009 Ayakovlev Pochta
 
Why02
Why02Why02
Why02
 
Quick Wins
Quick WinsQuick Wins
Quick Wins
 
Take2
Take2Take2
Take2
 
Hl2009 1c Bitrix
Hl2009 1c BitrixHl2009 1c Bitrix
Hl2009 1c Bitrix
 
Php Daemon
Php DaemonPhp Daemon
Php Daemon
 
Dz Java Hi Load 0.4
Dz Java Hi Load 0.4Dz Java Hi Load 0.4
Dz Java Hi Load 0.4
 
Highload Perf Tuning
Highload Perf TuningHighload Perf Tuning
Highload Perf Tuning
 
Hl2009 Pr V2
Hl2009 Pr V2Hl2009 Pr V2
Hl2009 Pr V2
 
Highload2009
Highload2009Highload2009
Highload2009
 
особенности использования Times Ten In Memory Database в высоконагруженной среде
особенности использования Times Ten In Memory Database в высоконагруженной средеособенности использования Times Ten In Memory Database в высоконагруженной среде
особенности использования Times Ten In Memory Database в высоконагруженной среде
 
бегун
бегунбегун
бегун
 
Hl Nekoval
Hl NekovalHl Nekoval
Hl Nekoval
 
High Load 2009 Dimaa Rus Ready
High Load 2009 Dimaa Rus ReadyHigh Load 2009 Dimaa Rus Ready
High Load 2009 Dimaa Rus Ready
 
High Load 2009 Dimaa Rus Ready 16 9
High Load 2009 Dimaa Rus Ready 16 9High Load 2009 Dimaa Rus Ready 16 9
High Load 2009 Dimaa Rus Ready 16 9
 
Pl High Load V1.1
Pl High Load V1.1Pl High Load V1.1
Pl High Load V1.1
 
температура мира
температура миратемпература мира
температура мира
 
м.токовинин компромиссная производительность
м.токовинин   компромиссная производительностьм.токовинин   компромиссная производительность
м.токовинин компромиссная производительность
 
бегун
бегунбегун
бегун
 

Dash Profiler 200910

  • 2. A Problem A web application ~100K lines of code Using many external services If response time goes up... what’s causing it? Continuous monitoring in production Must have very low CPU and I/O cost Minimal code changes
  • 3. A Typical Approach package MyNetIO; sub send_request { my ($hostname, $request) = @_ ...send to $hostname... } How much time was spent sending the request?
  • 4. A Typical Approach package MyNetIO; use Time::Hires qw(time); sub send_request { my ($hostname, $request) = @_ my $start = time(); ...send to $hostname... $durations->{MyNetIO}{$hostname} = time() - $start; } • Doesn’t record count so can’t produce averages. • Two lines of code. Worse if multiple return statements. • Doesn’t record time if function exits via an exception. Still need to write code to flush
  • 5. A Solution: DashProfiler Simple Flexible Lightweight
  • 6. DashProfiler • Can group samples into granular time units • Can measure exclusive time in a period • Can flush to disk at intervals • Just needs one line of code per sample
  • 7. DashProfiler Internals Built on DBI::Profile, part of the DBI Aggregates measurements into a data tree Two-level tree by default: $root->{ $key1 }->{ $key2 }->[ ...leaf node... ] $root->{ ‘MyNetIO’ }->{ $hostname }->[ ...leaf node... ]
  • 8. DashProfiler Data Each leaf node in the tree is a reference to an array: $root->{ $key1 }->{ $key2 } = [ 106, # 0: count of samples at this node 0.0312958955764771, # 1: total duration 0.000490069389343262, # 2: first duration 0.000176072120666504, # 3: shortest duration 0.00140702724456787, # 4: longest duration 1023115819.83019, # 5: time of first sample 1023115819.86576, # 6: time of last sample ] First sample populates all Later samples always update 0, 1, and 6 and may update 3 or 4
  • 9. DashProfiler By-Time Optional extra time level in the data tree $time = int(time() / $granularity) * $granularity; $root->{ $time }->{ ‘MyNetIO’ }->{ $hostname }->[ ... ] So a new sub-tree is grown each granularity seconds
  • 10. DashProfiler Config use DashProfiler; DashProfiler->add_profile( foo => { } ); DashProfiler->add_profile( foo => { granularity => 10, flush_interval => 600, flush_hook => sub { ... }, sample_class => ‘DashProfiler::Sample’, dbi_profile_class => ‘DBI::Profile’, period_exclusive => ..., period_summary => ..., ... }); Create named profiles Lots of features
  • 11. Without DashProfiler package MyNetIO; use Time::Hires qw(time); sub send_request { my ($hostname, $request) = @_ my $start = time(); ...send to $hostname... $durations->{MyNetIO}{$hostname} = time() - $start; }
  • 12. Without DashProfiler package MyNetIO; use DashProfiler::Import foo_profiler => [ ‘MyNetIO’ ]; sub send_request { my ($hostname, $request) = @_ my $sample = foo_profiler( $hostname ); ...send to $hostname... } - imports a pre-curried profiler code ref DashProfiler::Import - Profilers return bless object containing timestamp - Object destruction triggers accumulation of sample
  • 13. With DashProfiler Name of profile created with add_profile() Value to use for ‘key1’ package MyNetIO; use DashProfiler::Import foo_profiler => [ ‘MyNetIO’ ]; sub send_request { Value to use for ‘key2’ my ($hostname, $request) = @_ my $sample = foo_profiler( $hostname ); ...send to $hostname... } Duration is measured when $sample goes out of scope
  • 14. With DashProfiler package MyNetIO; use DashProfiler::Import foo_profiler => [ ‘MyNetIO’ ]; sub send_request { my ($hostname, $request) = @_ my $sample = foo_profiler( $hostname ) if foo_profiler_enabled(); ...send to $hostname... Automatically imported compile-time constant } reduces cost to zero if profile is disabled
  • 15. DashProfiler Flush Data is written to STDERR on exit, by default Regular flushing is enabled by specifying a flush_interval The dbi_profile_class handles the flush. Choices include: DBI::Profile DBI::ProfileData DBI::ProfileData::Apache DashProfiler->add_profile( foo => { ..., flush_interval => 600, dbi_profile_class => ‘DBI::ProfileData’, flush_hook => sub { ... }, ... });
  • 16. DashProfiler Periods • Group samples into periods - e.g. http request to response - start_sample_period() and end_sample_period() - counted, to enable averages and totals per period - can output period counts instead of sample counts • Measure ‘exclusive’ time - time from period start to end that’s not been accounted for by other samples - enabled via period_exclusive option
  • 17. Example Data Average response times over 24 hours DashProfiler doesn’t generate graphs itself, but the data can be used to create graphs like these
  • 18. Example Data Worst case response times over 24 hours
  • 19. DashProfiler Perspectives • Each DashProfiler can have multiple DBI Profile objects attached • Samples accumulate in all attached profiles • Each profile can have a different Path • giving different ‘perspectives’ or level of detail - key1 + key2 - key1 + country + browser type - key2 + browser type - ... etc.
  • 20. DashProfiler Per-Period • Optional extra ‘per-period’ DBI profile • Enabled via period_summary option • Automatically attached and reset by start_sample_period() • Gives current totals for this period • Great for ‘debug footers’ on web page showing how much time was spent generating this page
  • 21. DashProfiler Cost Time cost of taking a sample: 0.000021s - Time to create sample object, destroy it, accumulate the counts - In hot code can be 0.000015s - (Timings made on a 2GHz MacBook Pro Intel Core Duo) - (Could be made much faster by porting sampler class to C)
  • 22. Questions? Tim.Bunce@pobox.com @timbunce on twitter http://blog.timbunce.org