Tuesday, December 3, 2013

Custom DTrace Probes for Perl on Oracle Linux 6

Chris Andrews (@chrisandrews) has developed the libusdt library a few years back so that dynamic language developers can publish custom DTrace providers easily. He has also developed the associated modules for Ruby, Perl and Node.js... If you are dealing with one of these languages, publishing a DTrace provider usually takes no more than 5 lines.

Last September, Chris has adapted his library so that it works with Oracle Linux 6 DTrace and the Unbreakable Enterprise Kernel 3. This post explains how to use Perl Devel::DTrace::Provider module in this context.

Installing the Devel::DTrace::Provider Perl Module

The 1.11 version of Devel::DTrace::Provider doesn’t come with the latest libusdt. We can assume, next release will do! In the meantime, if you install the module on Perl, it fails. In order to workaround that issue, install it from the source and change the libusdt library with the latest one... As a prerequisites, make sure you have an Oracle Linux 6 running DTrace and you have downloaded the DTrace utilities and the associated headers from your Oracle Premier Support. You should be able to run the script below as root:
modprobe dtrace
modprobe profile
modprobe sdt
modprobe systrace
modprobe fasttrap
chmod 666 /dev/dtrace/helper
Install the following Perl Module that are required by Devel::DTrace::Provider:
yum -y install perl-Data-OptList perl-Params-Util \
     perl-Sub-Install perl-JSON perl-Sub-Exporter
Download the module gzip tarball. The 1.11 release can be downloaded from here. Download the libusdt library from its GitHub.com page. You can download it as a zip here. Once you have the 2 distributions on your filesystem, decompress them and make sure libusdt is part of the Perl Module like below:
tar -zxvf Devel-DTrace-Provider-1.11.tar.gz
cd Devel-DTrace-Provider-1.11
rm -rf libusdt
unzip ../master.zip
mv libusdt-master libusdt
Build and install the Perl module:
perl Makefile.PL
make
sudo make install
You can simply test the module like in the example below:
sudo make test
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/builder.t ...... ok   
t/imported.t ..... ok   
t/imported2.t .... ok   
t/json.t ......... ok   
t/noargs.t ....... ok   
t/provider.t ..... ok    
t/unavailable.t .. ok   
All tests successful.
Files=7, Tests=43,  0 wallclock secs ( 0.04 usr  0.01 sys +  0.25 cusr  0.04 csys =  0.34 CPU)
Result: PASS

Include a Custom DTrace Provider in your Perl script

Once the module installed, you can use it from any of your Perl scripts. Create a file name helloworld.pl that declares and enable a probe for a new provider named myprovider:
use Devel::DTrace::Provider;

my $provider = Devel::DTrace::Provider->new('myprovider', 'myapp');
my $probe = $provider->add_probe('start', 'monitor', ['string']);
$provider->enable;

$probe->fire('HelloWorld');
The script below will be able to intercept the probe and display its parameter:
sudo dtrace -qZn 'myprovider*::: { printf("%s:%s:%s:%s (%s)\n", probeprov, probemod, probefunc, probename, copyinstr(arg0)) }'
Run your Perl script:
perl helloworld.pl
It displays the probe as well as value sent as an output parameter:
myprovider10894:myapp:monitor:start (HelloWorld)
You can now enjoy extending your application with a custom DTrace provider on Linux too...

No comments:

Post a Comment