File Coverage

lib/Log/Shiras/TapPrint.pm
Criterion Covered Total %
statement 56 59 94.9
branch 13 22 59.0
condition 6 12 50.0
subroutine 13 14 92.8
pod 2 2 100.0
total 90 109 82.5


line stmt bran cond sub pod time code
1             package Log::Shiras::TapPrint;
2             our $AUTHORITY = 'cpan:JANDREW';
3 1     1   441 use version; our $VERSION = version->declare("v0.46.0");
  1         2  
  1         6  
4 1     1   71 use strict;
  1         2  
  1         17  
5 1     1   3 use warnings;
  1         1  
  1         23  
6 1     1   21 use 5.010;
  1         2  
7 1     1   3 use utf8;
  1         1  
  1         6  
8 1     1   19 use lib '../../';
  1         2  
  1         6  
9             #~ use Log::Shiras::Unhide qw( :InternalTaPPrinT );
10             ###InternalTaPPrinT warn "You uncovered internal logging statements for Log::Shiras::TapPrint-$VERSION" if !$ENV{hide_warn};
11 1     1   92 use Moose::Exporter;
  1         1  
  1         9  
12             Moose::Exporter->setup_import_methods(
13             as_is => [ qw( re_route_print restore_print ) ],
14             );
15 1     1   39 use MooseX::Types::Moose qw( HashRef );
  1         2  
  1         16  
16 1     1   3221 use Carp 'longmess';
  1         1  
  1         46  
17 1     1   449 use IO::Callback;
  1         3924  
  1         23  
18 1     1   5 use Log::Shiras::Switchboard;
  1         1  
  1         6  
