File Coverage

blib/lib/Log/Dispatchouli.pm
Criterion Covered Total %
statement 261 333 78.3
branch 58 104 55.7
condition 14 22 63.6
subroutine 49 65 75.3
pod 34 40 85.0
total 416 564 73.7


line stmt bran cond sub pod time code
1 7     7   154942 use v5.20;
  7         25  
2 7     7   37 use warnings;
  7         10  
  7         548  
3             package Log::Dispatchouli 3.013;
4             # ABSTRACT: a simple wrapper around Log::Dispatch
5              
6             # Not dangerous. Accepted without change.
7 7     7   3195 use experimental 'postderef', 'signatures';
  7         26757  
  7         41  
8              
9 7     7   1667 use Carp ();
  7         17  
  7         185  
10 7     7   40 use File::Spec ();
  7         15  
  7         191  
11 7     7   4179 use Log::Dispatch;
  7         1830750  
  7         305  
12 7     7   5081 use Log::Fmt ();
  7         28  
  7         345  
13 7     7   77 use Params::Util qw(_ARRAY0 _HASH0 _CODELIKE);
  7         38  
  7         608  
14 7     7   47 use Scalar::Util qw(blessed weaken);
  7         14  
  7         369  
15 7     7   42 use String::Flogger;
  7         12  
  7         50  
16 7     7   1836 use Try::Tiny 0.04;
  7         200  
  7         14380  
