aboutsummaryrefslogtreecommitdiff
path: root/lib/Log.rakumod
blob: c308544dd6a31ccf6408ab9a5b45dcc4180cf3a5 (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
#! /usr/bin/env false

use v6.d;

use Log::Implementation;
use Log::Level;

unit module Log;

our $instance;

=begin pod

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

=head1 Description

The C<Log> module provides a role which I<should> be implemented by a logging
system. It presents a standardized interface for use around the Raku ecosystem.
This would allow module developers to add logging statements throughout their
libraries, and these logs being in the same format as the application using the
libraries.

=head1 Usage

Usage of the C<Log> module goes through implementations of it, such as
C<Log::Simple>, C<Log::Colored>, or C<Log::JSON>. The C<Log> role itself only
helps in ensuring the interfaces are the same, allowing easy replacement of the
implementation if ever needed in the future.

Whatever imlementation of C<Log> you use, it C<must> be set in the C<$*LOG>
dynamic variable. This makes it available to all the libraries that are used in
the program. You C<should> set it as early as possible.

Because it must be using the C<$*LOG> variable, module developers around the
ecosystem can rely on it for their logging needs. However, not every
application will implement this, and that needs to be accounted for, too. For
this, make use of Raku's C<with> flow control statement.

=begin code :lang<raku>
.notice('This is a log message') with $*LOG;
=end code

This can be used freely and safely, throughout all modules. Any application
using that module and implementing C<Log> will immediately be able to reap the
benefits.

=head2 Implementing a Log class

=begin code :lang<raku>
use Log;

unit class Log::Custom is Log;

# Implement all required methods
=end code

=head3 Methods

There are 8 log levels, each with two method calls to invoke them. All of these
I<must> be implemented.

=item C<multi method emergency (Str:D $) { * }>
=item C<multi method emergency (Str:D $, *@) { * }>
=item C<multi method alert (Str:D $) { * }>
=item C<multi method alert (Str:D $, *@) { * }>
=item C<multi method critical (Str:D $) { * }>
=item C<multi method critical (Str:D $, *@) { * }>
=item C<multi method error (Str:D $) { * }>
=item C<multi method error (Str:D $, *@) { * }>
=item C<multi method warning (Str:D $) { * }>
=item C<multi method warning (Str:D $, *@) { * }>
=item C<multi method notice (Str:D $) { * }>
=item C<multi method info (Str:D $) { * }>
=item C<multi method info (Str:D $, *@) { * }>
=item C<multi method notice (Str:D $, *@) { * }>
=item C<multi method debug (Str:D $0 { * }>
=item C<multi method debug (Str:D $, *@) { * }>

Additionally, the following configuration method I<must> be implemented.

=item C<multi method add-output (IO::Handle:D $, Int() $ where Log::Level::Emergency ≤ * ≤ Log::Level::Debug, Callable $?) { * }>

=head2 Environment variables

This logging standard defines two environment variables to respect.

=defn RAKU_LOG_CLASS
The C<RAKU_LOG_CLASS> allows a user to override the logging class used by the
application. This allows programs ran interactively to show more human friendly
logs, and the same program ran in a cluster to provide formatted logs for
ingestion into a central logging system, without any code changes required.

=defn RAKU_LOG_LEVEL
This allows a user to override the log level used by the application. This way,
by default, a program won't be too spammy with low-level details, but a user
I<can> enable it if they want to figure out why something isn't working the way
they expected.

=begin LICENSE
Copyright © 2020

This program is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation, version 3.

This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
details.

You should have received a copy of the GNU Lesser General Public License along
with this program.  If not, see http://www.gnu.org/licenses/.
=end LICENSE

=end pod

# vim: ft=raku noet sw=8 ts=8