NAME
Stacktrace::Configurable - a configurable Perl stack trace
SYNOPSIS
use Stacktrace::Configurable;
Stacktrace::Configurable->new(format=>$fmt)->get_trace->as_string;
DESCRIPTION
The idea for "Stacktrace::Configurable" came when I needed a easily
readable stack trace in Log::Log4perl output. That distribution's
pattern layout can give you a stack trace but it's not very readable.
There are other modules out there that provide a caller stack, like
Devel::StackTrace and Carp. Choose what suits you best.
A stack trace is basically a list of stack frames starting with the
place where the get_trace method is called down to the main program. The
first element in that list is also called the topmost frame.
Each frame of the list collected by get_trace is a
Stacktrace::Configurable::Frame object which provides simple accessors
for the information returned by "caller". Additionally, a frame has a
"nr" in Stacktrace::Configurable::Frame attribute which contains its
position in the list starting from 1 (topmost).
Constructor
The constructor "Stacktrace::Configurable->new" is called with a list of
key/value pairs as parameters. After constructing an empty object it
uses each of those keys as method name and calls it passing the value as
parameter.
Example:
$trace=Stacktrace::Configurable->new(format=>$fmt);
Attributes
Attributes are simple accessor methods that provide access to scalar
variables stored in the object. If called with a parameter the new value
is stored. The return value is always the new or current value.
These attributes are implemented:
format
the format specification, see below
frames
the stack trace. It is an arrayref of
Stacktrace::Configurable::Frame objects usually initialized by the
get_trace method.
Public Methods
$obj->get_trace
collects the stack trace with the caller of "get_trace" as the
topmost frame and stores it as "$obj->frames".
Returns the object itself to allow for chained calls like
$obj->get_trace->as_string;
$obj->as_string
formats the stack trace according to the current format and returns
the resulting string.
Methods interesting for subclassing
$obj->skip_package_re
returns the empty list. If overwritten by subclasses, it should
return a regular expression matching package names which is used to
skip stack frames from the top of the stack. "get_trace" starts to
collect stack frames from the top of the stack. If "skip_package_re"
returns a regexp, it drops those frames as long as their "package"
matches the regexp. Once a non-matching package is discovered all
remaining frames are included in the trace no matter what "package".
This allows you to skip frames internal to your subclass from the
top of the stack if you are not sure of the nesting level at which
"get_trace" is called.
$obj->skip_package_number
Similar to "skip_package_re", only it specifies the actual nesting
level. For the base class ("Stacktrace::Configurable") 1 is
returned.
$obj->default_format
this method returns a constant that is used by the constructor to
initialize the "format" attribute if omitted.
The current default format is:
'env=STACKTRACE_CONFIG,'.
'%[nr=1,s= ==== START STACK TRACE ===]b%[nr=1,n]b'. # header line before the actual stack trace
'%4b[%*n] at %f line %l%[n]b'. # 4 spaces indentation, the filename and line number and a newline
'%12b%[skip_package]s %a[env=STACKTRACE_CONFIG_A]%[nr=$,n]b'. # the called function w/o package and the parameters
'%[nr=$,s= === END STACK TRACE ===]b%[nr=$,n]b' # trailer line after the stack trace
$obj->fmt_b
$obj->fmt_n
$obj->fmt_s
$obj->fmt_a
$obj->fmt_f
$obj->fmt_l
$obj->fmt_c
$obj->fmt_p
these methods format a certain portion of a stack frame. They are
called as methods. So, the first parameter is the object itself. The
following parameters are:
$frame
the frame to format
$width
the width part of the format specification
$param
the param part of the format specification
Return value: the formatted string
Private Methods
$obj->_use_dumper
Format
The format used by Stacktrace::Configurable is inspired by "printf" and
Log::Log4perl::Layout::PatternLayout.
The first format component is an optional string starting with "env="
and ending in a comma, like
env=STACKTRACE_CONFIG,
If this component is found "as_string" consults the specified
environment variable for instructions. If the variable is "off", "no" or
0, no stack trace at all is created and "as_string" returns the empty
string.
If after stripping of that first component, the format becomes the empty
string the value of the environment variable or, if also empty, the
default format is used as format specification.
The rest of the format is a string with embedded format specifications
or *fspec*. An fspec starts with a percent sign, "%". Then follows an
optional width component, an optional parameter component and the
mandatory format letter.
The width component is just an integer number optionally prepended with
a minus sign or an asterisk ("*"). Not every fspec uses the width
component or does something useful for "*".
The parameter component is surrounded by brackets ("[]").
The parsing of an fspec is kept simple. So, it does not support nested
brackets or similar.
The following format letters are implemented:
b Originally the name "b" was chosen because "s" was already in use.
It stands for *blank* or empty space. Though, it can generate
arbitrary output and be based on conditions.
The simplest form %b just outputs one space. Add a width component,
%20b and you get 20 spaces.
The parameter component is a set of 2 optional items separated by
comma. The first item specifies a condition. The second modifies the
string used in place of the space.
Let's first look at examples where the condition part is omitted.
The "n" parameter tells to use a newline instead of a space. So,
"%20[n]b" inserts 20 newline characters. The parameter "t" does the
same only that a tabulator character is used. "%20[t]b" results in
20 tabs. The 3rd option is the "s=" parameter. It allows you to
specify arbitrary strings. "%4[s=ab]b" results in
abababab
Now, let's look at conditional output. The "nr=" parameter matches a
specific stack frame given by its number. It is most useful at the
start and the end of the stack trace.
Examples:
%[nr=1,s=stack trace start]b
if given at the beginning of the format, this specification prints
the string "stack trace start" but only for the topmost frame.
%[nr=$,s=stack trace end]b
"nr=$" matches only for the last stack frame. So, the fspec above
prints "stack trace end" at the end of the trace.
The "nr!" condition also matches a specific frame given by its
number. But in addition to generate output it cuts off the trace
after the current frame. It is used if you want to print only the
topmost N frames. It is often used with the empty string as what to
print, like
%[nr!10,s=]b
This prints nothing but cuts off the stack trace after the 10th
frame.
The last condition is "nr%N" and "nr%N=M". It can be used to insert
a special delimiter after every N stack frames.
%[nr%10=1,n]b%80[nr%10=1,s==]b
prints a delimiter consisting of a newline and 80 equal signs after
every 10th frame.
The condition is true if "frame_number % M == N" where N defaults to
0.
n inserts the frame number. This format ignores the parameter
component. Width can be given as positive or negative number an is
interpreted just like in "sprintf". If width is "*" or "-*", the
actual width is taken to fit the largest frame number.
Examples:
%n
%4n
%-4n
%*n
%-*n
s inserts the subroutine. The width component is ignored and only one
parameter is known, "skip_package". If specified, the package where
the function belongs to is omitted.
Examples:
%s # might print "Pack::Age::fun"
%[skip_package]s # prints only "fun"
a inserts the subroutine arguments. The width component is ignored.
The parameter component is a comma separated list of
dump
all arguments are dumped using Data::Dumper. The dumper object
is configured in a way to print the whole thing in one line.
This may cause very verbose stack traces.
dump=Pack::Age
all arguments for which "ref" returns "Pack::Age" are dumped
using Data::Dumper.
You can, of course, also dump simple ARRAYs, HASHes etc.
dump=/regexp/
all arguments for which "ref" matches the regexp are dumped
using Data::Dumper.
If multiple such parameters are given, an argument that matches
at least one regexp is dumped.
deparse
if "dump" or "dump=CODE" is also specified, the dumper object is
configured to deparse the subroutine that is passed in the
argument.
multiline
multiline=N
multiline=N.M
normally, all arguments are printed in one line separated by
comma and space. With this parameter every argument is printed
on a separate line.
A format containing "%s %[multiline]a" would for instance
generate this output:
main::function (
"param1",
2,
"p3"
)
The surrounding parentheses are part of the %a output.
"N" and "M" are indentation specifications. "N" tells how many
positions the closing parenthesis is indented. "M" tells how
many positions further each parameter is indented. The default
value for both is 4.
env=ENVVAR
This parameter reads the environment variable "ENVVAR" and
appends it to the parameter list.
Examples:
%[dump,deparse,multiline]a # very verbose
f inserts the file name. This fspec recognizes the following
parameters:
skip_prefix=PREFIX
if the file name of the stack frame begins with "PREFIX", it is
cut off.
For instance, if your personal Perl modules are installed in
/usr/local/perl, then you might specify
%[skip_prefix=/usr/local/perl/]f
basename
cuts off the directory part of the file name.
If a width component is specified and the file name is longer
than the absolute value of the given width, then if the width is
positive, the file name is cut at the end to meet the given
width. If the width is negative, the file name is cut at the
start to meet the width. Then an ellipsis (3 dots) is appended
or prepended.
l inserts the line number. The width component is interpreted like in
"sprintf".
c prints the context of the subroutine call as "void", "scalar" or
"list".
p prints the package name of the stack frame.
The %p fspec recognizes the "skip_prefix" parameter just like %f.
The width component is also interpreted the same way as for %f.
Examples:
env=T,%f(%l) # one line of "filename.pm(23)" for each frame
# unless $ENV{T} is "off", "no" or "0"
env=T, # use the format given in $ENV{T}
# unless $ENV{T} is "off", "no" or "0"
Subclassing
TODO
AUTHOR
Torsten Förtsch <torsten.foertsch@gmx.net>
COPYRIGHT
Copyright 2014- Torsten Förtsch
LICENSE
This library is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
SEE ALSO
Carp, Devel::StackTrace,
Log::Log4perl::Layout::PatternLayout::Stacktrace