17              
18             require Log::Dispatchouli::Proxy;
19              
20             our @CARP_NOT = qw(Log::Dispatchouli::Proxy);
21              
22             #pod =head1 SYNOPSIS
23             #pod
24             #pod my $logger = Log::Dispatchouli->new({
25             #pod ident => 'stuff-purger',
26             #pod facility => 'daemon',
27             #pod to_stdout => $opt->{print},
28             #pod debug => $opt->{verbose}
29             #pod });
30             #pod
31             #pod $logger->log([ "There are %s items left to purge...", $stuff_left ]);
32             #pod
33             #pod $logger->log_debug("this is extra often-ignored debugging log");
34             #pod
35             #pod $logger->log_fatal("Now we will die!!");
36             #pod
37             #pod =head1 DESCRIPTION
38             #pod
39             #pod Log::Dispatchouli is a thin layer above L<Log::Dispatch> and meant to make it
40             #pod dead simple to add logging to a program without having to think much about
41             #pod categories, facilities, levels, or things like that. It is meant to make
42             #pod logging just configurable enough that you can find the logs you want and just
43             #pod easy enough that you will actually log things.
44             #pod
45             #pod Log::Dispatchouli can log to syslog (if you specify a facility), standard error
46             #pod or standard output, to a file, or to an array in memory. That last one is
47             #pod mostly useful for testing.
48             #pod
49             #pod In addition to providing as simple a way to get a handle for logging
50             #pod operations, Log::Dispatchouli uses L<String::Flogger> to process the things to
51             #pod be logged, meaning you can easily log data structures. Basically: strings are
52             #pod logged as is, arrayrefs are taken as (sprintf format, args), and subroutines
53             #pod are called only if needed. For more information read the L<String::Flogger>
54             #pod docs.
55             #pod
56             #pod =head1 LOGGER PREFIX
57             #pod
58             #pod Log messages may be prepended with information to set context. This can be set
59             #pod at a logger level or per log item. The simplest example is:
60             #pod
61             #pod my $logger = Log::Dispatchouli->new( ... );
62             #pod
63             #pod $logger->set_prefix("Batch 123: ");
64             #pod
65             #pod $logger->log("begun processing");
66             #pod
67             #pod # ...
68             #pod
69             #pod $logger->log("finished processing");
70             #pod
71             #pod The above will log something like:
72             #pod
73             #pod Batch 123: begun processing
74             #pod Batch 123: finished processing
75             #pod
76             #pod To pass a prefix per-message:
77             #pod
78             #pod $logger->log({ prefix => 'Sub-Item 234: ' }, 'error!')
79             #pod
80             #pod # Logs: Batch 123: Sub-Item 234: error!
81             #pod
82             #pod If the prefix is a string, it is prepended to each line of the message. If it
83             #pod is a coderef, it is called and passed the message to be logged. The return
84             #pod value is logged instead.
85             #pod
86             #pod L<Proxy loggers|/METHODS FOR PROXY LOGGERS> also have their own prefix
87             #pod settings, which accumulate. So:
88             #pod
89             #pod my $proxy = $logger->proxy({ proxy_prefix => 'Subsystem 12: ' });
90             #pod
91             #pod $proxy->set_prefix('Page 9: ');
92             #pod
93             #pod $proxy->log({ prefix => 'Paragraph 6: ' }, 'Done.');
94             #pod
95             #pod ...will log...
96             #pod
97             #pod Batch 123: Subsystem 12: Page 9: Paragraph 6: Done.
98             #pod
99             #pod =method new
100             #pod
101             #pod my $logger = Log::Dispatchouli->new(\%arg);
102             #pod
103             #pod This returns a new logger, a Log::Dispatchouli object.
104             #pod
105             #pod Valid arguments are:
106             #pod
107             #pod ident - the name of the thing logging (mandatory)
108             #pod to_self - log to the logger object for testing; default: false
109             #pod to_stdout - log to STDOUT; default: false
110             #pod to_stderr - log to STDERR; default: false
111             #pod facility - to which syslog facility to send logs; default: none
112             #pod
113             #pod to_file - DEPRECATED: this option will be removed in 2025
114             #pod log to PROGRAM_NAME.YYYYMMDD in the log path; default: false
115             #pod log_file - a leaf name for the file to log to with to_file
116             #pod log_path - path in which to log to file; defaults to DISPATCHOULI_PATH
117             #pod environment variable or, failing that, to your system's tmpdir
118             #pod
119             #pod file_format - this optional coderef is passed the message to be logged
120             #pod and returns the text to write out
121             #pod
122             #pod log_pid - if 1, prefix all log entries with the pid; default: true
123             #pod can also be a comma-delimited list of log targets where pid is
124             #pod logged, like "stderr,syslog"; mostly useful for logging pid in
125             #pod syslog, but not on standard I/O
126             #pod fail_fatal - a boolean; if true, failure to log is fatal; default: true
127             #pod muted - a boolean; if true, only fatals are logged; default: false
128             #pod debug - a boolean; if true, log_debug method is not a no-op
129             #pod defaults to the truth of the DISPATCHOULI_DEBUG env var
130             #pod quiet_fatal - 'stderr' or 'stdout' or an arrayref of zero, one, or both
131             #pod fatal log messages will not be logged to these
132             #pod (default: stderr)
133             #pod config_id - a name for this logger's config; rarely needed!
134             #pod syslog_socket - a value for Sys::Syslog's "socket" arg; default: "native"
135             #pod
136             #pod The log path is either F</tmp> or the value of the F<DISPATCHOULI_PATH> env var.
137             #pod
138             #pod If the F<DISPATCHOULI_NOSYSLOG> env var is true, we don't log to syslog.
139             #pod
140             #pod =cut
141              
142 39     39 1 477378 sub new ($class, $arg = undef) {
  39         73  
  39         76  
  39         60  
143 39   100     104 $arg ||= {};
144              
145             my $ident = $arg->{ident}
146 39 100       375 or Carp::croak "no ident specified when using $class";
147              
148 38 50       121 my $config_id = defined $arg->{config_id} ? $arg->{config_id} : $ident;
149              
150 38         65 my %quiet_fatal;
151 38         95 for ('quiet_fatal') {
152 38         179 %quiet_fatal = map {; $_ => 1 } grep { defined }
  38         116  
153             exists $arg->{$_}
154 38 0       137 ? _ARRAY0($arg->{$_}) ? @{ $arg->{$_} } : $arg->{$_}
  0 50       0  
155             : ('stderr');
156             };
157              
158 38         226 my $log = Log::Dispatch->new;
159             my $self = bless {
160             dispatcher => $log,
161 38 100       2667 log_pid => (exists $arg->{log_pid} ? $arg->{log_pid} : 1),
162             } => $class;
163              
164 38 100       129 if ($arg->{to_file}) {
165 2         396 Carp::carp("to_file argument for Log::Dispatchouli is deprecated and will be removed in late 2025");
166              
167 2         508 require Log::Dispatch::File;
168             my $log_file = File::Spec->catfile(
169             ($arg->{log_path} || $self->env_value('PATH') || File::Spec->tmpdir),
170 2   33     42428 $arg->{log_file} || do {
      66        
171             my @time = localtime;
172             sprintf('%s.%04u%02u%02u',
173             $ident,
174             $time[5] + 1900,
175             $time[4] + 1,
176             $time[3])
177             }
178             );
179              
180             $log->add(
181             Log::Dispatch::File->new(
182             name => 'logfile',
183             min_level => 'debug',
184             filename => $log_file,
185             mode => 'append',
186 2         9 callbacks => do {
187 2         9 my $log_pid = $self->log_pid_for('file');
188              
189 2 100       7 if (my $format = $arg->{file_format}) {
190             sub {
191 1     1   85 my $message = {@_}->{message};
192 1 50       5 $message = "[$$] $message" if $log_pid;
193 1         5 $format->($message)
194 1         15 };
195             } else {
196             # The time format returned here is subject to change. -- rjbs,
197             # 2008-11-21
198             sub {
199 1     1   106 my $message = {@_}->{message};
200 1 50       9 $message = "[$$] $message" if $log_pid;
201 1         29 (localtime) . " $message\n";
202 1         11 };
203             }
204             },
205             )
206             );
207             }
208              
209 38 50 33     1267 if ($arg->{facility} and not $self->env_value('NOSYSLOG')) {
210             $self->setup_syslog_output(
211             facility => $arg->{facility},
212             socket => $arg->{syslog_socket},
213 0         0 ident => $ident,
214             );
215             }
216              
217 38 100       136 if ($arg->{to_self}) {
218 34         311 $self->{events} = [];
219 34         3603 require Log::Dispatch::Array;
220             $log->add(
221             Log::Dispatch::Array->new(
222             name => 'self',
223             min_level => 'debug',
224             array => $self->{events},
225             ($self->log_pid_for('self')
226 2     2   365 ? (callbacks => sub { "[$$] ". {@_}->{message} })
227 34 100       226227 : ())
228             ),
229             );
230             }
231              
232 38         5205 $self->{prefix} = $arg->{prefix};
233 38         102 $self->{ident} = $ident;
234 38         118 $self->{config_id} = $config_id;
235              
236 38         99 DEST: for my $dest (qw(err out)) {
237 76 50       291 next DEST unless $arg->{"to_std$dest"};
238 0         0 my $method = "enable_std$dest";
239              
240 0         0 $self->$method;
241             }
242              
243             $self->{debug} = exists $arg->{debug}
244 38 50       179 ? ($arg->{debug} ? 1 : 0)
    100          
    100          
245             : ($self->env_value('DEBUG') ? 1 : 0);
246 38         91 $self->{muted} = $arg->{muted};
247              
248 38         90 $self->{quiet_fatal} = \%quiet_fatal;
249 38 50       114 $self->{fail_fatal} = exists $arg->{fail_fatal} ? $arg->{fail_fatal} : 1;
250              
251 38         177 return $self;
252             }
253              
254 36     36 0 77 sub log_pid_for ($self, $output) {
  36         68  
  36         70  
  36         85  
255 36         105 my $log_pid = $self->{log_pid};
256 36 100       296 return undef unless $log_pid;
257              
258 2 50       26 return 1 if $log_pid eq 1;
259              
260 0         0 $self->{log_pid_for} = { map {; $_ => 1 } split /,/, $log_pid };
  0         0  
261              
262 0 0       0 return $self->{log_pid_for}{$output} ? 1 : undef;
263             }
264              
265             #pod =method enable_stdout
266             #pod
267             #pod =method enable_stderr
268             #pod
269             #pod These methods turn on logging to STDOUT or STDERR, respectively. If that
270             #pod logging has already been enabled, these methods do nothing.
271             #pod
272             #pod There is not, yet, a I<disable> version of these methods.
273             #pod
274             #pod =cut
275              
276             for my $dest (qw(out err)) {
277             my $name = "std$dest";
278 0     0   0 my $code = sub ($self) {
  0         0  
  0         0  
279 0 0       0 return if $self->dispatcher->output($name);
280              
281             my $callback = $self->log_pid_for($name)
282 0     0   0 ? sub { "[$$] " . ({@_}->{message}) . "\n" }
283 0 0   0   0 : sub { ({@_}->{message}) . "\n" };
  0         0  
284              
285             $self->dispatcher->add(
286             $self->stdio_dispatcher_class->new(
287             name => "std$dest",
288             min_level => 'debug',
289             stderr => ($dest eq 'err' ? 1 : 0),
290             callbacks => $callback,
291 0 0       0 ($self->{quiet_fatal}{"std$dest"} ? (max_level => 'info') : ()),
    0          
292             ),
293             );
294             };
295              
296 7     7   63 no strict 'refs';
  7         15  
  7         27828  
297             *{"enable_std$dest"} = $code;
298             }
299              
300 0     0 0 0 sub setup_syslog_output ($self, %arg) {
  0         0  
  0         0  
  0         0  
301 0         0 require Log::Dispatch::Syslog;
302             $self->{dispatcher}->add(
303             Log::Dispatch::Syslog->new(
304             name => 'syslog',
305             ident => $arg{ident},
306             facility => $arg{facility},
307             logopt => ($self->log_pid_for('syslog') ? 'pid' : ''),
308             min_level => 'debug',
309             socket => $arg{socket} || 'native',
310             callbacks => sub {
311 0     0   0 ( my $m = {@_}->{message} ) =~ s/\n/<LF>/g;
312 0         0 $m
313             },
314 0 0 0     0 ),
315             );
316             }
317              
318             #pod =method log
319             #pod
320             #pod $logger->log(@messages);
321             #pod
322             #pod $logger->log(\%arg, @messages);
323             #pod
324             #pod This method uses L<String::Flogger> on the input, then I<unconditionally> logs
325             #pod the result. Each message is flogged individually, then joined with spaces.
326             #pod
327             #pod If the first argument is a hashref, it will be used as extra arguments to
328             #pod logging. It may include a C<prefix> entry to preprocess the message by
329             #pod prepending a string (if the prefix is a string) or calling a subroutine to
330             #pod generate a new message (if the prefix is a coderef).
331             #pod
332             #pod =cut
333              
334 49     49   91 sub _flog_messages ($self, $arg, $rest) {
  49         65  
  49         109  
  49         74  
  49         68  
335 49         133 my $flogger = $self->string_flogger;
336 49         117 my @flogged = map {; $flogger->flog($_) } @$rest;
  51         430  
337 49 100       17285 my $message = @flogged > 1 ? join(q{ }, @flogged) : $flogged[0];
338              
339             my @prefix = _ARRAY0($arg->{prefix})
340 19         57 ? @{ $arg->{prefix} }
341 49 100       290 : $arg->{prefix};
342              
343 49         161 for (reverse grep { defined } $self->get_prefix, @prefix) {
  148         414  
344 76 100       197 if (_CODELIKE( $_ )) {
345 1         5 $message = $_->($message);
346             } else {
347 75         349 $message =~ s/^/$_/gm;
348             }
349             }
350              
351 49         261 return $message;
352             }
353              
354 49     49 1 101 sub flog_messages ($self, @rest) {
  49         71  
  49         104  
  49         75  
355 49 100       162 my $arg = _HASH0($rest[0]) ? shift(@rest) : {};
356 49         136 return $self->_flog_messages($arg, \@rest);
357             }
358              
359 42     42 1 432829 sub log ($self, @rest) {
  42         70  
  42         96  
  42         69  
360 42 100       199 my $arg = _HASH0($rest[0]) ? shift(@rest) : {};
361              
362 42         76 my $message;
363              
364 42 100 100     186 if ($arg->{fatal} or ! $self->get_muted) {
365             try {
366 40     40   2181 $message = $self->flog_messages($arg, @rest);
367              
368             $self->dispatcher->log(
369 40   100     136 level => $arg->{level} || 'info',
370             message => $message,
371             );
372             } catch {
373 0 0   0   0 $message = '(no message could be logged)' unless defined $message;
374 0 0       0 die $_ if $self->{fail_fatal};
375 40         370 };
376             }
377              
378 42 100       6296 Carp::croak $message if $arg->{fatal};
379              
380 39         238 return;
381             }
382              
383             #pod =method log_fatal
384             #pod
385             #pod This behaves like the C<log> method, but will throw the logged string as an
386             #pod exception after logging.
387             #pod
388             #pod This method can also be called as C<fatal>, to match other popular logging
389             #pod interfaces. B<If you want to override this method, you must override
390             #pod C<log_fatal> and not C<fatal>>.
391             #pod
392             #pod =cut
393              
394 3     3 1 27528 sub log_fatal ($self, @rest) {
  3         8  
  3         6  
  3         6  
395 3 50       20 my $arg = _HASH0($rest[0]) ? shift(@rest) : {}; # for future expansion
396              
397 3 50       23 local $arg->{level} = defined $arg->{level} ? $arg->{level} : 'error';
398 3 50       16 local $arg->{fatal} = defined $arg->{fatal} ? $arg->{fatal} : 1;
399              
400 3         12 $self->log($arg, @rest);
401             }
402              
403             #pod =method log_debug
404             #pod
405             #pod This behaves like the C<log> method, but will only log (at the debug level) if
406             #pod the logger object has its debug property set to true.
407             #pod
408             #pod This method can also be called as C<debug>, to match other popular logging
409             #pod interfaces. B<If you want to override this method, you must override
410             #pod C<log_debug> and not C<debug>>.
411             #pod
412             #pod =cut
413              
414 5     5 1 799 sub log_debug ($self, @rest) {
  5         10  
  5         14  
  5         10  
415 5 50       17 return unless $self->is_debug;
416              
417 0 0       0 my $arg = _HASH0($rest[0]) ? shift(@rest) : {}; # for future expansion
418              
419 0 0       0 local $arg->{level} = defined $arg->{level} ? $arg->{level} : 'debug';
420              
421 0         0 $self->log($arg, @rest);
422             }
423              
424             #pod =method log_event
425             #pod
426             #pod This method is like C<log>, but is used for structured logging instead of free
427             #pod form text. It's invoked like this:
428             #pod
429             #pod $logger->log($event_type => $data_ref);
430             #pod
431             #pod C<$event_type> should be a simple string, probably a valid identifier, that
432             #pod identifies the kind of event being logged. It is suggested, but not required,
433             #pod that all events of the same type have the same kind of structured data in them.
434             #pod
435             #pod C<$data_ref> is a set of key/value pairs of data to log in this event. It can
436             #pod be an arrayref (in which case the ordering of pairs is preserved) or a hashref
437             #pod (in which case they are sorted by key).
438             #pod
439             #pod The logged string will be in logfmt format, meaning a series of key=value
440             #pod pairs separated by spaces and following these rules:
441             #pod
442             #pod =for :list
443             #pod * an "identifier" is a string of printable ASCII characters between C<!> and
444             #pod C<~>, excluding C<\> and C<=>
445             #pod * keys must be valid identifiers
446             #pod * if a key is empty, C<~> is used instead
447             #pod * if a key contains characters not permitted in an identifier, they are
448             #pod replaced by C<?>
449             #pod * values must I<either> be valid identifiers, or be quoted
450             #pod * quoted value start and end with C<">
451             #pod * in a quoted value, C<"> becomes C<\">, C<\> becomes C<\\>, newline and
452             #pod carriage return become C<\n> and C<\r> respectively, and other control
453             #pod characters are replaced with C<\u{....}> where the contents of the braces are
454             #pod the hex value of the control character
455             #pod
456             #pod When values are undef, they are represented as C<~>.
457             #pod
458             #pod When values are array references, the index/values are mapped over, so that:
459             #pod
460             #pod key => [ 'a', 'b' ]
461             #pod
462             #pod becomes
463             #pod
464             #pod key.0=a key.1=b
465             #pod
466             #pod When values are hash references, the key/values are mapped, with keys sorted,
467             #pod so that:
468             #pod
469             #pod key => { b => 2, a => 1 }
470             #pod
471             #pod becomes
472             #pod
473             #pod key.a=1 key.b=2
474             #pod
475             #pod This expansion is performed recursively. If a value itself recurses,
476             #pod appearances of a reference after the first time will be replaced with a string
477             #pod like C<&foo.bar>, pointing to the first occurrence. I<This is not meant to be
478             #pod a robust serialization mechanism.> It's just here to help you be a little
479             #pod lazy. Don't push the limits.
480             #pod
481             #pod If the value in C<$data_ref> is a code reference, it will be called and its
482             #pod result logged. If its result is also a code reference, you get whatever
483             #pod garbage that code reference stringifies to.
484             #pod
485             #pod If the value in C<$data_ref> is a reference reference, then the referenced
486             #pod scalar will be passed to String::Flogger, and the resulting string will be used
487             #pod as the value to log. That string will be quoted as described above, if needed.
488             #pod
489             #pod =cut
490              
491 3     3   5 sub _compute_proxy_ctx_kvstr_aref ($) {
  3         6  
492 3         6 return [];
493             }
494              
495 14     14 1 24 sub fmt_event ($self, $type, $data) {
  14         19  
  14         20  
  14         20  
  14         15  
496             my $kv_aref = Log::Fmt->_pairs_to_kvstr_aref([
497             event => $type,
498 14 100       125 (_ARRAY0($data) ? @$data : $data->%{ sort keys %$data })
499             ]);
500              
501 14         95 return join q{ }, @$kv_aref;
502             }
503              
504 14     14 1 144 sub log_event ($self, $type, $data) {
  14         21  
  14         29  
  14         21  
  14         17  
505 14 50       43 return if $self->get_muted;
506              
507 14         42 my $message = $self->fmt_event($type, $data);
508              
509 14         69 $self->dispatcher->log(
510             level => 'info',
511             message => $message,
512             );
513              
514 14         1542 return;
515             }
516              
517             #pod =method log_debug_event
518             #pod
519             #pod This method is just like C<log_event>, but will log nothing unless the logger
520             #pod has its C<debug> property set to true.
521             #pod
522             #pod =cut
523              
524 3     3 1 14 sub log_debug_event ($self, $type, $data) {
  3         5  
  3         4  
  3         4  
  3         4  
525 3 50       7 return unless $self->get_debug;
526              
527 0         0 $self->log_event($type, $data);
528             }
529              
530             #pod =method set_debug
531             #pod
532             #pod $logger->set_debug($bool);
533             #pod
534             #pod This sets the logger's debug property, which affects the behavior of
535             #pod C<log_debug>.
536             #pod
537             #pod =cut
538              
539 0 0   0 1 0 sub set_debug ($self, $bool) { $self->{debug} = $bool ? 1 : 0 }
  0         0  
  0         0  
  0         0  
  0         0  
