NAME

Devel::Probe - Quick & dirty code probes for Perl

VERSION

Version 0.000005

SYNOPSIS

use Devel::Probe;
...
Devel::Probe::trigger(sub {
    my ($file, $line) = @_;
    # probe logic
});
Devel::Probe::config(%config);
...
Devel::Probe::enable();
...
Devel::Probe::disable();

DESCRIPTION

Use this module to allow the possibility of creating probes for some lines in your code.

The probing code is installed when you import the module, but it is disabled. In these conditions, the probe code is light enough that it should cause no impact at all in your CPU usage; an impact might be noticed when you enable the module and configure some probes, particularly depending on the frequency with which those probes will be triggered, and how heavy the trigger callback turns out to be.

FUNCTIONS

  • trigger(\&coderef)

    Specify a piece of Perl code that will be called for every probe that triggers.

  • config(\%config)

    Specify a configuration for the module, including what lines in your code will cause probes to be triggered. This call will always disable the module as a first action, so you always need to explicitly enable it again, either from the configuration itself or in a further call to enable().

  • add_probe(file, line, type)

    Manually add a probe. This is what gets called from config() when adding probes; please see the CONFIGURATION example for more information.

  • enable() / disable() / is_enabled()

    Dynamically activate and deactivate probing, and check this status.

  • install() / remove() / is_installed()

    Install or remove the probe handling code, and check this status. When you import the module, install() is called automatically for you.

  • clear()

    Remove all probes.

  • dump()

    Print all probes to stderr.

CONFIGURATION

An example configuration hash looks like this:

my %config = (
    actions => [
        { action => 'disable' },
        { action => 'clear' },
        { action => 'define' ... },
        { action => 'dump' },
        { action => 'enable' },
    ],
);

Possible actions are:

  • disable: disable probing.

  • clear: clear current list of probes.

  • dump: dump current list of probes to stderr.

  • enable: enable probing.

  • define: define a new probe. A full define action looks like:

    my %define = (
        action => 'define',
        type => PROBE_TYPE,
        file => 'file_name',
        lines => [ 10, 245, 333 ],
    );

    The type field is optional and its default value is once. Possible values are:

    • once: the probe will trigger once and then will be destroyed right after that. This default makes it more difficult to overwhelm your system with too much probing, unless you explicitly request a different type of probe.

    • permanent: the probe will trigger every time that line of code is executed.

EXAMPLE

This will invoke the callback defined with the call to trigger(), the first time line 21 executes, taking advantage of PadWalker to dump the local variables. After that first execution, that particular probe will not be triggered anymore. For line 22, every time that line is executed the probe will be triggered.

# line 1 of s.pl
use Data::Dumper qw(Dumper);
use PadWalker qw(peek_my);
use Devel::Probe;

Devel::Probe::trigger(sub {
    my ($file, $line) = @_;
    say Dumper(peek_my(1)); # 1 to jump up one level in the stack;
});

my %config = (
    actions => [
        { action => 'define', file => 's.pl', lines => [ 21 ] },
        { action => 'define', file => 's.pl', type = 'permanent', lines => [ 22 ] },
    ],
);
Devel::Probe::config(\%config);
Devel::Probe::enable();
my $count;
while (1) {
    $count++;                                   # line 21
    my $something_inside_the_loop = $count * 2; # line 22
    sleep 5;
}
Devel::Probe::disable();

SUGGESTIONS

For files found directly by the Perl interpreter, the file name in the probe definition will usually be a relative path name; for files that are found through the PERL5LIB environment variable, the file name in the probe definition will usually be a full path name.

One typical use case would be to have a signal handler associated with a specific signal, which when triggered would disable the module, read the configuration from a given place, reconfigure the module accordingly and then enable it. Similarly, this kind of control can be implemented using remote endpoints to deal with reconfiguring, disabling and enabling the module.

TODO

  • Probes are stored in a hash of file names; per file name, there is a hash of line numbers (with the probe type as a value). It is likely this can be made more performant with a better data structure, but that needs profiling.

AUTHORS

  • Gonzalo Diethelm gonzus AT cpan DOT org

  • Ben Tyler btyler AT cpan DOT org