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