540              
541             #pod =method get_debug
542             #pod
543             #pod This gets the logger's debug property, which affects the behavior of
544             #pod C<log_debug>.
545             #pod
546             #pod =cut
547              
548 16     16 1 25 sub get_debug ($self) { return $self->{debug} }
  16         30  
  16         23  
  16         87  
549              
550             #pod =method clear_debug
551             #pod
552             #pod This method does nothing, and is only useful for L<Log::Dispatchouli::Proxy>
553             #pod objects. See L<Methods for Proxy Loggers|/METHODS FOR PROXY LOGGERS>, below.
554             #pod
555             #pod =cut
556              
557             sub clear_debug ($) { }
558              
559 1     1 0 5 sub mute ($self) { $self->{muted} = 1 }
  1         3  
  1         2  
  1         3  
560 3     3 0 15 sub unmute ($self) { $self->{muted} = 0 }
  3         5  
  3         5  
  3         8  
561              
562             #pod =method set_muted
563             #pod
564             #pod $logger->set_muted($bool);
565             #pod
566             #pod This sets the logger's muted property, which affects the behavior of
567             #pod C<log>.
568             #pod
569             #pod =cut
570              
571 0     0 1 0 sub set_muted ($self, $bool) {
  0         0  
  0         0  
  0         0  
572 0 0       0 return ($self->{muted} = $bool ? 1 : 0);
573             }
574              
575             #pod =method get_muted
576             #pod
577             #pod This gets the logger's muted property, which affects the behavior of
578             #pod C<log>.
579             #pod
580             #pod =cut
581              
582 60     60 1 93 sub get_muted ($self) { return $self->{muted} }
  60         108  
  60         87  
  60         277  
