The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
NAME
    Harbinger::Client - Impend all the doom you could ever want รขยšย”

VERSION
    version 0.001000

SYNOPSIS
     my $client = Harbinger::Client->new(
       harbinger_ip => '10.6.1.6',
       harbinger_port => 8090,
       default_args => [
         server => 'foo.lan.bar.com',
         port   => 1890,
       ],
     );

     my $doom = $client->start(
        ident => 'process-images',
     );

     for (@images) {
        ...
        $doom->bode_ill;
     }

     $client->send($doom->finish);

DESCRIPTION
    After reading The Mature Optimization Handbook
    <http://carlos.bueno.org/optimization/mature-optimization.pdf>, in a
    fever dream of hubris, I wrote "Harbinger::Client" and Harbinger::Server
    <https://github.com/frioux/Harbinger>. They have both served me
    surprisingly well with how minimal they are. The goal is to be as
    lightweight as possible such that the measuring of performance does not
    degrade performance nor impact reliability. If the client ever throws an
    exception I have failed in my goals.

    As should be clear in the "SYNOPSIS" the grim measurement that the
    "Harbinger" records is called "DOOM ๐Ÿ’€". "DOOM ๐Ÿ’€" currently measures a
    handful of data points, but the important bits are:

    * time

    * space

    * queries

    See more in "DOOM ๐Ÿ’€".

   METHODS
   "new"
    Instantiate client with this method. Note example in "SYNOPSIS".

    Takes a hash of "harbinger_ip" (default of 127.0.0.1), "harbinger_port"
    (default of 8001), and "default_args" (default of "[]").

    "harbinger_ip" and "harbinger_port" are how to connect to the remote
    "HarBinger::Server".

    "default_args" get used in "start" and "instant" when forging new "DOOM
    ๐Ÿ’€".

   "start"
    The typical way to start measuring some "DOOM ๐Ÿ’€". Note example in
    "SYNOPSIS".

    Actual implementation at "Harbinger::Client::Doom->start".

   "instant"
     $client->instant(
        ident => 'man overboard',
        count => 1,
     );

    Instead of measuring deltas as "DOOM ๐Ÿ’€" typically does, this method is
    for measuring instantaneous events, maybe for counting or graphing them
    later. Sends the event immediately.

   "send"
     $client->send($completed_doom);

    Once "DOOM ๐Ÿ’€" is ready to be sent to the server pass it to "send".

LIGHTHOUSE โ›ฏ
    Beware the siren song (๐Ÿ‘„) of the Harbinger! The API is not stable yet, I
    already have major changes planned for a plugin (๐Ÿ”Œ) system. I'm not even
    going to attempt to keep things working. You've been warned (โš ).

DOOM ๐Ÿ’€
    Measure the crushing weight, the glacial pace, the incredible demand
    which your application puts upon your database server with "DOOMโ„ข"

  DOOMFUL ATTRIBUTES โ˜ 
   "server"
    Something unique that identifies the machine that we are measuring the
    "DOOM ๐Ÿ’€" for. A good idea is the ip address or the hostname. If this is
    not set "DOOM ๐Ÿ’€" will not be sent or recorded.

   "ident"
    Something unique that identifies the task that we are measuring the
    "DOOM ๐Ÿ’€" for. For a web server, "PATH_INFO" might be a good option, or
    for some kind of message queue the task type would be a good option.

   "pid"
    The pid of the process "DOOM ๐Ÿ’€" is being recorded for. Has a sensible
    default, you probably will never need to set it.

   "port"
    The port that the service is listening on, if applicable. Leave alone if
    unknown or not applicable.

   "count"
    The count of things being done in this unit of "DOOM ๐Ÿ’€". If it were a
    web request that returns a list of items, this would reasonably be set
    as that number. If the operation is not related to things that are
    countable, leave alone.

   "milliseconds_elapsed"
    The total milliseconds elapsed during the unit of "DOOM ๐Ÿ’€". If instant
    or unknown "DOOM ๐Ÿ’€" leave empty.

   "db_query_count"
    The total queries executed during the unit of "DOOM ๐Ÿ’€". If not
    applicable or unknown "DOOM ๐Ÿ’€" leave empty.

   "memory_growth_in_kb"
    The total memory growth in kb during the unit of "DOOM ๐Ÿ’€". If not
    applicable or unknown "DOOM ๐Ÿ’€" leave empty.

   "query_logger"
    A tool to measure query count with "DBIx::Class". Please only use as
    documented, underlying implementation may change. See "QUERYLOG ๐Ÿ“œ"

  DOOMFUL METHODS ๐Ÿ”ฎ
   "Harbinger::Client::Doom->start"
    Normally called via "start". Sets up some internal stuff to make
    automatic measuring of "memory_growth_in_kb" and "milliseconds_elapsed"
    work. Takes a hash and merges hash into the object via accessors.

    NOTE: to automatically measure memory growth you need either
    Win32::Process::Memory or Proc::ProcessTable installed.

   "$doom->bode_ill"
    Increment the "DOOM ๐Ÿ’€" "count"er.

   "$doom->finish"
     $doom->finish( count => 32 );

    Finalizes "memory_growth_in_kb" and "milliseconds_elapsed". As with
    "Harbinger::Client::Doom->start" takes a hash and merges it into the
    object via accessors. Returns the object to allow chaining.

