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