583              
584             #pod =method clear_muted
585             #pod
586             #pod This method does nothing, and is only useful for L<Log::Dispatchouli::Proxy>
587             #pod objects. See L<Methods for Proxy Loggers|/METHODS FOR PROXY LOGGERS>, below.
588             #pod
589             #pod =cut
590              
591             sub clear_muted ($) { }
592              
593             #pod =method get_prefix
594             #pod
595             #pod my $prefix = $logger->get_prefix;
596             #pod
597             #pod This method returns the currently-set prefix for the logger, which may be a
598             #pod string or code reference or undef. See L<Logger Prefix|/LOGGER PREFIX>.
599             #pod
600             #pod =method set_prefix
601             #pod
602             #pod $logger->set_prefix( $new_prefix );
603             #pod
604             #pod This method changes the prefix. See L<Logger Prefix|/LOGGER PREFIX>.
605             #pod
606             #pod =method clear_prefix
607             #pod
608             #pod This method clears any set logger prefix. (It can also be called as
609             #pod C<unset_prefix>, but this is deprecated. See L<Logger Prefix|/LOGGER PREFIX>.
610             #pod
611             #pod =cut
612              
613 49     49 1 75 sub get_prefix ($self) { return $self->{prefix} }
  49         102  
  49         98  
  49         367  
614 5     5 1 18 sub set_prefix ($self, $prefix) { $self->{prefix} = $prefix }
  5         9  
  5         12  
  5         7  
  5         19  
615 3     3 1 9 sub clear_prefix ($self) { $self->unset_prefix }
  3         8  
  3         5  
  3         12  
616 3     3 0 5 sub unset_prefix ($self) { undef $self->{prefix} }
  3         6  
  3         4  
  3         12  
617              
618             #pod =method ident
619             #pod
620             #pod This method returns the logger's ident.
621             #pod
622             #pod =cut
623              
624 7     7 1 270977 sub ident ($self) { $self->{ident} }
  7         15  
  7         12  
  7         87  
625              
626             #pod =method config_id
627             #pod
628             #pod This method returns the logger's configuration id, which defaults to its ident.
629             #pod This can be used to make two loggers equivalent in Log::Dispatchouli::Global so
630             #pod that trying to reinitialize with a new logger with the same C<config_id> as the
631             #pod current logger will not throw an exception, and will simply do no thing.
632             #pod
633             #pod =cut
634              
635 0     0 1 0 sub config_id ($self) { $self->{config_id} }
  0         0  
  0         0  
  0         0  
636              
637             #pod =head1 METHODS FOR SUBCLASSING
638             #pod
639             #pod =head2 string_flogger
640             #pod
641             #pod This method returns the thing on which F<flog> will be called to format log
642             #pod messages. By default, it just returns C<String::Flogger>
643             #pod
644             #pod =cut
645              
646 49     49 1 69 sub string_flogger ($) { 'String::Flogger' }
  49         94  
  49         124  
647              
648             #pod =head2 env_prefix
649             #pod
650             #pod This method should return a string used as a prefix to find environment
651             #pod variables that affect the logger's behavior. For example, if this method
652             #pod returns C<XYZZY> then when checking the environment for a default value for the
653             #pod C<debug> parameter, Log::Dispatchouli will first check C<XYZZY_DEBUG>, then
654             #pod C<DISPATCHOULI_DEBUG>.
655             #pod
656             #pod By default, this method returns C<()>, which means no extra environment
657             #pod variable is checked.
658             #pod
659             #pod =cut
660              
661 34     34 1 98 sub env_prefix ($) { return; }
  34         48  
  34         78  
