Apache::DProf(3pm)

πŸ“¦
version 0.18 Β· 2 versions
, in ubuntu jammy

πŸ’– Apache::DProf β€” bestie edition ✨

okay so this is the manual page for Apache::DProf (it lives in the 3pm section, and yeah we're in the User Contributed Perl Documentation zone 🫢). Short version: it hooks Devel::DProf into mod_perl. That's the whole vibe. Let's get into it πŸ’…


✨ SYNOPSIS ✨

literally one line, bestie. drop this into your httpd.conf:

#in httpd.conf
PerlModule Apache::DProf

that's it. that's the whole setup. iconic 🌸


πŸ¦‹ DESCRIPTION πŸ¦‹

so what does it actually do? Apache::DProf runs a Devel::DProf profiler inside each child server, and it writes the tmon.out file into the directory $ServerRoot/logs/dprof/$$ β€” and it does that when the child is shutdown, no cap.

then, the next time the parent server pulls in Apache::DProf (whether that's via a soft or a hard restart), the $ServerRoot/logs/dprof directory gets cleaned out first, before any new profiles get written for the new children. fresh start energy, we love to see it 🧚


πŸ’€ WHY πŸ’€

okay so plot twist: you can profile code running under mod_perl with just the Devel::DProf module from CPAN, no extra module needed. but. you must have apache version 1.3b3 or higher. noted. πŸ“Œ

when the server is started, Devel::DProf installs an "END" block to write the tmon.out file β€” and that block runs when the server is shutdown. here's how you'd start and stop a server with the profiler enabled, fr fr:

% setenv PERL5OPT -d:DProf
% httpd -X -d `pwd` &
... make some requests to the server here ...
% kill `cat logs/httpd.pid`
% unsetenv PERL5OPT
% dprofpp

cute right? …except there are downsides to this approach, and we gotta be honest about them 😭

  • Setting and unsetting PERL5OPT is a pain.
  • Server startup code will be profiled as well, which we are not really concerned with, we're interested in runtime code, right?
  • It will not work unless the server is run in non-forking "-X" mode

πŸ™ˆ why is it like this tho πŸ™ˆ

these limitations all come from Devel::DProf assuming that the code you're profiling is running under a standard Perl binary β€” like, the one you run from the command line.

"Devel::Dprof" relies on the Perl -d switch to initialize the Perl debugger, and that initialization happens inside the "perl_parse()" function call. it also relies on Perl's special "END" subroutines for termination, which is how it writes the raw profile to tmon.out. under the standard command line Perl interpreter, those "END" blocks get run when the "perl_run()" function is called.

also β€” and this is important β€” Devel::DProf will not profile any code if it is inside a forked process. 🚫

but here's the thing: every single time you run a Perl script from the command line, "perl_parse()" and "perl_run()" both get called, so Devel::DProf works just fine that way. slay.


🌈 but under mod_perl… 🌈

under mod_perl, "perl_parse()" and "perl_run()" are called only once β€” when the parent server is starting. so any "END" blocks encountered during server startup, or outside of "Apache::Registry" scripts, are suspended, and they run when the server is shutdown via apache's child exit callback hook.

also the parent server only runs Perl startup code β€” all request time code runs in the forked child processes.

if you followed the previous paragraph, you should be able to see: Devel::DProf does not fit into the mod_perl model too well 😬

and that is literally why the Apache::DProf module exists β€” to make it fit, without modifying the Devel::DProf module or Perl itself. king behavior πŸ‘‘


✨ how it actually works ✨

the Apache::DProf module also requires apache version 1.3b3 or higher and "PerlChildInitHandler" enabled. you configure it simply by adding this line to your httpd.conf file:

PerlModule Apache::DProf

when the Apache::DProf module is pulled in by the parent server, it pushes a "PerlChildInitHandler" via the Apache push_handlers method. then when a child server is starting, the "Apache::DProf::handler" subroutine gets called.

this handler will create a directory "dprof/$$" relative to ServerRoot, which is where Devel::DProf will create its tmon.out file. then the handler initializes the Perl debugger and pulls in Devel::DProf, who will then install its hooks into the debugger and start its profile timer ⏱️

the "END" subroutine installed by Devel::DProf will be run when the child server is shutdown, and the $ServerRoot/dprof/$$/tmon.out file will be generated and ready for dprofpp. chef's kiss 😌

NOTE: $ServerRoot/logs/dprof/ will need to be writable by the user Apache is running as (i.e. nobody, apache, etc.). if you can not write to $ServerRoot as this user, set $ENV{APACHE_DPROF_PATH_ABSOLUTE} to an absolute path of a directory this user can. πŸ”₯ don't skip this one bestie, permissions are the villain of every story πŸ’€

πŸ‘‘ AUTHOR πŸ‘‘

Originally written by Doug MacEachern

Currently maintained by Dirk Lindner <lze@cpan.org.org>


πŸ’œ LICENSE πŸ’œ

This module is distributed under the same terms as Perl itself.


πŸŽ€ SEE ALSO πŸŽ€


and that's the page, bestie!! this one came from perl v5.34.0, dated 2022-02-06, and it's Apache::DProf(3pm) in the manual β€” go forth and profile responsibly πŸ«Άβœ¨πŸ’–

πŸ“¦ where this page comes from