1Log::Report(3) User Contributed Perl Documentation Log::Report(3)
2
3
4
6 Log::Report - report a problem, with exceptions and translation support
7
9 Log::Report
10 is an Exporter
11
13 # Invocation with 'mode' to get trace and verbose messages
14 use Log::Report mode => 'DEBUG';
15
16 # Usually invoked with a domain, which groups packages for translation
17 use Log::Report 'my-domain', %options;
18
19 # Interpolation syntax via String::Print
20 # First step to translations, once you need it.
21 print __x"my name is {name}", name => $n; # print, so no exception
22 print __"Hello World\n"; # no interpolation, optional translation
23 print __x'Hello World'; # SYNTAX ERROR!! ' is alternative for ::
24
25 # Functions replacing die/warn/carp, casting exceptions.
26 error "oops"; # exception like die(), no translation
27 -f $config or panic "Help!"; # alert/error/fault/info/...more
28
29 # Combined exception, interpolation, and optional translation
30 error __x"Help!"; # __x() creates ::Message object
31 error __x('gettext msgid', param => $value, ...)
32 if $condition;
33
34 # Also non fatal "exceptions" find their way to dispatchers
35 info __x"started {pid}", pid => $$; # translatable
36 debug "$i was here!"; # you probably do not want to translate debug
37 panic "arrghhh"; # like Carp::Confess
38
39 # Many destinations for an exception message (may exist in parallel)
40 dispatcher PERL => 'default' # see Log::Report::Dispatcher: use die/warn
41 , reasons => 'NOTICE-'; # this dispatcher is already present at start
42
43 dispatcher SYSLOG => 'syslog'# also send to syslog
44 , charset => 'iso-8859-1' # explicit character conversions
45 , locale => 'en_US'; # overrule user's locale
46
47 dispatcher close => 'default'; # stop default die/warn dispatcher
48
49 # Fill-in values, like Locale::TextDomain and gettext
50 # See Log::Report::Message section DETAILS
51 fault __x"cannot allocate {size} bytes", size => $size;
52 fault "cannot allocate $size bytes"; # no translation, ok
53 fault __x"cannot allocate $size bytes"; # not translatable, wrong
54
55 # Translation depending on count
56 # Leading and trailing whitespace stay magically outside translation
57 # tables. @files in scalar context. Special parameter with _
58 print __xn"found one file\n", "found {_count} files", @files;
59
60 # Borrow from an other text-domain (see Log::Report::Message)
61 print __x(+"errors in {line}", _domain => 'global', line => $line);
62
63 # catch errors (implements hidden eval/die)
64 try { error };
65 if($@) {...} # $@ isa Log::Report::Dispatcher::Try
66 if(my $exception = $@->wasFatal) # ::Exception object
67
68 # Language translations at the output component
69 # Translation management via Log::Report::Lexicon
70 use POSIX::1003::Locale qw/setlocale LC_ALL/;
71 setlocale(LC_ALL, 'nl_NL');
72 info __"Hello World!"; # in Dutch, if translation table found
73
74 # Exception classes, see Log::Report::Exception
75 try { error __x"something", _class => 'parsing,schema' };
76 if($@->wasFatal->inClass('parsing')) ...
77
79 Get messages to users and logs. "Log::Report" combines three tasks
80 which are closely related in one:
81
82 . logging (like Log::Log4Perl and syslog), and
83 . exceptions (like error and info), with
84 . translations (like "gettext" and Locale::TextDomain)
85
86 You do not need to use this module for all three reasons: pick what you
87 need now, maybe extend the usage later. Read more about how and why in
88 the "DETAILS" section, below. Especially, you should read about the
89 REASON parameter.
90
91 Also, you can study this module swiftly via the article published in
92 the German Perl "$foo-magazine". English version:
93 http://perl.overmeer.net/log-report/papers/201306-PerlMagazine-article-en.html
94
96 Report Production and Configuration
97 dispatcher( <$type, $name, %options>|<$command, @names> )
98 The "dispatcher" function controls access to dispatchers: the back-
99 ends which process messages, do the logging. Dispatchers are
100 global entities, addressed by a symbolic $name. Please read
101 Log::Report::Dispatcher as well.
102
103 The "Log::Report" suite has its own dispatcher @types, but also
104 connects to external dispatching frameworks. Each need some
105 (minor) conversions, especially with respect to translation of
106 REASONS of the reports into log-levels as the back-end understands.
107
108 [1.10] When you open a dispatcher with a $name which is already in
109 use, that existing dispatcher gets closed. Except when you have
110 given an 'dispatcher "do-not-reopen"' earlier, in which case the
111 first object stays alive, and the second attempt ignored. [1.11]
112 The automatically created default dispatcher will get replaced,
113 even when this option is given, by another dispatcher which is
114 named 'default'.
115
116 The %options are a mixture of parameters needed for the Log::Report
117 dispatcher wrapper and the settings of the back-end. See
118 Log::Report::Dispatcher, the documentation for the back-end
119 specific wrappers, and the back-ends for more details.
120
121 Implemented COMMANDs are "close", "find", "list", "disable",
122 "enable", "mode", "filter", "needs", "active-try", and
123 "do-not-reopen".
124
125 Most commands are followed by a LIST of dispatcher @names to be
126 addressed. For "mode" see section "Run modes"; it requires a MODE
127 argument before the LIST of NAMEs. Non-existing names will be
128 ignored. When "ALL" is specified, then all existing dispatchers
129 will get addressed. For "filter" see "Filters" in
130 Log::Report::Dispatcher; it requires a CODE reference before the
131 @names of the dispatchers which will have the it applied (defaults
132 to all).
133
134 With "needs", you only provide a REASON: it will return the list of
135 dispatchers which need to be called in case of a message with the
136 REASON is triggered. The "active-try" [1.09] returns the closest
137 surrounding exception catcher, a Log::Report::Dispatcher::Try
138 object.
139
140 For both the creation as COMMANDs version of this method, all
141 objects involved are returned as LIST, non-existing ones skipped.
142 In SCALAR context with only one name, the one object is returned.
143
144 example: play with dispatchers
145
146 dispatcher Log::Dispatcher::File => mylog =>
147 , accept => 'MISTAKE-' # for wrapper
148 , locale => 'pt_BR' # other language
149 , filename => 'logfile'; # for back-end
150
151 dispatcher close => 'mylog'; # cleanup
152 my $obj = dispatcher find => 'mylog';
153 my @obj = dispatcher 'list';
154 dispatcher disable => 'syslog';
155 dispatcher enable => 'mylog', 'syslog'; # more at a time
156 dispatcher mode => 'DEBUG', 'mylog';
157 dispatcher mode => 'DEBUG', 'ALL';
158 my $catcher = dispatcher 'active-try';
159 dispatcher 'do-not-reopen';
160
161 my @need_info = dispatcher needs => 'INFO';
162 if(dispatcher needs => 'INFO') ... # anyone needs INFO
163
164 # Getopt::Long integration: see Log::Report::Dispatcher::mode()
165 dispatcher PERL => 'default', mode => 'DEBUG', accept => 'ALL'
166 if $debug;
167
168 report( [%options], $reason, $message|<STRING,$params>, )
169 The "report" function is sending (for some $reason) a $message to
170 be displayed or logged (by a `dispatcher'). This function is the
171 core for error(), info() etc functions, which are nicer names for
172 this exception throwing: better use those short names.
173
174 The $reason is a string like 'ERROR' (for function error()). The
175 $message is a Log::Report::Message object (which are created with
176 the special translation syntax like __x()). The $message may also
177 be a plain string, or an Log::Report::Exception object. The
178 optional first parameter is a HASH which can be used to influence
179 the dispatchers.
180
181 The optional %options are listed below. Quite differently from
182 other functions and methods, they have to be passed in a HASH as
183 first parameter.
184
185 This function returns the LIST of dispatchers which accepted the
186 $message. When empty, no back-end has accepted it so the $message
187 was "lost". Even when no back-end needs the message, the program
188 will still exit when there is a $reason to die().
189
190 -Option --Default
191 errno $! or 1
192 is_fatal <depends on reason>
193 locale undef
194 location undef
195 stack undef
196 to undef
197
198 errno => INTEGER
199 When the $reason includes the error text (See "Run modes"), you
200 can overrule the error code kept in $!. In other cases, the
201 return code defaults to 1 (historical UNIX behavior). When the
202 message $reason (combined with the run-mode) is severe enough to
203 stop the program, this value as return code of the program. The
204 use of this option itself will not trigger an die().
205
206 is_fatal => BOOLEAN
207 Some logged exceptions are fatal, other aren't. The default
208 usually is correct. However, you may want an error to be caught
209 (usually with try()), redispatch it to syslog, but without it
210 killing the main program.
211
212 locale => LOCALE
213 Use this specific locale, in stead of the user's preference.
214
215 location => STRING
216 When defined, this location is used in the display. Otherwise,
217 it is determined automatically if needed. An empty string will
218 disable any attempt to display this line.
219
220 stack => ARRAY
221 When defined, that data is used to display the call stack.
222 Otherwise, it is collected via caller() if needed.
223
224 to => NAME|ARRAY-of-NAMEs
225 Sent the $message only to the NAMEd dispatchers. Ignore unknown
226 NAMEs. Still, the dispatcher needs to be enabled and accept the
227 REASONs.
228
229 example: for use of report()
230
231 # long syntax example
232 report TRACE => "start processing now";
233 report INFO => '500: ' . __'Internal Server Error';
234
235 # explicit dispatcher, no translation
236 report {to => 'syslog'}, NOTICE => "started process $$";
237 notice "started process $$", _to => 'syslog'; # same
238
239 # short syntax examples
240 trace "start processing now";
241 warning __x'Disk {percent%.2f}% full', percent => $p
242 if $p > 97;
243
244 # error message, overruled to be printed in Brazilian
245 report {locale => 'pt_BR'}
246 , WARNING => "do this at home!";
247
248 try(CODE, %options)
249 Execute the CODE while blocking all dispatchers as long as it is
250 running. The exceptions which occur while running the CODE are
251 caught until it has finished. When there where no fatal errors,
252 the result of the CODE execution is returned.
253
254 After the CODE was tried, the $@ will contain a
255 Log::Report::Dispatcher::Try object, which contains the collected
256 messages. Read that manual page to understand "try".
257
258 Run-time errors from Perl and die's, croak's and confess's within
259 the program (which shouldn't appear, but you never know) are
260 collected into an Log::Report::Message object, using
261 Log::Report::Die.
262
263 The %options are passed to the constructor of the try-dispatcher,
264 see Log::Report::Dispatcher::Try::new(). For instance, you may
265 like to add "mode => 'DEBUG'", or "accept => 'ERROR-'".
266
267 Be warned that the parameter to "try" is a CODE reference. This
268 means that you shall not use a comma after the block when there are
269 %options specified. On the other hand, you shall use a semi-colon
270 after the block if there are no arguments.
271
272 Be warned that the {} are interpreted as subroutine, which means
273 that, for instance, it has its own @_. The manual-page of
274 Try::Tiny lists a few more side-effects of this.
275
276 example:
277
278 my $x = try { 3/$x }; # mind the ';' !!
279 if($@) { # signals something went wrong
280
281 if(try {...}) { # block ended normally, returns bool
282
283 try { ... } # no comma!!
284 mode => 'DEBUG', accept => 'ERROR-';
285
286 try sub { ... }, # with comma, also \&function
287 mode => 'DEBUG', accept => 'ALL';
288
289 my $response = try { $ua->request($request) };
290 if(my $e = $@->wasFatal) ...
291
292 Abbreviations for report()
293 The following functions are all wrappers for calls to report(), and
294 available when "syntax is SHORT" (by default, see import()). You
295 cannot specify additional options to influence the behavior of
296 report(), which are usually not needed anyway.
297
298 alert($message)
299 Short for "report ALERT => $message"
300
301 assert($message)
302 Short for "report ASSERT => $message"
303
304 error($message)
305 Short for "report ERROR => $message"
306
307 failure($message)
308 Short for "report FAILURE => $message"
309
310 fault($message)
311 Short for "report FAULT => $message"
312
313 info($message)
314 Short for "report INFO => $message"
315
316 mistake($message)
317 Short for "report MISTAKE => $message"
318
319 notice($message)
320 Short for "report NOTICE => $message"
321
322 panic($message)
323 Short for "report PANIC => $message"
324
325 trace($message)
326 Short for "report TRACE => $message"
327
328 warning($message)
329 Short for "report WARNING => $message"
330
331 Messages (optionally translatable)
332 Even when you do not support translations (yet) you may want to use
333 message objects to improve the logging feature. For instance, you get
334 very powerful interpolation from String::Print.
335
336 The language translations are initiate by limited set of functions
337 which contain two under-scores ("__") in their name. Most of them
338 return a Log::Report::Message object.
339
340 Be warned(1) that -in general- its considered very bad practice to
341 combine multiple translations into one message: translating may also
342 affect the order of the translated components. Besides, when the person
343 which translates only sees smaller parts of the text, his (or her) job
344 becomes more complex. So:
345
346 print __"Hello" . ', ' . __"World!"; # works, but to be avoided
347 print __"Hello, World!"; # preferred, complete sentence
348
349 The the former case, tricks with overloading used by the
350 Log::Report::Message objects will still make delayed translations work.
351
352 In normal situations, it is not a problem to translate interpolated
353 values:
354
355 print __"the color is {c}", c => __"red";
356
357 Be warned(2) that using "__'Hello'" will produce a syntax error like
358 "String found where operator expected at .... Can't find string
359 terminator "'" anywhere before EOF". The first quote is the cause of
360 the complaint, but the second generates the error. In the early days
361 of Perl, the single quote was used to separate package name from
362 function name, a role which was later replaced by a double-colon. So
363 "__'Hello'" gets interpreted as "__::Hello '". Then, there is a
364 trailing single quote which has no counterpart.
365
366 N__($msgid)
367 Label to indicate that the string is a text which will be
368 translated later. The function itself does nothing. See also
369 N__w().
370
371 This no-op function is used as label to the xgettext program to
372 build the translation tables.
373
374 example: how to use N__()
375
376 # add three msgids to the translation table
377 my @colors = (N__"red", N__"green", N__"blue");
378 my @colors = N__w "red green blue"; # same
379 print __ $colors[1]; # translate green
380
381 # using __(), would work as well
382 my @colors = (__"red", __"green", __"blue");
383 print $colors[1];
384 # however: this will always create all Log::Report::Message objects,
385 # where maybe only one is used.
386
387 N__n($single_msgid, $plural_msgid)
388 Label to indicate that the two MSGIDs are related, the first as
389 single, the seconds as its plural. Only used to find the text
390 fragments to be translated. The function itself does nothing.
391
392 example: how to use N__n()
393
394 my @save = N__n "save file", "save files";
395 my @save = (N__n "save file", "save files");
396 my @save = N__n("save file", "save files");
397
398 # be warned about SCALARs in prototype!
399 print __n @save, $nr_files; # wrong!
400 print __n $save[0], $save[1], @files, %vars;
401
402 N__w(STRING)
403 This extension to the Locale::TextDomain syntax, is a combined "qw"
404 (list of quoted words) and N__() into a list of translatable words.
405
406 example: of N__w()
407
408 my @colors = (N__"red", N__"green", N__"blue");
409 my @colors = N__w"red green blue"; # same
410 print __ $colors[1];
411
412 __($msgid)
413 This function (name is two under-score characters) will cause the
414 $msgid to be replaced by the translations when doing the actual
415 output. Returned is a Log::Report::Message object, which will be
416 used in translation later. Translating is invoked when the object
417 gets stringified. When you have no translation tables, the $msgid
418 will be shown untranslated.
419
420 If you need options for Log::Report::Message::new() then use __x();
421 the prototype of this function does not permit parameters: it is a
422 prefix operator!
423
424 example: how to use __()
425
426 print __"Hello World"; # translated into user's language
427 print __'Hello World'; # syntax error!
428 print __('Hello World'); # ok, translated
429 print __"Hello", " World"; # World not translated
430
431 my $s = __"Hello World"; # creates object, not yet translated
432 print ref $s; # Log::Report::Message
433 print $s; # ok, translated
434 print $s->toString('fr'); # ok, forced into French
435
436 __n($msgid, $plural_msgid, $count, PAIRS)
437 It depends on the value of $count (and the selected language) which
438 text will be displayed. When translations can not be performed,
439 then $msgid will be used when $count is 1, and PLURAL_MSGSID in
440 other cases. However, some languages have more complex schemes
441 than English.
442
443 The PAIRS are options for Log::Report::Message::new() and variables
444 to be filled in.
445
446 example: how to use __n()
447
448 print __n "one", "more", $a;
449 print __n("one", "more", $a), "\n";
450 print +(__n "one", "more", $a), "\n";
451
452 # new-lines are ignore at lookup, but printed.
453 print __n "one\n", "more\n", $a;
454
455 # count is in scalar context
456 # the value is also available as _count
457 print __n "found one\n", "found {_count}\n", @r;
458
459 # ARRAYs and HASHes are counted
460 print __n "one", "more", \@r;
461
462 __nx($msgid, $plural_msgid, $count, PAIRS)
463 It depends on the value of $count (and the selected language) which
464 text will be displayed. See details in __n(). After translation,
465 the VARIABLES will be filled-in.
466
467 The PAIRS are options for Log::Report::Message::new() and variables
468 to be filled in.
469
470 example: how to use __nx()
471
472 print __nx "one file", "{_count} files", $nr_files;
473 print __nx "one file", "{_count} files", @files;
474
475 local $" = ', ';
476 print __nx "one file: {f}", "{_count} files: {f}", @files, f => \@files;
477
478 __x($msgid, PAIRS)
479 Translate the $msgid and then interpolate the VARIABLES in that
480 string. Of course, translation and interpolation is delayed as
481 long as possible. Both OPTIONS and VARIABLES are key-value pairs.
482
483 The PAIRS are options for Log::Report::Message::new() and variables
484 to be filled in.
485
486 __xn($single_msgid, $plural_msgid, $count, $paurs)
487 Same as __nx(), because we have no preferred order for 'x' and 'n'.
488
489 Messages with msgctxt
490
491 In Log::Report, the message context (mgsctxt in the PO-files --in the
492 translation tables) can be used in a very powerful way. Read all about
493 it in Log::Report::Translator::Context
494
495 The msgctxt versions of the tranditional gettext infrastructure are far
496 less useful for Log::Report, because we can easily work with different
497 text domains within the same program. That should avoid most of the
498 accidental translation conflicts between components of the code.
499
500 Just for compatibility with Locale::TextDomain and completeness, the
501 'p' versions of above methods are supported. See examples for these
502 functions in Locale::TextDomain.
503
504 Warnings: Functions "N__p()" and "N__np()" seem not to be usable in
505 reality, hence not implemented. The script xgettext-perl and
506 Log::Report::Extract::PerlPPI (both in the Log::Report::Lexicon
507 distribution) do not yet support these functions.
508
509 __np($msgctxt, $msgid, $plural, count)
510 __npx($msgctxt, $msgid, $plural, count, PAIRS)
511 __p($msgctxt, $msgid)
512 __px($msgctxt, $msgid, PAIRS)
513
514 Configuration
515 $obj->import( [$level,][$domain,] %options )
516 The import is automatically called when the package is compiled.
517 For all packages but one in your distribution, it will only contain
518 the name of the $domain.
519
520 For one package, the import list may additionally contain
521 textdomain configuration %options. These %options are used for all
522 packages which use the same $domain. These are alternatives:
523
524 # Do not use variables in the %*config! They are not yet initialized
525 # when Log::Report->import is run!!!
526 use Log::Report 'my-domain', %config, %domain_config;
527
528 use Log::Report 'my-domain', %config;
529 textdomain 'my-domain', %domain_config; # vars allowed
530
531 The latter syntax has major advantages, when the configuration of
532 the domain is determined at run-time. It is probably also easier
533 to understand.
534
535 See Log::Report::Domain::configure(), for the list of %options for
536 the domain configuration. Here, we only list the options which are
537 related to the normal import behavior.
538
539 The export $level is a plus (+) followed by a number, for instance
540 +1, to indicate to on which caller level we need to work. This is
541 used in Log::Report::Optional. It defaults to '0': my direct
542 caller.
543
544 -Option --Default
545 import undef
546 message_class Log::Report::Message
547 mode 'NORMAL'
548 syntax 'SHORT'
549
550 import => FUNCTION|ARRAY
551 [0.998] When not specified, the "syntax" option determines the
552 list of functions which are being exported. With this option,
553 the "syntax" option is ignored and only the specified FUNCTION(s)
554 are imported.
555
556 message_class => CLASS
557 [1.08] Use a more powerful message object class, for instance
558 because your messages need extra attributes. The provided CLASS
559 must extend Log::Report::Message
560
561 mode => LEVEL
562 This sets the default mode for all created dispatchers. You can
563 also selectively change the output mode, like
564 dispatcher PERL => 'default', mode => 3
565
566 syntax => 'REPORT'|'SHORT'|'LONG'
567 The SHORT syntax will add the report abbreviations (like function
568 error()) to your name-space. Otherwise, each message must be
569 produced with report(). "LONG" is an alternative to "REPORT":
570 both do not pollute your namespace with the useful abbrev
571 functions.
572
573 example: of import
574
575 use Log::Report mode => 3; # '3' or 'DEBUG'
576
577 use Log::Report 'my-domain'; # in each package producing messages
578
579 use Log::Report 'my-domain' # in one package, top of distr
580 , mode => 'VERBOSE'
581 , syntax => 'REPORT' # report ERROR, not error()
582 , translator => Log::Report::Translator::POT->new
583 ( lexicon => '/home/mine/locale' # translation tables
584 )
585 , native_language => 'nl_NL'; # untranslated msgs are Dutch
586
587 use Log::Report import => 'try'; # or ARRAY of functions
588
589 textdomain( <[$name],$config>|<$name, 'DELETE'|'EXISTS'>|$domain )
590 [1.00] Without CONFIGuration, this returns the Log::Report::Domain
591 object which administers the $domain, by default the domain
592 effective in the scope of the package.
593
594 A very special case is "DELETE", which will remove the domain
595 configuration. [1.20] "EXISTS" will check for existence: when it
596 exists, it will be returned, but a domain will not be automagically
597 created.
598
599 [1.20] You may also pass a pre-configured domain.
600
601 Reasons
602 Log::Report->needs( $reason, [$reasons] )
603 Returns true when the reporter needs any of the $reasons, when any
604 of the active dispatchers is collecting messages in the specified
605 level. This is useful when the processing of data for the message
606 is relatively expensive, but for instance only required in debug
607 mode.
608
609 example:
610
611 if(Log::Report->needs('TRACE'))
612 { my @args = ...expensive calculation...;
613 trace "your options are: @args";
614 }
615
617 Introduction
618 Getting messages to users and logs. The distincting concept of this
619 module, is that three tasks which are strongly related are merged into
620 one simple syntax. The three tasks:
621
622 produce some text on a certain condition,
623 translate it to the proper language, and
624 deliver it in some way to a user.
625
626 Text messages in Perl are produced by commands like "print", "die",
627 "warn", "carp", or "croak". But where is that output directed to?
628 Translations is hard. There is no clean exception mechanism.
629
630 Besides, the "print"/"warn"/"die" together produce only three different
631 output "levels" with a message. Think of the variation syslog offers:
632 more than 7 levels. Many people manually implement their own tricks to
633 get additional levels, like verbose and debug flags. Log::Report
634 offers that variety.
635
636 The (optional) translations use the beautiful syntax defined by
637 Locale::TextDomain, with some own extensions (of course). A very
638 important difference is that translations are delayed till the delivery
639 step: until a dispatcher actually writes your message into a file,
640 sends it to syslog, or shows it on the screen. This means that the
641 pop-up in the graphical interface of the user may show the text in the
642 language of the user --say Chinese in utf8--, but at the same time
643 syslog may write the latin1 English version of the same message.
644
645 Background ideas
646 The following ideas are the base of this implementation:
647
648 . simplification
649 Handling errors and warnings is probably the most labor-intensive
650 task for a programmer: when programs are written correctly, up-to
651 three-quarters of the code is related to testing, reporting, and
652 handling (problem) conditions. Simplifying the way to create
653 reports, simplifies programming and maintenance.
654
655 . multiple dispatchers
656 It is not the location where the (for instance) error occurs which
657 determines what will happen with the text, but the main application
658 which uses the the complaining module has control. Messages have a
659 reason. Based on the `reason' classification, they can get
660 ignored, send to one or multiple dispatchers, like Log::Dispatch,
661 Log::Log4perl, or UNIX syslog.
662
663 . delayed translations
664 The background ideas are that of Locale::TextDomain, based on
665 gettext(). However, in the "Log::Report" infrastructure,
666 translations are postponed until the text is dispatched to a screen
667 or log-file; the same report can be sent to syslog in (for
668 instance) English and to the user interface in Dutch.
669
670 . context sensitive
671 Using contexts, you can set-up how to translate or rewrite
672 messages, to improve messages. A typical problem is whether to use
673 gender in text (use 'his' or 'her'): you can set a gender in a
674 context, and the use translation tables to pick the right one.
675
676 Error handling models
677 There are two approaches to handling errors and warnings. In the first
678 approach, as produced by "die", "warn" and the "carp" family of
679 commands, the program handles the problem immediately on the location
680 where the problem appears. In the second approach, an exception is
681 thrown on the spot where the problem is created, and then somewhere
682 else in the program the condition is handled.
683
684 The implementation of exceptions in Perl5 is done with a eval-die pair:
685 on the spot where the problem occurs, "die" is called. But, because of
686 the execution of that routine is placed within an "eval", the program
687 as a whole will not die, just the execution of a part of the program
688 will seize. However, what if the condition which caused the routine to
689 die is solvable on a higher level? Or what if the user of the code
690 doesn't bother that a part fails, because it has implemented
691 alternatives for that situation? Exception handling is quite clumsy in
692 Perl5.
693
694 The "Log::Report" set of distributions let modules concentrate on the
695 program flow, and let the main program decide on the report handling
696 model. The infrastructure to translate messages into multiple
697 languages, whether to create exceptions or carp/die, to collect longer
698 explanations with the messages, to log to mail or syslog, and so on, is
699 decided in pluggable back-ends.
700
701 The Reason for the report
702
703 Traditionally, perl has a very simple view on error reports: you either
704 have a warning or an error. However, it would be much clearer for
705 user's and module-using applications, when a distinction is made
706 between various causes. For instance, a configuration error is quite
707 different from a disk-full situation. In "Log::Report", the produced
708 reports in the code tell what is wrong. The main application defines
709 loggers, which interpret the cause into (syslog) levels.
710
711 Defined by "Log::Report" are
712
713 . trace (debug, program)
714 The message will be used when some logger has debugging enabled.
715 The messages show steps taken by the program, which are of interest
716 by the developers and maintainers of the code, but not for end-
717 users.
718
719 . assert (program)
720 Shows an unexpected condition, but continues to run. When you want
721 the program to abort in such situation, that use "panic".
722
723 . info (verbose, program)
724 These messages show larger steps in the execution of the program.
725 Experienced users of the program usually do not want to see all
726 these intermediate steps. Most programs will display info messages
727 (and higher) when some "verbose" flag is given on the command-line.
728
729 . notice (program)
730 An user may need to be aware of the program's accidental smart
731 behavior, for instance, that it initializes a lasting "Desktop"
732 directory in your home directory. Notices should be sparse.
733
734 . warning (program)
735 The program encountered some problems, but was able to work around
736 it by smart behavior. For instance, the program does not
737 understand a line from a log-file, but simply skips the line.
738
739 . mistake (user)
740 When a user does something wrong, but what is correctable by smart
741 behavior of the program. For instance, in some configuration file,
742 you can fill-in "yes" or "no", but the user wrote "yeah". The
743 program interprets this as "yes", producing a mistake message as
744 warning.
745
746 It is much nicer to tell someone that he/she made a mistake, than
747 to call that an error.
748
749 . error (user)
750 The user did something wrong, which is not automatically
751 correctable or the program is not willing to correct it
752 automatically for reasons of code quality. For instance, an
753 unknown option flag is given on the command-line. These are
754 configuration issues, and have no useful value in $!. The program
755 will be stopped, usually before taken off.
756
757 . fault (system)
758 The program encountered a situation where it has no work-around.
759 For instance, a file cannot be opened to be written. The cause of
760 that problem can be some user error (i.e. wrong filename), or
761 external (you accidentally removed a directory yesterday). In any
762 case, the $! ($ERRNO) variable is set here.
763
764 . alert (system)
765 Some external cause disturbs the execution of the program, but the
766 program stays alive and will try to continue operation. For
767 instance, the connection to the database is lost. After a few
768 attempts, the database can be reached and the program continues as
769 if nothing happened. The cause is external, so $! is set.
770 Usually, a system administrator needs to be informed about the
771 problem.
772
773 . failure (system)
774 Some external cause makes it impossible for this program to
775 continue. $! is set, and usually the system administrator wants to
776 be informed. The program will die.
777
778 The difference with "fault" is subtile and not always clear. A
779 fault reports an error returned by an operating system call, where
780 the failure would report an operational problem, like a failing
781 mount.
782
783 . panic (program)
784 All above report classes are expected: some predictable situation
785 is encountered, and therefore a message is produced. However,
786 programs often do some internal checking. Of course, these
787 conditions should never be triggered, but if they do... then we can
788 only stop.
789
790 For instance, in an OO perl module, the base class requires all
791 sub-classes to implement a certain method. The base class will
792 produce a stub method with triggers a panic when called. The non-
793 dieing version of this test "assert".
794
795 Debugging or being "verbose" are run-time behaviors, and have nothing
796 directly to do with the type of message which is produced. These two
797 are modes which can be set on the dispatchers: one dispatcher may be
798 more verbose that some other.
799
800 On purpose, we do not use the terms "die" or "fatal", because the
801 dispatcher can be configured what to do in cause of which condition.
802 For instance, it may decide to stop execution on warnings as well.
803
804 The terms "carp" and "croak" are avoided, because the program cause
805 versus user cause distinction (warn vs carp) is reflected in the use of
806 different reasons. There is no need for "confess" and "croak" either,
807 because the dispatcher can be configured to produce stack-trace
808 information (for a limited sub-set of dispatchers)
809
810 Report levels
811
812 Various frameworks used with perl programs define different labels to
813 indicate the reason for the message to be produced.
814
815 Perl5 Log::Dispatch Syslog Log4Perl Log::Report
816 print 0,debug debug debug trace
817 print 0,debug debug debug assert
818 print 1,info info info info
819 warn\n 2,notice notice info notice
820 warn 3,warning warn warn mistake
821 carp 3,warning warn warn warning
822 die\n 4,error err error error
823 die 5,critical crit fatal fault
824 croak 6,alert alert fatal alert
825 croak 7,emergency emerg fatal failure
826 confess 7,emergency emerg fatal panic
827
828 Run modes
829
830 The run-mode change which messages are passed to a dispatcher, but from
831 a different angle than the dispatch filters; the mode changes
832 behavioral aspects of the messages, which are described in detail in
833 "Processing the message" in Log::Report::Dispatcher. However, it
834 should behave as you expect: the DEBUG mode shows more than the VERBOSE
835 mode, and both show more than the NORMAL mode.
836
837 . Example: extract run mode from Getopt::Long
838
839 The GetOptions() function will count the number of "v" options on the
840 command-line when a "+" is after the option name.
841
842 use Log::Report;
843 use Getopt::Long qw(:config no_ignore_case bundling);
844
845 my $mode; # defaults to NORMAL
846 GetOptions 'v+' => \$mode
847 , 'verbose=i' => \$mode
848 , 'mode=s' => \$mode
849 or exit 1;
850
851 dispatcher 'PERL', 'default', mode => $mode;
852
853 Now, "-vv" will set $mode to 2, as will "--verbose 2" and "--verbose=2"
854 and "--mode=ASSERT". Of course, you do not need to provide all these
855 options to the user: make a choice.
856
857 . Example: the mode of a dispatcher
858
859 my $mode = dispatcher(find => 'myname')->mode;
860
861 . Example: run-time change mode of a dispatcher
862
863 To change the running mode of the dispatcher, you can do
864 dispatcher mode => DEBUG => 'myname';
865
866 However, be warned that this does not change the types of messages
867 accepted by the dispatcher! So: probably you will not receive the
868 trace, assert, and info messages after all. So, probably you need to
869 replace the dispatcher with a new one with the same name:
870 dispatcher FILE => 'myname', to => ..., mode => 'DEBUG';
871
872 This may reopen connections (depends on the actual dispatcher), which
873 might be not what you wish to happened. In that case, you must take
874 the following approach:
875
876 # at the start of your program
877 dispatcher FILE => 'myname', to => ...
878 , accept => 'ALL'; # overrule the default 'NOTICE-' !!
879
880 # now it works
881 dispatcher mode => DEBUG => 'myname'; # debugging on
882 ...
883 dispatcher mode => NORMAL => 'myname'; # debugging off
884
885 Of course, this comes with a small overall performance penalty.
886
887 Exceptions
888
889 The simple view on live says: you 're dead when you die. However, more
890 complex situations try to revive the dead. Typically, the "die" is
891 considered a terminating exception, but not terminating the whole
892 program, but only some logical block. Of course, a wrapper round that
893 block must decide what to do with these emerging problems.
894
895 Java-like languages do not "die" but throw exceptions which contain the
896 information about what went wrong. Perl modules like
897 "Exception::Class" simulate this. It's a hassle to create exception
898 class objects for each emerging problem, and the same amount of work to
899 walk through all the options.
900
901 Log::Report follows a simpler scheme. Fatal messages will "die", which
902 is caught with "eval", just the Perl way (used invisible to you).
903 However, the wrapper gets its hands on the message as the user has
904 specified it: untranslated, with all unprocessed parameters still at
905 hand.
906
907 try { fault __x "cannot open file {file}", file => $fn };
908 if($@) # is Log::Report::Dispatcher::Try
909 { my $cause = $@->wasFatal; # is Log::Report::Exception
910 $cause->throw if $cause->message->msgid =~ m/ open /;
911 # all other problems ignored
912 }
913
914 See Log::Report::Dispatcher::Try and Log::Report::Exception.
915
916 Comparison
917 Some notes on differences between the Log::Report approach and other
918 Perl concepts.
919
920 die/warn/Carp
921
922 Perl's built-in exception system is very primitive: "die" and "warn".
923 Most programming languages provide a much more detailed exception
924 mechanism.
925
926 A typical perl program can look like this:
927
928 my $dir = '/etc';
929
930 File::Spec->file_name is_absolute($dir)
931 or die "ERROR: directory name must be absolute.\n";
932
933 -d $dir
934 or die "ERROR: what platform are you on?";
935
936 until(opendir DIR, $dir)
937 { warn "ERROR: cannot read system directory $dir: $!";
938 sleep 60;
939 }
940
941 print "Processing directory $dir\n"
942 if $verbose;
943
944 while(defined(my $file = readdir DIR))
945 { if($file =~ m/\.bak$/)
946 { warn "WARNING: found backup file $dir/$f\n";
947 next;
948 }
949
950 die "ERROR: file $dir/$file is binary"
951 if $debug && -B "$dir/$file";
952
953 print "DEBUG: processing file $dir/$file\n"
954 if $debug;
955
956 open FILE, "<", "$dir/$file"
957 or die "ERROR: cannot read from $dir/$f: $!";
958
959 close FILE
960 or croak "ERROR: read errors in $dir/$file: $!";
961 }
962
963 Where "die", "warn", and "print" are used for various tasks. With
964 "Log::Report", you would write
965
966 use Log::Report;
967
968 # can be left-out when there is no debug/verbose
969 dispatcher PERL => 'default', mode => 'DEBUG';
970
971 my $dir = '/etc';
972
973 File::Spec->file_name is_absolute($dir)
974 or mistake "directory name must be absolute";
975
976 -d $dir
977 or panic "what platform are you on?";
978
979 until(opendir DIR, $dir)
980 { alert "cannot read system directory $dir";
981 sleep 60;
982 }
983
984 info "Processing directory $dir";
985
986 while(defined(my $file = readdir DIR))
987 { if($file =~ m/\.bak$/)
988 { notice "found backup file $dir/$f";
989 next;
990 }
991
992 assert "file $dir/$file is binary"
993 if -B "$dir/$file";
994
995 trace "processing file $dir/$file";
996
997 unless(open FILE, "<", "$dir/$file")
998 { error "no permission to read from $dir/$f"
999 if $!==ENOPERM;
1000 fault "unable to read from $dir/$f";
1001 }
1002
1003 close FILE
1004 or failure "read errors in $dir/$file";
1005 }
1006
1007 A lot of things are quite visibly different, and there are a few
1008 smaller changes. There is no need for a new-line after the text of the
1009 message. When applicable (error about system problem), then the $! is
1010 added automatically.
1011
1012 Log::Dispatch and Log::Log4perl
1013
1014 The two major logging frameworks for Perl are Log::Dispatch and
1015 Log::Log4perl; both provide a pluggable logging interface.
1016
1017 Both frameworks do not have (gettext or maketext) language translation
1018 support, which has various consequences. When you wish for to report
1019 in some other language, it must be translated before the logging
1020 function is called. This may mean that an error message is produced
1021 in Chinese, and therefore also ends-up in the syslog file in Chinese.
1022 When this is not your language, you have a problem.
1023
1024 Log::Report translates only in the back-end, which means that the user
1025 may get the message in Chinese, but you get your report in your beloved
1026 Dutch. When no dispatcher needs to report the message, then no time is
1027 lost in translating.
1028
1029 With both logging frameworks, you use terminology comparable to syslog:
1030 the module programmer determines the seriousness of the error message,
1031 not the application which integrates multiple modules. This is the way
1032 perl programs usually work, but often the cause for inconsequent user
1033 interaction.
1034
1035 Locale::gettext and Locate::TextDomain
1036
1037 Both on GNU gettext based implementations can be used as translation
1038 frameworks. Locale::TextDomain syntax is supported, with quite some
1039 extensions. Read the excellent documentation of Locale::Textdomain.
1040 Only the tried access via "$__" and "%__" are not supported.
1041
1042 The main difference with these modules is the moment when the
1043 translation takes place. In Locale::TextDomain, an "__x()" will result
1044 in an immediate translation request via gettext(). "Log::Report"'s
1045 version of "__x()" will only capture what needs to be translated in an
1046 object. When the object is used in a print statement, only then the
1047 translation will take place. This is needed to offer ways to send
1048 different translations of the message to different destinations.
1049
1050 To be able to postpone translation, objects are returned which
1051 stringify into the translated text.
1052
1054 Error: in SCALAR context, only one dispatcher name accepted
1055 The dispatcher() method returns the Log::Report::Dispatcher objects
1056 which it has accessed. When multiple names where given, it wishes
1057 to return a LIST of objects, not the count of them.
1058
1060 This module is part of Log-Report distribution version 1.36, built on
1061 October 27, 2023. Website: http://perl.overmeer.net/CPAN/
1062
1064 Copyrights 2007-2023 by [Mark Overmeer <markov@cpan.org>]. For other
1065 contributors see ChangeLog.
1066
1067 This program is free software; you can redistribute it and/or modify it
1068 under the same terms as Perl itself. See http://dev.perl.org/licenses/
1069
1070
1071
1072perl v5.36.1 2023-10-27 Log::Report(3)