File Coverage

blib/lib/Log/Dispatch/TextTable.pm
Criterion Covered Total %
statement 45 46 97.8
branch 7 8 87.5
condition 1 2 50.0
subroutine 13 14 92.8
pod 7 7 100.0
total 73 77 94.8


line stmt bran cond sub pod time code
1 3     3   1042593 use strict;
  3         16  
  3         93  
2 3     3   17 use warnings;
  3         6  
  3         134  
3             package Log::Dispatch::TextTable 0.033;
4 3     3   18 use parent qw(Log::Dispatch::Output);
  3         5  
  3         22  
5             # ABSTRACT: log events to a textual table
6              
7 3     3   104999 use Log::Dispatch 2.0 ();
  3         75  
  3         66  
8 3     3   2009 use Text::Table;
  3         51394  
  3         1395  
9              
10             #pod =head1 SYNOPSIS
11             #pod
12             #pod use Log::Dispatch;
13             #pod use Log::Dispatch::TextTable;
14             #pod
15             #pod my $log = Log::Dispatch->new;
16             #pod
17             #pod $log->add(Log::Dispatch::TextTable->new(
18             #pod name => 'text_table',
19             #pod min_level => 'debug',
20             #pod flush_if => sub { (shift)->event_count >= 60 },
21             #pod ));
22             #pod
23             #pod while (@events) {
24             #pod # every 60 events, a formatted table is printed to the screen
25             #pod $log->warn($_);
26             #pod }
27             #pod
28             #pod =head1 DESCRIPTION
29             #pod
30             #pod This provides a Log::Dispatch log output system that builds logged events into
31             #pod a textual table and, when done, does something with the table. By default, it
32             #pod will print the table.
33             #pod
34             #pod =method new
35             #pod
36             #pod my $table_log = Log::Dispatch::TextTable->new(\%arg);
37             #pod
38             #pod This method constructs a new Log::Dispatch::TextTable output object. Valid
39             #pod arguments are:
40             #pod
41             #pod send_to - a coderef indicating where to send the logging table (optional)
42             #pod defaults to print to stdout; see transmit method
43             #pod flush_if - a coderef indicating whether, if ever, to flush (optional)
44             #pod defaults to never flush; see should_flush and flush methods
45             #pod columns - an arrayref of columns to include in the table; message, level,
46             #pod and time are always provided
47             #pod
48             #pod =cut
49              
50             sub new {
51 3     3 1 2420 my ($class, %arg) = @_;
52              
53             # when done, by default, print out the passed-in table
54 3   50 0   16 $arg{send_to} ||= sub { print $_[0] };
  0         0  
55              
56             # construct the column list, using the default if no columns were given
57 3 100       21 my @columns = $arg{columns} ? @{ $arg{columns} } : qw(time level message);
  1         4  
58 3         9 my @header = map { $_, \q{ | } } @columns;
  8         23  
59 3         14 $#header--; # drop the final |-divider
60              
61 3         24 my $table = Text::Table->new(@header);
62              
63             my $self = {
64             columns => \@columns,
65             table => $table,
66             send_to => $arg{send_to},
67             flush_if => $arg{flush_if},
68 3         4523 };
69              
70 3         11 bless $self => $class;
71              
72             # this is our duty as a well-behaved Log::Dispatch plugin
73 3         40 $self->_basic_init(%arg);
74              
75 3         416 return $self;
76             }
77              
78             #pod =method log_message
79             #pod
80             #pod This is the method which performs the actual logging, as detailed by
81             #pod Log::Dispatch::Output. It adds the data to the table and may flush. (See
82             #pod L</should_flush>.)
83             #pod
84             #pod =cut
85              
86             sub log_message {
87 11     11 1 9612 my ($self, %p) = @_;
88 11 50       404 $p{time} = localtime unless exists $p{time};
89              
90             $self->table->add(
91 11         59 @p{ @{ $self->{columns} } }
  11         63  
92             );
93              
94 11 100       1014 $self->flush(\%p) if $self->should_flush;
95             }
96              
97             #pod =method table
98             #pod
99             #pod This method returns the Text::Table object being used for the log's logging.
100             #pod
101             #pod =cut
102              
103 28     28 1 997 sub table { return $_[0]->{table} }
104              
105             #pod =method entry_count
106             #pod
107             #pod This method returns the current number of entries in the table.
108             #pod
109             #pod =cut
110              
111             sub entry_count {
112 6     6 1 26 my ($self) = @_;
113 6         14 $self->table->body_height;
114             }
115              
116             #pod =method flush
117             #pod
118             #pod This method transmits the current table and then clears it. This is useful for
119             #pod emptying large tables every now and then.
120             #pod
121             #pod =cut
122              
123             sub flush {
124 1     1 1 16 my ($self) = @_;
125 1         4 $self->transmit;
126 1         9825 $self->table->clear;
127             }
128              
129             #pod =method should_flush
130             #pod
131             #pod This method returns true if the logger is ready to flush its contents. This is
132             #pod always false, unless a C<flush_if> callback was provided during instantiation.
133             #pod
134             #pod The callback is passed the Log::Dispatch::TextTable object and a reference to
135             #pod the last entry logged.
136             #pod
137             #pod =cut
138              
139             sub should_flush {
140 11     11 1 26 my ($self, $p) = @_;
141              
142 11 100       83 return unless (ref $self->{flush_if} eq 'CODE');
143              
144 6         19 return $self->{flush_if}->($self, $p);
145             }
146              
147             #pod =method transmit
148             #pod
149             #pod This method sends out the table's current contents to their destination via
150             #pod the callback provided via the C<send_to> argument to C<new>.
151             #pod
152             #pod =cut
153              
154             sub transmit {
155 4     4 1 17 my ($self) = @_;
156 4         10 $self->{send_to}->($self->table);
157             }
158              
159             sub DESTROY {
160 3     3   74 my ($self) = @_;
161 3         20 $self->transmit;
162             }
163              
164             #pod =head1 TODO
165             #pod
166             #pod I'd like to make it possible to transmit just the rows since the last transmit
167             #pod I<without> flushing, but Text::Table needs a bit of a patch for that.
168             #pod
169             #pod =cut
170              
171             1;
172              
173             __END__
174              
175             =pod
176              
177             =encoding UTF-8
178              
179             =head1 NAME
180              
181             Log::Dispatch::TextTable - log events to a textual table
182              
183             =head1 VERSION
184              
185             version 0.033
186              
187             =head1 SYNOPSIS
188              
189             use Log::Dispatch;
190             use Log::Dispatch::TextTable;
191            
192             my $log = Log::Dispatch->new;
193            
194             $log->add(Log::Dispatch::TextTable->new(
195             name => 'text_table',
196             min_level => 'debug',
197             flush_if => sub { (shift)->event_count >= 60 },
198             ));
199            
200             while (@events) {
201             # every 60 events, a formatted table is printed to the screen
202             $log->warn($_);
203             }
204              
205             =head1 DESCRIPTION
206              
207             This provides a Log::Dispatch log output system that builds logged events into
208             a textual table and, when done, does something with the table. By default, it
209             will print the table.
210              
211             =head1 PERL VERSION
212              
213             This library should run on perls released even a long time ago. It should work
214             on any version of perl released in the last five years.
215              
216             Although it may work on older versions of perl, no guarantee is made that the
217             minimum required version will not be increased. The version may be increased
218             for any reason, and there is no promise that patches will be accepted to lower
219             the minimum required perl.
220              
221             =head1 METHODS
222              
223             =head2 new
224              
225             my $table_log = Log::Dispatch::TextTable->new(\%arg);
226              
227             This method constructs a new Log::Dispatch::TextTable output object. Valid
228             arguments are:
229              
230             send_to - a coderef indicating where to send the logging table (optional)
231             defaults to print to stdout; see transmit method
232             flush_if - a coderef indicating whether, if ever, to flush (optional)
233             defaults to never flush; see should_flush and flush methods
234             columns - an arrayref of columns to include in the table; message, level,
235             and time are always provided
236              
237             =head2 log_message
238              
239             This is the method which performs the actual logging, as detailed by
240             Log::Dispatch::Output. It adds the data to the table and may flush. (See
241             L</should_flush>.)
242              
243             =head2 table
244              
245             This method returns the Text::Table object being used for the log's logging.
246              
247             =head2 entry_count
248              
249             This method returns the current number of entries in the table.
250              
251             =head2 flush
252              
253             This method transmits the current table and then clears it. This is useful for
254             emptying large tables every now and then.
255              
256             =head2 should_flush
257              
258             This method returns true if the logger is ready to flush its contents. This is
259             always false, unless a C<flush_if> callback was provided during instantiation.
260              
261             The callback is passed the Log::Dispatch::TextTable object and a reference to
262             the last entry logged.
263              
264             =head2 transmit
265              
266             This method sends out the table's current contents to their destination via
267             the callback provided via the C<send_to> argument to C<new>.
268              
269             =head1 TODO
270              
271             I'd like to make it possible to transmit just the rows since the last transmit
272             I<without> flushing, but Text::Table needs a bit of a patch for that.
273              
274             =head1 AUTHOR
275              
276             Ricardo SIGNES <cpan@semiotic.systems>
277              
278             =head1 CONTRIBUTORS
279              
280             =for stopwords Ricardo SIGNES Signes
281              
282             =over 4
283              
284             =item *
285              
286             Ricardo SIGNES <rjbs@codesimply.com>
287              
288             =item *
289              
290             Ricardo Signes <rjbs@semiotic.systems>
291              
292             =back
293              
294             =head1 COPYRIGHT AND LICENSE
295              
296             This software is copyright (c) 2022 by Ricardo SIGNES.
297              
298             This is free software; you can redistribute it and/or modify it under
299             the same terms as the Perl 5 programming language system itself.
300              
301             =cut