662              
663             #pod =head2 env_value
664             #pod
665             #pod my $value = $logger->env_value('DEBUG');
666             #pod
667             #pod This method returns the value for the environment variable suffix given. For
668             #pod example, the example given, calling with C<DEBUG> will check
669             #pod C<DISPATCHOULI_DEBUG>.
670             #pod
671             #pod =cut
672              
673 37     37 1 60 sub env_value ($self, $suffix) {
  37         63  
  37         117  
  37         52  
674 37         213 my @path = grep { defined } ($self->env_prefix, 'DISPATCHOULI');
  40         148  
675              
676 37         77 for my $prefix (@path) {
677 38         119 my $name = join q{_}, $prefix, $suffix;
678 38 100       181 return $ENV{ $name } if defined $ENV{ $name };
679             }
680              
681 32         127 return;
682             }
683              
684             #pod =method flog_messages
685             #pod
686             #pod my $str = $logger->flog_messages($m1, $m2, ...);
687             #pod
688             #pod This returns the string that would have been logged if the given arguments had
689             #pod been passed to C<< $logger->log(...) >>, without regard for log level,
690             #pod debugging, or the like.
691             #pod
692             #pod Unlike using the logger's string flogger, this will include any relevant prefix
693             #pod strings.
694             #pod
695             #pod =method fmt_event
696             #pod
697             #pod my $str = $logger->fmt_event($event_type => $data_ref);
698             #pod
699             #pod This method is equivalent to C<flog_messages>, but for an event. It returns
700             #pod the string format of the event, including all relevant prefixes.
701             #pod
702             #pod =head1 METHODS FOR TESTING
703             #pod
704             #pod =head2 new_tester
705             #pod
706             #pod my $logger = Log::Dispatchouli->new_tester( \%arg );
707             #pod
708             #pod This returns a new logger that logs only C<to_self>. It's useful in testing.
709             #pod If no C<ident> arg is provided, one will be generated. C<log_pid> is off by
710             #pod default, but can be overridden.
711             #pod
712             #pod C<\%arg> is optional.
713             #pod
714             #pod =cut
715              
716 28     28 1 2077085 sub new_tester ($class, $arg = undef) {
  28         78  
  28         53  
  28         49  
717 28   100     110 $arg ||= {};
718              
719 28         455 return $class->new({
720             ident => "$$:$0",
721             log_pid => 0,
722             %$arg,
723             to_stderr => 0,
724             to_stdout => 0,
725             to_file => 0,
726             to_self => 1,
727             facility => undef,
728             });
729             }
730              
731             #pod =head2 events
732             #pod
733             #pod This method returns the arrayref of events logged to an array in memory (in the
734             #pod logger). If the logger is not logging C<to_self> this raises an exception.
735             #pod
736             #pod =cut
737              
738 46     46 1 2450 sub events ($self) {
  46         72  
  46         69  
739             Carp::confess "->events called on a logger not logging to self"
740 46 50       152 unless $self->{events};
741              
742 46         251 return $self->{events};
743             }
744              
745             #pod =head2 clear_events
746             #pod
747             #pod This method empties the current sequence of events logged into an array in
748             #pod memory. If the logger is not logging C<to_self> this raises an exception.
749             #pod
750             #pod =cut
751              
752 32     32 1 46706 sub clear_events ($self) {
  32         69  
  32         46  
753             Carp::confess "->events called on a logger not logging to self"
754 32 50       119 unless $self->{events};
755              
756 32         115 $self->{events}->@* = ();
757 32         68 return;
758             }
759              
760             #pod =head1 METHODS FOR PROXY LOGGERS
761             #pod
762             #pod =head2 proxy
763             #pod
764             #pod my $proxy_logger = $logger->proxy( \%arg );
765             #pod
766             #pod This method returns a new proxy logger -- an instance of
767             #pod L<Log::Dispatchouli::Proxy> -- which will log through the given logger, but
768             #pod which may have some settings localized.
769             #pod
770             #pod C<%arg> is optional. It may contain the following entries:
771             #pod
772             #pod =for :list
773             #pod = proxy_prefix
774             #pod This is a prefix that will be applied to anything the proxy logger logs, and
775             #pod cannot be changed.
776             #pod = proxy_ctx
777             #pod This is data to be inserted in front of event data logged through the proxy.
778             #pod It will appear I<after> the C<event> key but before the logged event data. It
779             #pod can be in the same format as the C<$data_ref> argument to C<log_event>.
780             #pod = debug
781             #pod This can be set to true or false to change the proxy's "am I in debug mode?"
782             #pod setting. It can be changed or cleared later on the proxy.
783             #pod
784             #pod =cut
785              
786 11     11 0 17 sub proxy_class ($) {
  11         16  
787 11         138 return 'Log::Dispatchouli::Proxy';
788             }
789              
790 11     11 1 128 sub proxy ($self, $arg = undef) {
  11         18  
  11         19  
  11         17  
791 11   50     30 $arg ||= {};
792              
793             my $proxy = $self->proxy_class->_new({
794             parent => $self,
795             logger => $self,
796             proxy_prefix => $arg->{proxy_prefix},
797 11 0       29 (exists $arg->{debug} ? (debug => ($arg->{debug} ? 1 : 0)) : ()),
    50          
798             });
799              
800 11 100       47 if (my $ctx = $arg->{proxy_ctx}) {
801             $proxy->{proxy_ctx} = _ARRAY0($ctx)
802             ? [ @$ctx ]
803 8 100       89 : [ $ctx->%{ sort keys %$ctx } ];
804             }
805              
806 11         38 return $proxy;
807             }
808              
809             #pod =head2 parent
810             #pod
811             #pod =head2 logger
812             #pod
813             #pod These methods return the logger itself. (They're more useful when called on
814             #pod proxy loggers.)
815             #pod
816             #pod =cut
817              
818 1     1 1 2 sub parent ($self) { $self }
  1         2  
  1         1  
  1         3  
819 1     1 1 440 sub logger ($self) { $self }
  1         2  
  1         1  
  1         6  
820              
821             #pod =method dispatcher
822             #pod
823             #pod This returns the underlying Log::Dispatch object. This is not the method
824             #pod you're looking for. Move along.
825             #pod
826             #pod =cut
827              
828 61     61 1 100 sub dispatcher ($self) { $self->{dispatcher} }
  61         99  
  61         80  
  61         456  
