File Coverage

blib/lib/Log/Dispatchouli.pm
Criterion Covered Total %
statement 265 339 78.1
branch 59 106 55.6
condition 15 25 60.0
subroutine 50 67 74.6
pod 34 40 85.0
total 423 577 73.3


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