diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2014-11-01 01:47:12 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2014-11-01 01:47:12 +0000 |
commit | 94566f012421026c8311552f99175a5989eba063 (patch) | |
tree | 0bfd47111b94a1715d14b8c4ab2d82ad1abc09b1 /lib/Log/Log4perl/Resurrector.pm | |
download | Log-Log4perl-tarball-master.tar.gz |
Log-Log4perl-1.46HEADLog-Log4perl-1.46master
Diffstat (limited to 'lib/Log/Log4perl/Resurrector.pm')
-rw-r--r-- | lib/Log/Log4perl/Resurrector.pm | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/lib/Log/Log4perl/Resurrector.pm b/lib/Log/Log4perl/Resurrector.pm new file mode 100644 index 0000000..0eee01a --- /dev/null +++ b/lib/Log/Log4perl/Resurrector.pm @@ -0,0 +1,214 @@ +package Log::Log4perl::Resurrector; +use warnings; +use strict; + +# [rt.cpan.org #84818] +use if $^O eq "MSWin32", "Win32"; + +use File::Temp qw(tempfile); +use File::Spec; + +use constant INTERNAL_DEBUG => 0; + +our $resurrecting = ''; + +########################################### +sub import { +########################################### + resurrector_init(); +} + +################################################## +sub resurrector_fh { +################################################## + my($file) = @_; + + local($/) = undef; + open FILE, "<$file" or die "Cannot open $file"; + my $text = <FILE>; + close FILE; + + print "Read ", length($text), " bytes from $file\n" if INTERNAL_DEBUG; + + my($tmp_fh, $tmpfile) = tempfile( UNLINK => 1 ); + print "Opened tmpfile $tmpfile\n" if INTERNAL_DEBUG; + + $text =~ s/^\s*###l4p//mg; + + print "Text=[$text]\n" if INTERNAL_DEBUG; + + print $tmp_fh $text; + seek $tmp_fh, 0, 0; + + return $tmp_fh; +} + +########################################### +sub resurrector_loader { +########################################### + my ($code, $module) = @_; + + print "resurrector_loader called with $module\n" if INTERNAL_DEBUG; + + # Avoid recursion + if($resurrecting eq $module) { + print "ignoring $module (recursion)\n" if INTERNAL_DEBUG; + return undef; + } + + local $resurrecting = $module; + + + # Skip Log4perl appenders + if($module =~ m#^Log/Log4perl/Appender#) { + print "Ignoring $module (Log4perl-internal)\n" if INTERNAL_DEBUG; + return undef; + } + + my $path = $module; + + # Skip unknown files + if(!-f $module) { + # We might have a 'use lib' statement that modified the + # INC path, search again. + $path = pm_search($module); + if(! defined $path) { + print "File $module not found\n" if INTERNAL_DEBUG; + return undef; + } + print "File $module found in $path\n" if INTERNAL_DEBUG; + } + + print "Resurrecting module $path\n" if INTERNAL_DEBUG; + + my $fh = resurrector_fh($path); + + my $abs_path = File::Spec->rel2abs( $path ); + print "Setting %INC entry of $module to $abs_path\n" if INTERNAL_DEBUG; + $INC{$module} = $abs_path; + + return $fh; +} + +########################################### +sub pm_search { +########################################### + my($pmfile) = @_; + + for(@INC) { + # Skip subrefs + next if ref($_); + my $path = File::Spec->catfile($_, $pmfile); + return $path if -f $path; + } + + return undef; +} + +########################################### +sub resurrector_init { +########################################### + unshift @INC, \&resurrector_loader; +} + +1; + +__END__ + +=encoding utf8 + +=head1 NAME + +Log::Log4perl::Resurrector - Dark Magic to resurrect hidden L4p statements + +=head1 DESCRIPTION + +Loading C<use Log::Log4perl::Resurrector> causes subsequently loaded +modules to have their hidden + + ###l4p use Log::Log4perl qw(:easy); + + ###l4p DEBUG(...) + ###l4p INFO(...) + ... + +statements uncommented and therefore 'resurrected', i.e. activated. + +This allows for a module C<Foobar.pm> to be written with Log4perl +statements commented out and running at full speed in normal mode. +When loaded via + + use Foobar; + +all hidden Log4perl statements will be ignored. + +However, if a script loads the module C<Foobar> I<after> loading +C<Log::Log4perl::Resurrector>, as in + + use Log::Log4perl::Resurrector; + use Foobar; + +then C<Log::Log4perl::Resurrector> will have put a source filter in place +that will extract all hidden Log4perl statements in C<Foobar> before +C<Foobar> actually gets loaded. + +Therefore, C<Foobar> will then behave as if the + + ###l4p use Log::Log4perl qw(:easy); + + ###l4p DEBUG(...) + ###l4p INFO(...) + ... + +statements were actually written like + + use Log::Log4perl qw(:easy); + + DEBUG(...) + INFO(...) + ... + +and the module C<Foobar> will indeed be Log4perl-enabled. Whether any +activated Log4perl statement will actually trigger log +messages, is up to the Log4perl configuration, of course. + +There's a startup cost to using C<Log::Log4perl::Resurrector> (all +subsequently loaded modules are examined) but once the compilation +phase has finished, the perl program will run at full speed. + +Some of the techniques used in this module have been stolen from the +C<Acme::Incorporated> CPAN module, written by I<chromatic>. Long +live CPAN! + +=head1 LICENSE + +Copyright 2002-2013 by Mike Schilli E<lt>m@perlmeister.comE<gt> +and Kevin Goess E<lt>cpan@goess.orgE<gt>. + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + +=head1 AUTHOR + +Please contribute patches to the project on Github: + + http://github.com/mschilli/log4perl + +Send bug reports or requests for enhancements to the authors via our + +MAILING LIST (questions, bug reports, suggestions/patches): +log4perl-devel@lists.sourceforge.net + +Authors (please contact them via the list above, not directly): +Mike Schilli <m@perlmeister.com>, +Kevin Goess <cpan@goess.org> + +Contributors (in alphabetical order): +Ateeq Altaf, Cory Bennett, Jens Berthold, Jeremy Bopp, Hutton +Davidson, Chris R. Donnelly, Matisse Enzer, Hugh Esco, Anthony +Foiani, James FitzGibbon, Carl Franks, Dennis Gregorovic, Andy +Grundman, Paul Harrington, Alexander Hartmaier David Hull, +Robert Jacobson, Jason Kohles, Jeff Macdonald, Markus Peter, +Brett Rann, Peter Rabbitson, Erik Selberg, Aaron Straup Cope, +Lars Thegler, David Viner, Mac Yang. + |