829              
830             #pod =method stdio_dispatcher_class
831             #pod
832             #pod This method is an experimental feature to allow you to pick an alternate
833             #pod dispatch class for stderr and stdio. By default, Log::Dispatch::Screen is
834             #pod used. B<This feature may go away at any time.>
835             #pod
836             #pod =cut
837              
838 0     0 1 0 sub stdio_dispatcher_class ($self) {
  0         0  
  0         0  
839 0         0 require Log::Dispatch::Screen;
840 0         0 return 'Log::Dispatch::Screen';
841             }
842              
843             #pod =head1 METHODS FOR API COMPATIBILITY
844             #pod
845             #pod To provide compatibility with some other loggers, most specifically
846             #pod L<Log::Contextual>, the following methods are provided. You should not use
847             #pod these methods without a good reason, and you should never subclass them.
848             #pod Instead, subclass the methods they call.
849             #pod
850             #pod =begin :list
851             #pod
852             #pod = is_debug
853             #pod
854             #pod This method calls C<get_debug>.
855             #pod
856             #pod = is_info
857             #pod
858             #pod = is_fatal
859             #pod
860             #pod These methods return true.
861             #pod
862             #pod = info
863             #pod
864             #pod = fatal
865             #pod
866             #pod = debug
867             #pod
868             #pod These methods redispatch to C<log>, C<log_fatal>, and C<log_debug>
869             #pod respectively.
870             #pod
871             #pod =end :list
872             #pod
873             #pod =cut
874              
875 11     11 1 35 sub is_debug ($self) { $self->get_debug }
  11         20  
  11         19  
  11         40  
876 0     0 1   sub is_info ($) { 1 }
  0            
  0            
877 0     0 1   sub is_fatal ($) { 1 }
  0            
  0            
878              
879 0     0 1   sub info ($self, @rest) { $self->log(@rest); }
  0            
  0            
  0            
  0            
880 0     0 1   sub fatal ($self, @rest) { $self->log_fatal(@rest); }
  0            
  0            
  0            
  0            
881 0     0 1   sub debug ($self, @rest) { $self->log_debug(@rest); }
  0            
  0            
  0            
  0            
882              
883             use overload
884 0     0   0 '&{}' => sub { my ($self) = @_; sub { $self->log(@_) } },
  0         0  
  0         0  
885 7         92 fallback => 1,
886 7     7   91 ;
  7         16  
