fix pod error
[p5sagit/Log-Contextual.git] / lib / Log / Contextual / TeeLogger.pm
1 package Log::Contextual::TeeLogger;
2
3 use strict;
4 use warnings;
5
6 {
7    for my $name (qw( trace debug info warn error fatal )) {
8
9       no strict 'refs';
10
11       *{$name} = sub {
12          my $self = shift;
13
14          foreach my $logger (@{$self->{loggers}}) {
15             $logger->$name(@_);
16          }
17       };
18
19       my $is_name = "is_${name}";
20
21       *{$is_name} = sub {
22          my $self = shift;
23          foreach my $logger (@{$self->{loggers}}) {
24             return 1 if $logger->$is_name(@_);
25          }
26          return 0;
27       };
28    }
29 }
30
31 sub new {
32    my ($class, $args) = @_;
33    my $self = bless {}, $class;
34
35    ref($self->{loggers} = $args->{loggers}) eq 'ARRAY'
36      or die "No loggers passed to tee logger";
37
38    return $self;
39 }
40
41 1;
42
43 __END__
44
45 =head1 NAME
46
47 Log::Contextual::TeeLogger - Output to more than one logger
48
49 =head1 SYNOPSIS
50
51  use Log::Contextual::SimpleLogger;
52  use Log::Contextual::TeeLogger;
53  use Log::Contextual qw( :log ),
54    -logger => Log::Contextual::TeeLogger->new({ loggers => [
55      Log::Contextual::SimpleLogger->new({ levels => [ 'debug' ] }),
56      Log::Contextual::SimpleLogger->new({
57        levels => [ 'info' ],
58        coderef => sub { print @_ },
59      }),
60    ]});
61
62  ## docs below here not yet edited
63
64  log_info { 'program started' }; # no-op because info is not in levels
65  sub foo {
66    log_debug { 'entered foo' };
67    ...
68  }
69
70 =head1 DESCRIPTION
71
72 This module is a simple logger made mostly for demonstration and initial
73 experimentation with L<Log::Contextual>.  We recommend you use a real logger
74 instead.  For something more serious but not overly complicated, take a look at
75 L<Log::Dispatchouli>.
76
77 =head1 METHODS
78
79 =head2 new
80
81 Arguments: C<< Dict[ levels => ArrayRef[Str], coderef => Optional[CodeRef] ] $conf >>
82
83  my $l = Log::Contextual::SimpleLogger->new({
84    levels => [qw( info warn )],
85    coderef => sub { print @_ }, # the default prints to STDERR
86  });
87
88 Creates a new SimpleLogger object with the passed levels enabled and optionally
89 a C<CodeRef> may be passed to modify how the logs are output/stored.
90
91 Levels may contain:
92
93  trace
94  debug
95  info
96  warn
97  error
98  fatal
99
100 =head2 $level
101
102 Arguments: C<@anything>
103
104 All of the following six methods work the same.  The basic pattern is:
105
106  sub $level {
107    my $self = shift;
108
109    print STDERR "[$level] " . join qq{\n}, @_;
110       if $self->is_$level;
111  }
112
113 =head3 trace
114
115  $l->trace( 'entered method foo with args ' join q{,}, @args );
116
117 =head3 debug
118
119  $l->debug( 'entered method foo' );
120
121 =head3 info
122
123  $l->info( 'started process foo' );
124
125 =head3 warn
126
127  $l->warn( 'possible misconfiguration at line 10' );
128
129 =head3 error
130
131  $l->error( 'non-numeric user input!' );
132
133 =head3 fatal
134
135  $l->fatal( '1 is never equal to 0!' );
136
137 =head2 is_$level
138
139 All of the following six functions just return true if their respective
140 level is enabled.
141
142 =head3 is_trace
143
144  say 'tracing' if $l->is_trace;
145
146 =head3 is_debug
147
148  say 'debuging' if $l->is_debug;
149
150 =head3 is_info
151
152  say q{info'ing} if $l->is_info;
153
154 =head3 is_warn
155
156  say 'warning' if $l->is_warn;
157
158 =head3 is_error
159
160  say 'erroring' if $l->is_error;
161
162 =head3 is_fatal
163
164  say q{fatal'ing} if $l->is_fatal;
165
166 =head1 AUTHOR
167
168 See L<Log::Contextual/"AUTHOR">
169
170 =head1 COPYRIGHT
171
172 See L<Log::Contextual/"COPYRIGHT">
173
174 =head1 LICENSE
175
176 See L<Log::Contextual/"LICENSE">
177
178 =cut
179