File Coverage

blib/lib/Log/MixedColor.pm
Criterion Covered Total %
statement 67 67 100.0
branch 14 16 87.5
condition 3 3 100.0
subroutine 13 13 100.0
pod 5 5 100.0
total 102 104 98.0


line stmt bran cond sub pod time code
1             # Author: Matthew Mallard
2             # Website: www.q-technologies.com.au
3             # Date: 6th October 2016
4              
5             # ABSTRACT: Outputs messages in multiple colors
6              
7              
8              
9              
10              
11             package Log::MixedColor;
12 1     1   127139 use Moose;
  1         474524  
  1         9  
13 1     1   7634 use Moose::Exporter;
  1         3  
  1         7  
14 1     1   747 use MooseX::Aliases;
  1         1406  
  1         4  
15 1     1   56434 use 5.10.0;
  1         4  
16 1     1   791 use Term::ANSIColor;
  1         10262  
  1         83  
17 1     1   507 use Module::Load::Conditional qw[ check_install ];
  1         18972  
  1         62  
18              
19 1     1   7 use constant DEBUG_MSG => "debug";
  1         2  
  1         53  
20 1     1   6 use constant ERROR_MSG => "error";
  1         7  
  1         811  
21              
22             # We only need to activate storage when someone using us has already installed the module
23             # otherwise the following code can silently fail
24             if( check_install( module => 'MooseX::Storage' )){
25             require MooseX::Storage;
26             MooseX::Storage->import();
27             with Storage(
28             'format' => 'JSON',
29             'io' => 'File',
30             traits => ['DisableCycleDetection']
31             );
32             }
33              
34              
35             has 'verbose' => (
36             is => 'rw',
37             isa => 'Bool',
38             default => 0,
39             alias => 'v',
40             );
41              
42              
43             has 'debug' => (
44             is => 'rw',
45             isa => 'Bool',
46             default => 0,
47             alias => 'd',
48             );
49              
50              
51             sub quote {
52 1     1 1 7383 my $self = shift;
53 1         7 return '%%' . shift() . '##';
54             }
55             alias q => 'quote';
56              
57              
58             has 'quote_start' => (
59             is => 'rw',
60             isa => 'Str',
61             default => '%%',
62             );
63              
64              
65              
66             has 'quote_end' => (
67             is => 'rw',
68             isa => 'Str',
69             default => '##',
70             );
71              
72              
73              
74             sub info_msg {
75 15     15 1 4045 my $self = shift;
76 15         31 chomp( my $msg = shift );
77 15         21 my $level = shift;
78 15 100       39 $level = "" if !$level;
79 15         494 my $color = $self->info_color;
80 15         402 my $var_col = $self->info_quote_color;
81 15         428 my $prefix = $self->info_prefix;
82 15   100     421 my $say = ( $self->verbose or $self->debug );
83 15         29 my $extra_nl = "";
84 15         19 my $excl = "";
85 15         38 my $fh = *STDOUT;
86 15 100       54 if( $level eq DEBUG_MSG ){
    100          
87 3         78 $color = $self->debug_color;
88 3         84 $var_col = $self->debug_quote_color;
89 3         82 $prefix = $self->debug_prefix;
90 3         72 $say = $self->debug;
91             } elsif( $level eq ERROR_MSG ){
92 7         231 $color = $self->err_color;
93 7         185 $var_col = $self->err_quote_color;
94 7         178 $prefix = $self->err_prefix;
95 7         12 $say = 1;
96 7         11 $extra_nl = "\n";
97 7         8 $excl = "!";
98 7         20 $fh = *STDERR;
99             }
100 15         33 for( $msg ){
101 15         41 my $code1 = color("reset") . color($var_col);
102 15         581 my $code2 = color("reset") . color($color);
103 15         525 s/%%/$code1/g;
104 15         54 s/##/$code2/g;
105             }
106 15 50       44 $prefix = $prefix . " " if $prefix;
107 15 100       59 say $fh $extra_nl
108             . color($color)
109             . $prefix
110             . $msg
111             . $excl
112             . color("reset")
113             . $extra_nl
114             if $say;
115             }
116             alias info => 'info_msg';
117              
118              
119             sub debug_msg {
120 5     5 1 3396 my $self = shift;
121 5         9 my $msg = shift;
122 5 100       170 $self->info_msg( $msg, DEBUG_MSG ) if $self->debug;
123             }
124             alias dmsg => 'debug_msg';
125              
126              
127             sub err_msg {
128 5     5 1 3329 my $self = shift;
129 5         10 my $msg = shift;
130 5         12 $self->info_msg( $msg, ERROR_MSG );
131             }
132             alias err => 'err_msg';
133             alias warn => 'err_msg';
134              
135              
136             sub fatal_err {
137 2     2 1 5520 my $self = shift;
138 2         3 my $msg = shift;
139 2         4 my $val = shift;
140 2 100       7 $val = 1 unless defined( $val );
141 2         8 $self->info_msg( $msg, ERROR_MSG );
142 2 50       195 exit $val if $self->fatal_is_fatal;
143             }
144             alias fatal => 'fatal_err';
145              
146              
147             has 'fatal_is_fatal' => (
148             is => 'rw',
149             isa => 'Bool',
150             default => 1,
151             );
152              
153              
154             has 'info_color' => (
155             is => 'rw',
156             isa => 'Str',
157             default => 'green',
158             );
159              
160             has 'debug_color' => (
161             is => 'rw',
162             isa => 'Str',
163             default => 'magenta',
164             );
165              
166             has 'err_color' => (
167             is => 'rw',
168             isa => 'Str',
169             default => 'red',
170             );
171              
172             has 'info_quote_color' => (
173             is => 'rw',
174             isa => 'Str',
175             default => 'black on_white',
176             );
177              
178             has 'debug_quote_color' => (
179             is => 'rw',
180             isa => 'Str',
181             default => 'blue',
182             );
183              
184             has 'err_quote_color' => (
185             is => 'rw',
186             isa => 'Str',
187             default => 'yellow',
188             );
189              
190             has 'info_prefix' => (
191             is => 'rw',
192             isa => 'Str',
193             default => 'Info:',
194             );
195              
196             has 'debug_prefix' => (
197             is => 'rw',
198             isa => 'Str',
199             default => 'Debug:',
200             );
201              
202             has 'err_prefix' => (
203             is => 'rw',
204             isa => 'Str',
205             default => 'Error:',
206             );
207              
208              
209              
210              
211             1;
212              
213             __END__
214              
215             =pod
216              
217             =encoding UTF-8
218              
219             =head1 NAME
220              
221             Log::MixedColor - Outputs messages in multiple colors
222              
223             =head1 VERSION
224              
225             version 1.000
226              
227             =head1 SYNOPSIS
228              
229             Output log messages in color while emphasizing parts of the message in a different color.
230             Although colour codes witin a message string can be done manually, this module is providing a
231             simplified approach to colour logging hopefully saving time and code
232             (and colour codes can also be inserted manually if required - i.e. they won't be stripped).
233              
234             use Log::MixedColor;
235             my $log = Log::MixedColor->new;
236              
237             $log->verbose(1);
238             $log->info_msg( "This is a " . $log->quote('general info') . " message." );
239              
240             $log->debug(1);
241             $log->debug_msg( "This is a " . $log->q('debug') . " message" );
242              
243             There are four types of messages:
244              
245             =over
246              
247             =item * C<info_msg> (or C<info>) - displayed when debug or verbose are turned on
248              
249             =item * C<debug_msg> (or C<dmsg>) - displayed when debug is turned on
250              
251             =item * C<err_msg> (or C<err>) - displayed all the time on STDERR
252              
253             =item * C<fatal_msg> (or C<fatal>) - displayed all the time on STDERR and will cause the script to exit
254              
255             =back
256              
257             The C<debug> and C<verbose> methods are intended so that the script utilising this module can
258             pass the command line option values specifying whether to operate the script logging in verbose or debug mode.
259              
260             use Getopt::Std;
261             use Log::MixedColor;
262              
263             our( $opt_v, $opt_d );
264             getopts('vd');
265              
266             my $log = Log::MixedColor->new( verbose => $opt_v, debug => $opt_d );
267              
268             $log->info_msg( "This is a " . $log->quote('general info') . " message." );
269             $log->debug_msg( "This is a " . $log->q('debug') . " message" );
270              
271             The debug log messages will only display when the script is run with C<-d> and the verbose messages will
272             be display when the script is run with C<-d> or C<-v>.
273              
274             =head1 METHODS
275              
276             =head2 new
277              
278             Create the I<Log::MixedColor> object. The following can be set at creation time (defaults shown):
279              
280             my $log = Log::MixedColor->new(
281             verbose => 0,
282             debug => 0,
283             fatal_is_fatal => 1
284             );
285              
286             which is equivalent to:
287              
288             my $log = Log::MixedColor->new;
289              
290             =head2 verbose
291              
292             Put the log object in verbose mode.
293              
294             $log->verbose(1);
295              
296             =head2 v
297              
298             Alias for C<verbose>.
299              
300             =head2 debug
301              
302             Put the log object in debug mode.
303              
304             $log->debug(1);
305              
306             =head2 d
307              
308             Alias for C<debug>.
309              
310             =head2 quote
311              
312             Quote a portion of the message in a different color to the rest of the message
313              
314             $log->debug_msg( "This is a ".$log->quote('quoted bit')." inside a message." );
315              
316             Alternatively, instead of using this method, you could just use the quoting strings directly, e.g.:
317              
318             $log->debug_msg( "This is a %%quoted bit## inside a message." );
319              
320             =head2 q
321              
322             Alias for C<quote>.
323              
324             =head2 quote_start
325              
326             Sets the string used to denote the start of the text to be quoted in a different color. Default shown
327              
328             $log->quote_start( '%%' );
329              
330             It needs to be different from that specified by C<quote_end>.
331              
332             =head2 quote_end
333              
334             Sets the string used to denote the end of the text to be quoted in a different color. Default shown.
335              
336             $log->quote_end( '##' );
337              
338             It needs to be different from that specified by C<quote_start>.
339              
340             =head2 info_msg
341              
342             Display a message on C<STDOUT> when the log object is in debug or verbose mode.
343              
344             $log->info_msg( "This is a " . $log->quote('general') . " message." );
345              
346             =head2 info
347              
348             Alias for C<info_msg>.
349              
350             =head2 debug_msg
351              
352             Display a message on C<STDOUT> when the log object is in debug mode.
353              
354             $log->debug_msg( "This is a " . $log->quote('low level') . " message." );
355              
356             =head2 dmsg
357              
358             Alias for C<debug_msg>.
359              
360             =head2 err_msg
361              
362             Display a message on C<STDERR>.
363              
364             $log->err_msg( "This is a " . $log->quote('warning') . " message." );
365              
366             =head2 err
367              
368             Alias for C<err_msg>.
369              
370             =head2 warn
371              
372             Alias for C<err_msg>.
373              
374             =head2 fatal_err
375              
376             Display a message on C<STDERR> and then exit the script.
377              
378             $log->fatal_err( "This is a ".$log->quote('critical')." message so we have to stop.", 2 );
379              
380             The optional second argument is the exit code the script will exit with. It defaults to C<1>.
381              
382             The I<exit> feature can be turned off by setting C<$log-E<gt>fatal_is_fatal> to false.
383              
384             =head2 fatal
385              
386             Alias for C<fatal_err>.
387              
388             =head2 fatal_is_fatal
389              
390             Determines whether the C<fatal_msg> method actually causes the script to exit. It
391             will by default.
392              
393             $log->fatal_is_fatal(0);
394              
395             Turning it off will make it equivalent to C<err_msg>, but might be helpful when developing a script
396             during which time you may not want it to be fatal, but you do when your script goes into production.
397              
398             =head2 COLORS
399              
400             To customise the colors, pass the color strings as recognised by L<Term::ANSIColor> to the following
401             relevant methods or set the equivalent properties as part of C<new> (the default is shown in brackets):
402              
403             =over
404              
405             =item * C<info_color> (green)
406              
407             =item * C<debug_color> (magenta)
408              
409             =item * C<err_color> (red)
410              
411             =item * C<info_quote_color> (black on_white)
412              
413             =item * C<debug_quote_color> (blue)
414              
415             =item * C<err_quote_color> (yellow)
416              
417             =back
418              
419             The C<fatal_err> method will use the same colours as the C<err_msg> method.
420              
421             =head2 Message Prefixes
422              
423             To allow for language variations and individual preferences the prefix before the output message can
424             be customised with the following methods (defaults shown in brackets):
425              
426             =over
427              
428             =item * C<info_prefix> (Info:)
429              
430             =item * C<debug_prefix> (Debug:)
431              
432             =item * C<err_prefix> (Error:)
433              
434             =back
435              
436             The C<fatal_err> method will use the same prefix as the C<err_msg> method.
437              
438             =head1 BUGS/FEATURES
439              
440             Please report any bugs or feature requests in the issues section of GitHub:
441             L<https://github.com/Q-Technologies/perl-Log-MixedColor>. Ideally, submit a Pull Request.
442              
443             =head1 AUTHOR
444              
445             Matthew Mallard <mqtech@cpan.org>
446              
447             =head1 COPYRIGHT AND LICENSE
448              
449             This software is copyright (c) 2019 by Matthew Mallard.
450              
451             This is free software; you can redistribute it and/or modify it under
452             the same terms as the Perl 5 programming language system itself.
453              
454             =cut