887              
888             #pod =head1 SEE ALSO
889             #pod
890             #pod =for :list
891             #pod * L<Log::Dispatch>
892             #pod * L<String::Flogger>
893             #pod
894             #pod =cut
895              
896             1;
897              
898             __END__
899              
900             =pod
901              
902             =encoding UTF-8
903              
904             =head1 NAME
905              
906             Log::Dispatchouli - a simple wrapper around Log::Dispatch
907              
908             =head1 VERSION
909              
910             version 3.013
911              
912             =head1 SYNOPSIS
913              
914             my $logger = Log::Dispatchouli->new({
915             ident => 'stuff-purger',
916             facility => 'daemon',
917             to_stdout => $opt->{print},
918             debug => $opt->{verbose}
919             });
920              
921             $logger->log([ "There are %s items left to purge...", $stuff_left ]);
922              
923             $logger->log_debug("this is extra often-ignored debugging log");
924              
925             $logger->log_fatal("Now we will die!!");
926              
927             =head1 DESCRIPTION
928              
929             Log::Dispatchouli is a thin layer above L<Log::Dispatch> and meant to make it
930             dead simple to add logging to a program without having to think much about
931             categories, facilities, levels, or things like that. It is meant to make
932             logging just configurable enough that you can find the logs you want and just
933             easy enough that you will actually log things.
934              
935             Log::Dispatchouli can log to syslog (if you specify a facility), standard error
936             or standard output, to a file, or to an array in memory. That last one is
937             mostly useful for testing.
938              
939             In addition to providing as simple a way to get a handle for logging
940             operations, Log::Dispatchouli uses L<String::Flogger> to process the things to
941             be logged, meaning you can easily log data structures. Basically: strings are
942             logged as is, arrayrefs are taken as (sprintf format, args), and subroutines
943             are called only if needed. For more information read the L<String::Flogger>
944             docs.
945              
946             =head1 PERL VERSION
947              
948             This library should run on perls released even a long time ago. It should
949             work on any version of perl released in the last five years.
950              
951             Although it may work on older versions of perl, no guarantee is made that the
952             minimum required version will not be increased. The version may be increased
953             for any reason, and there is no promise that patches will be accepted to
954             lower the minimum required perl.
955              
956             =head1 METHODS
957              
958             =head2 new
959              
960             my $logger = Log::Dispatchouli->new(\%arg);
961              
962             This returns a new logger, a Log::Dispatchouli object.
963              
964             Valid arguments are:
965              
966             ident - the name of the thing logging (mandatory)
967             to_self - log to the logger object for testing; default: false
968             to_stdout - log to STDOUT; default: false
969             to_stderr - log to STDERR; default: false
970             facility - to which syslog facility to send logs; default: none
971              
972             to_file - DEPRECATED: this option will be removed in 2025
973             log to PROGRAM_NAME.YYYYMMDD in the log path; default: false
974             log_file - a leaf name for the file to log to with to_file
975             log_path - path in which to log to file; defaults to DISPATCHOULI_PATH
976             environment variable or, failing that, to your system's tmpdir
977              
978             file_format - this optional coderef is passed the message to be logged
979             and returns the text to write out
980              
981             log_pid - if 1, prefix all log entries with the pid; default: true
982             can also be a comma-delimited list of log targets where pid is
983             logged, like "stderr,syslog"; mostly useful for logging pid in
984             syslog, but not on standard I/O
985             fail_fatal - a boolean; if true, failure to log is fatal; default: true
986             muted - a boolean; if true, only fatals are logged; default: false
987             debug - a boolean; if true, log_debug method is not a no-op
988             defaults to the truth of the DISPATCHOULI_DEBUG env var
989             quiet_fatal - 'stderr' or 'stdout' or an arrayref of zero, one, or both
990             fatal log messages will not be logged to these
991             (default: stderr)
992             config_id - a name for this logger's config; rarely needed!
993             syslog_socket - a value for Sys::Syslog's "socket" arg; default: "native"
994              
995             The log path is either F</tmp> or the value of the F<DISPATCHOULI_PATH> env var.
996              
997             If the F<DISPATCHOULI_NOSYSLOG> env var is true, we don't log to syslog.
998              
999             =head2 enable_stdout
1000              
1001             =head2 enable_stderr
1002              
1003             These methods turn on logging to STDOUT or STDERR, respectively. If that
1004             logging has already been enabled, these methods do nothing.
1005              
1006             There is not, yet, a I<disable> version of these methods.
1007              
1008             =head2 log
1009              
1010             $logger->log(@messages);
1011              
1012             $logger->log(\%arg, @messages);
1013              
1014             This method uses L<String::Flogger> on the input, then I<unconditionally> logs
1015             the result. Each message is flogged individually, then joined with spaces.
1016              
1017             If the first argument is a hashref, it will be used as extra arguments to
1018             logging. It may include a C<prefix> entry to preprocess the message by
1019             prepending a string (if the prefix is a string) or calling a subroutine to
1020             generate a new message (if the prefix is a coderef).
1021              
1022             =head2 log_fatal
1023              
1024             This behaves like the C<log> method, but will throw the logged string as an
1025             exception after logging.
1026              
1027             This method can also be called as C<fatal>, to match other popular logging
1028             interfaces. B<If you want to override this method, you must override
1029             C<log_fatal> and not C<fatal>>.
1030              
1031             =head2 log_debug
1032              
1033             This behaves like the C<log> method, but will only log (at the debug level) if
1034             the logger object has its debug property set to true.
1035              
1036             This method can also be called as C<debug>, to match other popular logging
1037             interfaces. B<If you want to override this method, you must override
1038             C<log_debug> and not C<debug>>.
1039              
1040             =head2 log_event
1041              
1042             This method is like C<log>, but is used for structured logging instead of free
1043             form text. It's invoked like this:
1044              
1045             $logger->log($event_type => $data_ref);
1046              
1047             C<$event_type> should be a simple string, probably a valid identifier, that
1048             identifies the kind of event being logged. It is suggested, but not required,
1049             that all events of the same type have the same kind of structured data in them.
1050              
1051             C<$data_ref> is a set of key/value pairs of data to log in this event. It can
1052             be an arrayref (in which case the ordering of pairs is preserved) or a hashref
1053             (in which case they are sorted by key).
1054              
1055             The logged string will be in logfmt format, meaning a series of key=value
1056             pairs separated by spaces and following these rules:
1057              
1058             =over 4
1059              
1060             =item *
1061              
1062             an "identifier" is a string of printable ASCII characters between C<!> and C<~>, excluding C<\> and C<=>
1063              
1064             =item *
1065              
1066             keys must be valid identifiers
1067              
1068             =item *
1069              
1070             if a key is empty, C<~> is used instead
1071              
1072             =item *
1073              
1074             if a key contains characters not permitted in an identifier, they are replaced by C<?>
1075              
1076             =item *
1077              
1078             values must I<either> be valid identifiers, or be quoted
1079              
1080             =item *
1081              
1082             quoted value start and end with C<">
1083              
1084             =item *
1085              
1086             in a quoted value, C<"> becomes C<\">, C<\> becomes C<\\>, newline and carriage return become C<\n> and C<\r> respectively, and other control characters are replaced with C<\u{....}> where the contents of the braces are the hex value of the control character
1087              
1088             =back
1089              
1090             When values are undef, they are represented as C<~>.
1091              
1092             When values are array references, the index/values are mapped over, so that:
1093              
1094             key => [ 'a', 'b' ]
1095              
1096             becomes
1097              
1098             key.0=a key.1=b
1099              
1100             When values are hash references, the key/values are mapped, with keys sorted,
1101             so that:
1102              
1103             key => { b => 2, a => 1 }
1104              
1105             becomes
1106              
1107             key.a=1 key.b=2
1108              
1109             This expansion is performed recursively. If a value itself recurses,
1110             appearances of a reference after the first time will be replaced with a string
1111             like C<&foo.bar>, pointing to the first occurrence. I<This is not meant to be
1112             a robust serialization mechanism.> It's just here to help you be a little
1113             lazy. Don't push the limits.
1114              
1115             If the value in C<$data_ref> is a code reference, it will be called and its
1116             result logged. If its result is also a code reference, you get whatever
1117             garbage that code reference stringifies to.
1118              
1119             If the value in C<$data_ref> is a reference reference, then the referenced
1120             scalar will be passed to String::Flogger, and the resulting string will be used
1121             as the value to log. That string will be quoted as described above, if needed.
1122              
1123             =head2 log_debug_event
1124              
1125             This method is just like C<log_event>, but will log nothing unless the logger
1126             has its C<debug> property set to true.
1127              
1128             =head2 set_debug
1129              
1130             $logger->set_debug($bool);
1131              
1132             This sets the logger's debug property, which affects the behavior of
1133             C<log_debug>.
1134              
1135             =head2 get_debug
1136              
1137             This gets the logger's debug property, which affects the behavior of
1138             C<log_debug>.
1139              
1140             =head2 clear_debug
1141              
1142             This method does nothing, and is only useful for L<Log::Dispatchouli::Proxy>
1143             objects. See L<Methods for Proxy Loggers|/METHODS FOR PROXY LOGGERS>, below.
1144              
1145             =head2 set_muted
1146              
1147             $logger->set_muted($bool);
1148              
1149             This sets the logger's muted property, which affects the behavior of
1150             C<log>.
1151              
1152             =head2 get_muted
1153              
1154             This gets the logger's muted property, which affects the behavior of
1155             C<log>.
1156              
1157             =head2 clear_muted
1158              
1159             This method does nothing, and is only useful for L<Log::Dispatchouli::Proxy>
1160             objects. See L<Methods for Proxy Loggers|/METHODS FOR PROXY LOGGERS>, below.
1161              
1162             =head2 get_prefix
1163              
1164             my $prefix = $logger->get_prefix;
1165              
1166             This method returns the currently-set prefix for the logger, which may be a
1167             string or code reference or undef. See L<Logger Prefix|/LOGGER PREFIX>.
1168              
1169             =head2 set_prefix
1170              
1171             $logger->set_prefix( $new_prefix );
1172              
1173             This method changes the prefix. See L<Logger Prefix|/LOGGER PREFIX>.
1174              
1175             =head2 clear_prefix
1176              
1177             This method clears any set logger prefix. (It can also be called as
1178             C<unset_prefix>, but this is deprecated. See L<Logger Prefix|/LOGGER PREFIX>.
1179              
1180             =head2 ident
1181              
1182             This method returns the logger's ident.
1183              
1184             =head2 config_id
1185              
1186             This method returns the logger's configuration id, which defaults to its ident.
1187             This can be used to make two loggers equivalent in Log::Dispatchouli::Global so
1188             that trying to reinitialize with a new logger with the same C<config_id> as the
1189             current logger will not throw an exception, and will simply do no thing.
1190              
1191             =head2 flog_messages
1192              
1193             my $str = $logger->flog_messages($m1, $m2, ...);
1194              
1195             This returns the string that would have been logged if the given arguments had
1196             been passed to C<< $logger->log(...) >>, without regard for log level,
1197             debugging, or the like.
1198              
1199             Unlike using the logger's string flogger, this will include any relevant prefix
1200             strings.
1201              
1202             =head2 fmt_event
1203              
1204             my $str = $logger->fmt_event($event_type => $data_ref);
1205              
1206             This method is equivalent to C<flog_messages>, but for an event. It returns
1207             the string format of the event, including all relevant prefixes.
1208              
1209             =head2 dispatcher
1210              
1211             This returns the underlying Log::Dispatch object. This is not the method
1212             you're looking for. Move along.
1213              
1214             =head2 stdio_dispatcher_class
1215              
1216             This method is an experimental feature to allow you to pick an alternate
1217             dispatch class for stderr and stdio. By default, Log::Dispatch::Screen is
1218             used. B<This feature may go away at any time.>
1219              
1220             =head1 LOGGER PREFIX
1221              
1222             Log messages may be prepended with information to set context. This can be set
1223             at a logger level or per log item. The simplest example is:
1224              
1225             my $logger = Log::Dispatchouli->new( ... );
1226              
1227             $logger->set_prefix("Batch 123: ");
1228              
1229             $logger->log("begun processing");
1230              
1231             # ...
1232              
1233             $logger->log("finished processing");
1234              
1235             The above will log something like:
1236              
1237             Batch 123: begun processing
1238             Batch 123: finished processing
1239              
1240             To pass a prefix per-message:
1241              
1242             $logger->log({ prefix => 'Sub-Item 234: ' }, 'error!')
1243              
1244             # Logs: Batch 123: Sub-Item 234: error!
1245              
1246             If the prefix is a string, it is prepended to each line of the message. If it
1247             is a coderef, it is called and passed the message to be logged. The return
1248             value is logged instead.
1249              
1250             L<Proxy loggers|/METHODS FOR PROXY LOGGERS> also have their own prefix
1251             settings, which accumulate. So:
1252              
1253             my $proxy = $logger->proxy({ proxy_prefix => 'Subsystem 12: ' });
1254              
1255             $proxy->set_prefix('Page 9: ');
1256              
1257             $proxy->log({ prefix => 'Paragraph 6: ' }, 'Done.');
1258              
1259             ...will log...
1260              
1261             Batch 123: Subsystem 12: Page 9: Paragraph 6: Done.
1262              
1263             =head1 METHODS FOR SUBCLASSING
1264              
1265             =head2 string_flogger
1266              
1267             This method returns the thing on which F<flog> will be called to format log
1268             messages. By default, it just returns C<String::Flogger>
1269              
1270             =head2 env_prefix
1271              
1272             This method should return a string used as a prefix to find environment
1273             variables that affect the logger's behavior. For example, if this method
1274             returns C<XYZZY> then when checking the environment for a default value for the
1275             C<debug> parameter, Log::Dispatchouli will first check C<XYZZY_DEBUG>, then
1276             C<DISPATCHOULI_DEBUG>.
1277              
1278             By default, this method returns C<()>, which means no extra environment
1279             variable is checked.
1280              
1281             =head2 env_value
1282              
1283             my $value = $logger->env_value('DEBUG');
1284              
1285             This method returns the value for the environment variable suffix given. For
1286             example, the example given, calling with C<DEBUG> will check
1287             C<DISPATCHOULI_DEBUG>.
1288              
1289             =head1 METHODS FOR TESTING
1290              
1291             =head2 new_tester
1292              
1293             my $logger = Log::Dispatchouli->new_tester( \%arg );
1294              
1295             This returns a new logger that logs only C<to_self>. It's useful in testing.
1296             If no C<ident> arg is provided, one will be generated. C<log_pid> is off by
1297             default, but can be overridden.
1298              
1299             C<\%arg> is optional.
1300              
1301             =head2 events
1302              
1303             This method returns the arrayref of events logged to an array in memory (in the
1304             logger). If the logger is not logging C<to_self> this raises an exception.
1305              
1306             =head2 clear_events
1307              
1308             This method empties the current sequence of events logged into an array in
1309             memory. If the logger is not logging C<to_self> this raises an exception.
1310              
1311             =head1 METHODS FOR PROXY LOGGERS
1312              
1313             =head2 proxy
1314              
1315             my $proxy_logger = $logger->proxy( \%arg );
1316              
1317             This method returns a new proxy logger -- an instance of
1318             L<Log::Dispatchouli::Proxy> -- which will log through the given logger, but
1319             which may have some settings localized.
1320              
1321             C<%arg> is optional. It may contain the following entries:
1322              
1323             =over 4
1324              
1325             =item proxy_prefix
1326              
1327             This is a prefix that will be applied to anything the proxy logger logs, and
1328             cannot be changed.
1329              
1330             =item proxy_ctx
1331              
1332             This is data to be inserted in front of event data logged through the proxy.
1333             It will appear I<after> the C<event> key but before the logged event data. It
1334             can be in the same format as the C<$data_ref> argument to C<log_event>.
1335              
1336             =item debug
1337              
1338             This can be set to true or false to change the proxy's "am I in debug mode?"
1339             setting. It can be changed or cleared later on the proxy.
1340              
1341             =back
1342              
1343             =head2 parent
1344              
1345             =head2 logger
1346              
1347             These methods return the logger itself. (They're more useful when called on
1348             proxy loggers.)
1349              
1350             =head1 METHODS FOR API COMPATIBILITY
1351              
1352             To provide compatibility with some other loggers, most specifically
1353             L<Log::Contextual>, the following methods are provided. You should not use
1354             these methods without a good reason, and you should never subclass them.
1355             Instead, subclass the methods they call.
1356              
1357             =over 4
1358              
1359             =item is_debug
1360              
1361             This method calls C<get_debug>.
1362              
1363             =item is_info
1364              
1365             =item is_fatal
1366              
1367             These methods return true.
1368              
1369             =item info
1370              
1371             =item fatal
1372              
1373             =item debug
1374              
1375             These methods redispatch to C<log>, C<log_fatal>, and C<log_debug>
1376             respectively.
1377              
1378             =back
1379              
1380             =head1 SEE ALSO
1381              
1382             =over 4
1383              
1384             =item *
1385              
1386             L<Log::Dispatch>
1387              
1388             =item *
1389              
1390             L<String::Flogger>
1391              
1392             =back
1393              
1394             =head1 AUTHOR
1395              
1396             Ricardo SIGNES <cpan@semiotic.systems>
1397              
1398             =head1 CONTRIBUTORS
1399              
1400             =for stopwords Charlie Garrison Christopher J. Madsen Dagfinn Ilmari Mannsåker Dan Book George Hartzell Jon Stuart Matt Phillips Olivier Mengué Randy Stauner Ricardo Signes Sawyer X
1401              
1402             =over 4
1403              
1404             =item *
1405              
1406             Charlie Garrison <cng@garrison.com.au>
1407              
1408             =item *
1409              
1410             Christopher J. Madsen <perl@cjmweb.net>
1411              
1412             =item *
1413              
1414             Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
1415              
1416             =item *
1417              
1418             Dan Book <grinnz@gmail.com>
1419              
1420             =item *
1421              
1422             George Hartzell <hartzell@alerce.com>
1423              
1424             =item *
1425              
1426             Jon Stuart <jon@fastmailteam.com>
1427              
1428             =item *
1429              
1430             Matt Phillips <mattp@cpan.org>
1431              
1432             =item *
1433              
1434             Olivier Mengué <dolmen@cpan.org>
1435              
1436             =item *
1437              
1438             Randy Stauner <randy@magnificent-tears.com>
1439              
1440             =item *
1441              
1442             Ricardo Signes <rjbs@semiotic.systems>
1443              
1444             =item *
1445              
1446             Sawyer X <xsawyerx@cpan.org>
1447              
1448             =back
1449              
1450             =head1 COPYRIGHT AND LICENSE
1451              
1452             This software is copyright (c) 2025 by Ricardo SIGNES.
1453              
1454             This is free software; you can redistribute it and/or modify it under
1455             the same terms as the Perl 5 programming language system itself.
1456              
1457             =cut