19             my $switchboard = Log::Shiras::Switchboard->instance;
20              
21             #########1 Exported Methods 3#########4#########5#########6#########7#########8#########9
22              
23             sub re_route_print{
24 2 50   2 1 2122 warn "Re-routing print statements" if !$ENV{hide_warn};
25             ###InternalTaPPrinT $switchboard->master_talk( { report => 'log_file', level => 2,
26             ###InternalTaPPrinT name_space => 'Log::Shiras::TapPrint::re_route_print',
27             ###InternalTaPPrinT message =>[ "Re-routing print statements", ], } );
28 2         3 my ( @passed ) = @_;
29             my $data_ref =
30             ( exists $passed[0] and
31             is_HashRef( $passed[0] ) and
32             ( exists $passed[0]->{report} or
33             exists $passed[0]->{level} or
34             exists $passed[0]->{carp_stack} or
35             exists $passed[0]->{fail_over} ) ) ?
36             $passed[0] :
37             ( @passed % 2 == 0 and
38             ( exists {@passed}->{report} or
39             exists {@passed}->{level} or
40             exists {@passed}->{carp_stack} or
41 2 50 33     11 exists {@passed}->{fail_over} ) ) ?
    50 33        
42             {@passed} :
43             { level => $_[0] };
44             ###InternalTaPPrinT $switchboard->master_talk( { report => 'log_file', level => 0,
45             ###InternalTaPPrinT name_space => 'Log::Shiras::TapPrint::re_route_print',
46             ###InternalTaPPrinT message =>[ "With settings: ", $data_ref ], } );
47              
48             # set common report
49 2 50       274 if( !$data_ref->{report} ){
50 0         0 $data_ref->{report} = 'log_file';
51             ###InternalTaPPrinT $switchboard->master_talk( { report => 'log_file', level => 3,
52             ###InternalTaPPrinT name_space => 'Log::Shiras::TapPrint::re_route_print',
53             ###InternalTaPPrinT message =>[ "No report was passed to 're_route_print' so the " .
54             ###InternalTaPPrinT "target report for print is set to: 'log_file'" ], } );
55             }
56              
57             # set common urgency level
58 2 50       4 if( !$data_ref->{level} ){
59 2         4 $data_ref->{level} = 2;
60             ###InternalTaPPrinT $switchboard->master_talk( { report => 'log_file', level => 3,
61             ###InternalTaPPrinT name_space => 'Log::Shiras::TapPrint::re_route_print',
62             ###InternalTaPPrinT message =>[ "No urgency level was defined in the 're_route_print' method " .
63             ###InternalTaPPrinT "call so future 'print' messages will be sent at: 2 (These go to 11)" ], } );
64             }
65              
66             # set failover
67 2 100       3 if( !$data_ref->{fail_over} ){
68 1         2 $data_ref->{fail_over} = 0;
69             ###InternalTaPPrinT $switchboard->master_talk( { report => 'log_file', level => 3,
70             ###InternalTaPPrinT name_space => 'Log::Shiras::TapPrint::re_route_print',
71             ###InternalTaPPrinT message =>[ "fail_over was not set - setting it to: 0" ], } );
72             }
73              
74             # set (add) carp stack
75 2 50       5 if( !$data_ref->{carp_stack} ){
76 2         1 $data_ref->{carp_stack} = 0;
77             ###InternalTaPPrinT $switchboard->master_talk( { report => 'log_file', level => 3,
78             ###InternalTaPPrinT name_space => 'Log::Shiras::TapPrint::re_route_print',
79             ###InternalTaPPrinT message =>[ "carp_stack was not set - setting it to: 0" ], } );
80             }
81              
82             # Set the source_sub (Fixed for this class)
83 2         3 $data_ref->{source_sub} = 'IO::Callback::print';
84             ###InternalTaPPrinT $switchboard->master_talk( { report => 'log_file', level => 1,
85             ###InternalTaPPrinT name_space => 'Log::Shiras::TapPrint::re_route_print',
86             ###InternalTaPPrinT message =>[ "Building the coderef with the data ref: ", $data_ref, ], } );
87              
88             my $code_ref = sub{
89 5     5   2731 $data_ref->{message} = [ @_ ];
90 5         6 chomp @{$data_ref->{message}};
  5         11  
91             ###InternalTaPPrinT $switchboard->master_talk( { report => 'log_file', level => 2,
92             ###InternalTaPPrinT name_space => 'Log::Shiras::TapPrint::print',
93             ###InternalTaPPrinT message =>[ "Inbound print statement: ", $data_ref->{message} ], } );
94 5         26 my $line = (caller( 2 ))[2];
95 5 100 66     58 $data_ref->{name_space} = ((caller( 3 ))[3] and (caller( 3 ))[3] !~ /__ANON__/) ? (caller( 3 ))[3] : (caller( 2 ))[0];
96 5         11 $data_ref->{name_space} .= "::$line";
97             ###InternalTaPPrinT $switchboard->master_talk( { report => 'log_file', level => 1,
98             ###InternalTaPPrinT name_space => 'Log::Shiras::TapPrint::print',
99             ###InternalTaPPrinT message =>[ "Added name_space: ", $data_ref->{name_space}, ], } );
100              
101             # Dispatch the message
102 5         14 my $report_count = $switchboard->master_talk( $data_ref );
103             ###InternalTaPPrinT $switchboard->master_talk( { report => 'log_file', level => 2,
104             ###InternalTaPPrinT name_space => 'Log::Shiras::TapPrint::print',
105             ###InternalTaPPrinT message =>[ "Message reported |$report_count| times"], } );
106              
107             # Handle fail_over
108 5 100 66     15 if( $report_count == 0 and $data_ref->{fail_over} ){
109             ###InternalTelephonE $switchboard->master_talk( { report => 'log_file', level => 4,
110             ###InternalTelephonE name_space => 'Log::Shiras::TapPrint::print',
111             ###InternalTelephonE message => [ "Message allowed but found no destination!", $data_ref->{message} ], } );
112 1         201 print STDOUT longmess( "This message sent to the report -$data_ref->{report}- was approved but found no destination objects to use" ), @_;
113             }
114 5         265 return 1;
115 2         9 };
116 2 50       17 select( IO::Callback->new('>', $code_ref) ) or die "Couldn't redirect STDOUT: $!";
117             ###InternalTaPPrinT $switchboard->master_talk( { report => 'log_file', level => 0,
118             ###InternalTaPPrinT name_space => 'Log::Shiras::TapPrint::re_route_print',
119             ###InternalTaPPrinT message =>[ "Finished re_routing print statements" ], } );
120 2         87 return 1;
121             }
122              
123             sub restore_print{
124 0 0   0 1   select( STDOUT ) or
125             die "Couldn't reset print: $!";
126             ###InternalTaPPrinT $switchboard->master_talk( { report => 'log_file', level => 0,
127             ###InternalTaPPrinT name_space => 'Log::Shiras::TapPrint::restore_print',
128             ###InternalTaPPrinT message =>[ "Log::Shiras is no longer tapping into 'print' statements!" ], } );
129 0           return 1;
130             }
131              
132             #########1 Phinish 3#########4#########5#########6#########7#########8#########9
133              
134             1;
135              
136             #########1 main pod docs 3#########4#########5#########6#########7#########8#########9
137             __END__
138              
139             =head1 NAME
140              
141             Log::Shiras::TapPrint - Reroute print to Log::Shiras::Switchboard
142              
143             =head1 SYNOPSIS
144              
145             use Modern::Perl;
146             #~ use Log::Shiras::Unhide qw( :InternalTaPPrinT );
147             $ENV{hide_warn} = 0;
148             use Log::Shiras::Switchboard;
149             use Log::Shiras::TapPrint 're_route_print';
150             my $ella_peterson = Log::Shiras::Switchboard->get_operator(
151             name_space_bounds =>{
152             UNBLOCK =>{
153             log_file => 'debug',
154             },
155             main =>{
156             27 =>{
157             UNBLOCK =>{
158             log_file => 'info',
159             },
160             },
161             },
162             },
163             reports =>{ log_file =>[ Print::Log->new ] },
164             );
165             re_route_print(
166             fail_over => 0,
167             level => 'debug',
168             report => 'log_file',
169             );
170             print "Hello World 1\n";
171             print "Hello World 2\n";
172             print STDOUT "Hello World 3\n";
173             restore_print;
174             print "Hello World 4\n";
175              
176             package Print::Log;
177             use Data::Dumper;
178             sub new{
179             bless {}, shift;
180             }
181             sub add_line{
182             shift;
183             my @input = ( ref $_[0]->{message} eq 'ARRAY' ) ?
184             @{$_[0]->{message}} : $_[0]->{message};
185             my ( @print_list, @initial_list );
186             no warnings 'uninitialized';
187             for my $value ( @input ){
188             push @initial_list, (( ref $value ) ? Dumper( $value ) : $value );
189             }
190             for my $line ( @initial_list ){
191             $line =~ s/\n$//;
192             $line =~ s/\n/\n\t\t/g;
193             push @print_list, $line;
194             }
195             my $output = sprintf( "| level - %-6s | name_space - %-s\n| line - %04d | file_name - %-s\n\t:(\t%s ):\n",
196             $_[0]->{level}, $_[0]->{name_space},
197             $_[0]->{line}, $_[0]->{filename},
198             join( "\n\t\t", @print_list ) );
199             print STDOUT $output;
200             use warnings 'uninitialized';
201             }
202              
203             1;
204              
205             #######################################################################################
206             # Synopsis Screen Output
207             # 01: Re-routing print statements at ../lib/Log/Shiras/TapPrint.pm line 22, <DATA> line 1.
208             # 02: | level - debug | name_space - main::26
209             # 03: | line - 0026 | file_name - log_shiras_tapprint.pl
210             # 04: :( Hello World 1 ):
211             # 05: Hello World 3
212             # 06: Hello World 4
213             #######################################################################################
214              
215             =head1 DESCRIPTION
216              
217             This package allows Log::Shiras to be used for code previously written with print statement
218             outputs. It will re-direct the print statements using the L<select
219             |http://perldoc.perl.org/functions/select.html> command with L<IO::Callback>. Using this
220             mechanisim means that a call to;
221              
222             print STDOUT "Print some line\n";
223              
224             Will still do as expected but;
225              
226             print "Capture this line\n";
227              
228             Will be routed to L<Log::Shiras::Switchboard>.
229              
230             This class is used to import functions into the script. These are not object methods and
231             there is no reason to call ->new. Uncomment line 2 of the SYNOPSIS to watch the inner
232             workings.
233              
234             =head2 Output Explanation
235              
236             B<01:> The method re_route_print will throw a warning statement whenever
237             $ENV{hide_warn} is not set and the method is called.
238              
239             B<02-04:> Line 26 of the code has been captured (meta data appended) and then sent to the
240             Print::Log class for reporting.
241              
242             B<05:> Line 27 of the script did not print since that line requires a different urgency than
243             the urgency provided by the L<re_route_print|/re_route_print( %args )> call in the SYNOPSIS.
244             Line 28 is not re-routed and does print normally since it is explicitly sent to STDOUT.
245              
246             B<06:> Line 29 of the script turns off re-routing so Line 30 of the script prints normally
247             with no shenanigans.
248              
249             =head2 Functions
250              
251             These functions are used to change the routing of general print statements.
252              
253             =head2 re_route_print( %args )
254              
255             This is the function used to re_route generic print statements to
256             L<Log::Shiras::Switchboard> for processing. There are several settings adjustments that
257             affect the routing of these statements. Since print statments are intended to be captured
258             in-place, with no modification, all these settings must be fixed when the re-routing is
259             implemented. Fine grained control of which print statements are used is done by line
260             number (See the SYNOPSIS for an example). This function accepts all of the possible
261             settings, minimally scrubs the data as needed, builds the needed anonymous subroutine,
262             and then redirects generic print statements to that subroutine. Each set of content from
263             generic print statements will then be packaged by the anonymous subroutine and sent to
264             L<Log::Shiras::Switchboard/master_talk( $args_ref )>. Since print statements are generally
265             scattered throughout pre-existing code the name-space is either 'main::line_number' for
266             scripts or the subroutine block name within which the print statement occurs with the line
267             number. For example the name_space 'main::my_sub::32' would be applied to a print
268             statement executed on line 32 within the sub block named 'my_sub' in the 'main' script.
269              
270             =over
271              
272             B<Accepts:>
273              
274             The following keys in a hash or hashref which are passed directly to
275             L<Log::Shiras::Switchboard/master_talk( $args_ref )> - see the documentation there to
276             understand how they are used by the switchboard. All values that are passed remain in force
277             until a new re_route_print call is made or the L<restore_print|/restore_print> call is made.
278              
279             =over
280              
281             report - I<default = 'log_file'>
282              
283             level - I<default = 2 (info)>
284              
285             fail_over - I<default = 0>
286              
287             carp_stack - I<default = 0>
288              
289             =back
290              
291             B<Returns:> 1
292              
293             =back
294              
295             =head2 restore_print
296              
297             This sends all generic print statements to STDOUT using L<select
298             |http://perldoc.perl.org/functions/select.html>.
299              
300             =over
301              
302             B<Accepts:> Nothing
303              
304             B<Returns:> 1
305              
306             =back
307              
308             =head1 SUPPORT
309              
310             =over
311              
312             L<github Log-Shiras/issues|https://github.com/jandrew/Log-Shiras/issues>
313              
314             =back
315              
316             =head1 GLOBAL VARIABLES
317              
318             =over
319              
320             =item B<$ENV{hide_warn}>
321              
322             The module will warn when re-routing print statements are turned on. It
323             will also warn when internal debug lines are 'Unhide'n. In
324             the case where the you don't want these warnings then set this
325             environmental variable to true.
326              
327             =back
328              
329             =head1 TODO
330              
331             =over
332              
333             B<1.> Nothing currently
334              
335             =back
336              
337             =head1 AUTHOR
338              
339             =over
340              
341             =item Jed Lund
342              
343             =item jandrew@cpan.org
344              
345             =back
346              
347             =head1 COPYRIGHT
348              
349             This program is free software; you can redistribute
350             it and/or modify it under the same terms as Perl itself.
351              
352             The full text of the license can be found in the
353             LICENSE file included with this module.
354              
355             =head1 DEPENDANCIES
356              
357             =over
358              
359             L<version>
360              
361             L<5.010|http://perldoc.perl.org/perl5100delta.html> (for use of
362             L<defined or|http://perldoc.perl.org/perlop.html#Logical-Defined-Or> //)
363              
364             L<utf8>
365              
366             L<Moose::Exporter>
367              
368             L<MooseX::Types::Moose>
369              
370             L<Carp> - longmess
371              
372             L<IO::Callback>
373              
374             L<Log::Shiras::Switchboard>
375              
376             =back
377              
378             =head1 SEE ALSO
379              
380             =over
381              
382             L<Capture::Tiny> - capture_stdout
383              
384             =back
385              
386             =cut
387              
388             #########1 main pod docs end 3#########4#########5#########6#########7#########8#########9