aboutsummaryrefslogtreecommitdiff
path: root/README.rakudoc
blob: f446d8399ec1a884036e1eeac7f77c67450c472b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
=begin pod

=NAME    Log
=VERSION 0.0.0
=AUTHOR  Patrick Spek <p.spek@tyil.nl>

=head1 Description

An interface for logging mechanisms in the Raku programming language to adhere
to. L<RFC5424|https://tools.ietf.org/html/rfc5424> has been used as a reference
point to decide which levels to support, and what naming conventions to use.

=head2 Intention

This module has been created to serve as an interface to which logging
mechanisms in Raku can adhere. A standardized interface for handling logging
will make it easier for all projects to get started with logging, while
allowing application handlers to adjust all logging to suit their current
application.

=head2 Usage

Any class that wants to handle logging in Raku can implement the Log interface.

	use Log;

	unit class Log::Custom is Log {
		…
	}

To do the actual logging, the C<$*LOG> dynamic variable is to be used.

=head3 For library developers

Throughout your library, you can use any of the 8 methods that a C<Log>
implementation must support:

=item C<emergency>
=item C<alert>
=item C<critical>
=item C<error>
=item C<warning>
=item C<notice>
=item C<info>
=item C<debug>

There's no guarantee that C<$*LOG> is populated, since developers may not
implement it for any number of reasons. Luckily, Raku has a terse way to work
with this reality, using the C<with> control flow statement.

	.info('This is an informational message') with $*LOG;

If C<$*LOG> is defined, C<.info> will be called on it. Otherwise, this
statement is skipped altogether. This allows application developers to decide
if they want any logging, and which implementation to use of the C<Log> class.

=head3 For application developers

Much like library developers, you can use the same methods to add logging to
your application. However, the application must also set up the C<$*LOG>
variable. Any implementation of C<Log> should work.

	my $*LOG = Log::Simple.new;

You should also add one or more outputs. These must be C<IO::Handle> objects.
To send all logging to C<STDERR>, add C<$*ERR> as output.

	$*LOG.add-output($*ERR);

You can specify a minimum log level for each output, and optionally a Callable
to act as filter.

	$*LOG.add-output($*ERR, Log::Level::Debug, filter => sub (%payload) {
		%payload<message> ~~ /Foo/ # Only send messages containing "Foo"
	});

=head4 Environment variables

There are some environment variables that must be honored. These are intended
to allow the user to customize the logging into what works for I<them>.

=head5 C<RAKU_LOG_CLASS>

When set, the class name defined in this environment variable must be used to
populate the C<$*LOG> variable. This can be implemented using a C<require>
statement and use of the I<defined-or> operator.

	$*LOG = (require ::(%*ENV<RAKU_LOG_CLASS> // 'Log::Simple')).new;

=head5 C<RAKU_LOG_LEVEL>

When set, this should override the log level used in the application. This is
easily implemented using the I<defined-or> operator in your code.

	$*LOG.add-output($*ERR, %*ENV<RAKU_LOG_LEVEL> // Log::Level::Info);

=head1 Installation

Install this module through L<zef|https://github.com/ugexe/zef>:

=begin code :lang<sh>
zef install Log
=end code

=head1 Documentation

Documentation is written as L<Pod6|https://docs.raku.org/language/pod>
documents, and can be read with the
L<C<p6doc>|https://modules.raku.org/dist/p6doc:github:perl6> module.

=begin input
p6doc Log
=end input

At your option, you can also use prettier readers, such as
L<C<App::Rakuman>|https://modules.raku.org/dist/App::Rakuman:cpan:TYIL>.

=begin input
rakuman Log
=end input

=head1 License

This module is distributed under the terms of the LGPL-3.0-only.

=end pod