NAME
Profile::Log - collect loggable application profiling stats
SYNOPSIS
use Profile::Log;
...
sub event_processor {
my $timer = Profile::Log->new() if PROFILE;
do_something();
$timer->did("minor") if PROFILE > 1;
$timer->mark("parallel") if PROFILE;
do_parallel_things();
wait_for_thing1();
$timer->did("thing1", "parallel") if PROFILE;
wait_for_thing2();
$timer->did("thing2", "parallel") if PROFILE;
finish_up();
$timer->did("finish") if PROFILE > 1;
# this module does not handle logging itself.
print LOG $timer->logline if PROFILE;
}
# later... available processing methods
my $timer = Profile::Log->new($log_line);
print $timer->zero; # profile start time
print $timer->end; # profile stop time
# ... t.b.c. ...
DESCRIPTION
Profile::Log
is about breaking down time spent in "critical paths", such as in transaction processing servers, into logical pieces - with easily tunable operation that does not incur undue performance penalities when it is not being used.
Profile::Log
exports the PROFILE
constant into the environment, depending on how it is configured (see "CONFIGURATION"). This will be set if profiling has been selected for the given script or module. As this is exported as a "constant subroutine", using the module as per the above synopsis will not incur any penalty at all (except, in the case above, the allocation of one undef scalar and the compile-time inclusion of Profile::Log
itself; in long-running application servers, this is an extremely minor concern).
The timing information is logged in a way that suits syslog, and is casually easy to inspect; the above example, on profiling level 2, might log (though all on one line):
0=12:34:56.123504; tot=0.504; minor: 0.020; m0:parallel=0.000; \
m0:thing1=0.450; m0:thing2=0.454; finish: 0.030
The first item is the time that the Profile::Log
object was created. The "tot" is the total length of time from when the object was created to the time that it was stopped (such as by asking for the log line).
On profiling level 1, you would instead get (assuming the same times for each component):
0=12:34:56.123504; tot=0.504; m0:parallel=0.020; \
m0:thing1=0.450; m0:thing2=0.454
EXPORTS
This module exports the PROFILE
constant to the caller's namespace. This will be set to 0 by default, or a number if configured in the per-user or environment specified configuration file. See "CONFIGURATION" for details.
If PROFILE is already defined as a subroutine or use constant
in the calling package, then that is not touched.
CONSTRUCTOR
my $timer = Profile::Log->new() if PROFILE;
Mark beginning of a profiled section, by creating a new Profile::Log
object.
Normally, you don't pass any arguments to the Profile::Log->new
constructor. However, if you want to reconstruct a previous Profile::Log
object from a line from your logs, then you can pass that in instead.
my $loaded_timer = Profile::Log->new($log_line);
For now, you need to strip off any leading syslog
wrappers to the front of the string you pass in as $log_line
.
ALTERNATE CONSTRUCTOR
It is also possible to feed in lines that came out of syslog(8). These are expected to be in the form:
Mon DD HH:MM:SS hostname ...
These must be fed into the alternate constructor ->new_from_syslog
. Information present in the syslog line, such as the hostname, any process name (sans PID), and extra information leading up to the beginning of the ->logline()
part are put into tags.
OBJECT METHODS
TIMING METHODS
->did($event, [$mark])
-
Indicate that the time elapsed since the timer was constructed or the last time
->did()
or->mark()
was called to the current time was spent doing "$event
". If you specify a$mark
(see below), then all the time back from when you created that mark is considered to have been spent doing$event
. ->mark($mark)
-
Set a time mark for later back-reference. Typically you would call this just before doing something that involves running things in parallel, and call
->did()
above with the optional$mark
parameter when each independent task completes. ->logline()
-
Returns the timing information in a summarised format, suitable for sending to
syslog
or something similar.This method automatically stops the timer the first time it is called.
TRACKING AND INSPECTING METHODS
These methods are about making sure custom details about what is being logged can easily be logged with the profiling information.
For instance, in application servers it is often useful to log the type of transaction being processed, or the URL. In multi-tier systems, you need to log a unique identifier with each request if you are to correlate individual timings through the system.
Also, these methods cover getting useful information out of the object once you have read it in from a log file.
->tag($tag, [$value])
-
Set (2 argument version) or get (1 argument version) an arbitrary tag. The
$tag
name should not contain a semicolon or equals sign, and the$value
must not contain any semicolons. This is not enforced. -
Returns a list of tags of this profile, in no particular order.
->zero
-
Return the number of seconds between midnight (UTC) and the time this profiling object was created.
In list context, returns a Unix epoch time and a number of microseconds,
Time::HiRes
style. ->diff($t2)
-
Returns the difference between two times, in seconds. If the dates are fully specified, then it will return an asolute (floating point) number of seconds.
This method is available as the overloaded
cmp
operator, for easy use withsort
. ->end
-
Return the number of seconds since midnight (UTC) and the time this profiling object's clock was stopped.
->marks
-
Returns a list of marks as an array. This will always include "0", the starting mark.
->iter
-
Returns an iterator that iterates over every delta, and mark, in the Profiler object.
The iterator responds to these methods; note that these are not method calls:
$iter->("next")
-
iterate. returns a true value unless there is nowhere to iterate to.
$iter->("start")
-
Returns the offset from time 0 that this delta started in fractional seconds.
$iter->("length")
-
Returns the length of this delta in (fractional) seconds.
$iter->("name")
-
Returns the name of this delta, including the mark identifier (
m
followed by a number and a colon, such as "m0:
").
->mark_iter([$mark])
-
Returns an iterator that iterates exactly once over every delta that was timed relative to
$mark
.If you don't pass a mark in, it iterates only over items that weren't timed relative to
$mark
.
TIMESTAMP FORMATTING
If you don't like the decisions I've made about only displaying milliseconds in the log, then you may sub-class Profile::Log
and provide these functions instead. These are called as object methods, though the object itself is not used to compute the result.
->getTimeStamp([$sec, $usec])
-
Formats an absolute timestamp from a
Time::HiRes
array. Defaults to formatting as:HH:MM:SS.SSS
->getInterval($sec | @tv_interval )
-
Formats an interval. This function accepts either a floating point number of seconds, or arguments as accepted by
Time::HiRes::tv_interval
.The function returns a string in scalar context, but in list context returns any rounding error also, in floating point seconds.
AUTHOR AND LICENSE
Designed and built by Sam Vilain, samv@cpan.org, brought to you courtesy of Catalyst IT Ltd - http://www.catalyst.net.nz/.
All code and documentation copyright © 2005, Catalyst IT Ltd. All Rights Reserved. This module is free software; you may use it and/or redistribute it under the same terms as Perl itself.
1 POD Error
The following errors were encountered while parsing the POD:
- Around line 778:
Non-ASCII character seen before =encoding in '©'. Assuming UTF-8