"Plack::Middleware::Harbinger"
     builder {
       enable Harbinger => {
          harbinger_ip   => '192.168.1.1',
          harbinger_port => 2250,
          default_args   => [
             server => '192.168.1.2',
             port   => 80,
          ],
       };
       $my_app
     };

    Takes the same args as "new". Adds "query_log" from "DOOM ๐Ÿ’€" to
    "harbinger.querylog" in "psgi ENV". See "QUERYLOG ๐Ÿ“œ".

    After the query completes the "DOOM ๐Ÿ’€" will automatically be sent.

    If "harbinger.ident" is set it will be used for the "ident", otherwise
    "PATH_INFO" will be used.

    "harbinger.server", and "harbinger.count" are passed more or less
    directly.

    "harbinger.port" will be passed if true, otherwise "SERVER_PORT" will be
    used.

"Catalyst::TraitFor::Controller::Harbinger"
    This page intentionally left blank.

QUERYLOG ๐Ÿ“œ
    You are recommended to apply the query log with
    DBIx::Class::QueryLog::Tee and DBIx::Class::QueryLog::Conditional.

    First, set up your schema package MyApp::Schema;

     use base 'DBIx::Class::Schema';
     use aliased 'DBIx::Class::QueryLog::Tee';
     use aliased 'DBIx::Class::QueryLog::Conditional';

     __PACKAGE__->load_namespaces(
        default_resultset_class => 'ResultSet',
     );

     sub connection {
        my $self = shift;

        my $ret = $self->next::method(@_);

        $ret->storage->debugobj(
           Tee->new(
              loggers => {
                 original => Conditional->new(
                    logger => $self->storage->debugobj,
                    enabled_method => sub { $ENV{DBIC_TRACE} },
                 ),
              },
           )
        );

        $ret->storage->debug(1);

        $ret
     }

     1;

    Note that the DBIx::Class::QueryLog::Tee extension allows you to add
    more Query loggers as you go, so you can even log inner loops and outer
    loops at the same time. Also note that
    DBIx::Class::QueryLog::Conditional allows you to have the "Harbinger"
    loggers always on, but the pretty DBIx::Class console logger can still
    be set via environment variable, as usual.

    Now to set the logger after whipping up some "DOOM ๐Ÿ’€" this is all that's
    needed:

     my $doom = $client->start(
        ident => 'process-images',
     );

     $schema->storage->debugobj
       ->add_logger('process-images-harbinger', $doom->query_logger);

     $client->send($doom->finish);
     $schema->storage->debugobj
       ->remove_logger('process-images-harbinger');

    Finally, if you have some legacy code or are using the wrong ORM, you
    can still use the QueryLogger as follows:

     $dbh->{Callbacks}{ChildCallbacks}{execute} = sub {
       $doom->query_log->query_start('', []);
       $doom->query_log->query_end('', []);
       return ();
     }

    If you can pull it off, doing this dynamically with "local" is
    preferred, but that's not always possible.

AUTHOR
    Arthur Axel "fREW" Schmidt <frioux+cpan@gmail.com>

COPYRIGHT AND LICENSE
    This software is copyright (c) 2014 by Arthur Axel "fREW" Schmidt.

    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.