aboutsummaryrefslogtreecommitdiff
path: root/lib/Log/Colored.rakumod
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Log/Colored.rakumod')
-rw-r--r--lib/Log/Colored.rakumod305
1 files changed, 305 insertions, 0 deletions
diff --git a/lib/Log/Colored.rakumod b/lib/Log/Colored.rakumod
new file mode 100644
index 0000000..239157e
--- /dev/null
+++ b/lib/Log/Colored.rakumod
@@ -0,0 +1,305 @@
+#! /usr/bin/env false
+
+use v6.d;
+
+use Log;
+use Log::Level;
+use Terminal::ANSIColor;
+
+#| An implementation of Log with colors.
+unit class Log::Colored is Log;
+
+#| An array of hashes. Each has must have a handle key, with an IO::Handle to
+#| print messages to. A level key with an integer to signify a Log::Level is
+#| also required.
+has @!outputs;
+
+#| A supplier to emit messages to.
+has Supplier $!messages;
+
+#| Send an emergency message.
+multi method emergency (
+ #| The message to print.
+ Str:D $message,
+) {
+ $!messages.emit({
+ message => self!message($message, 'bold underline red'),
+ level => 0,
+ })
+}
+
+#| Send a formatted emergency message.
+multi method emergency (
+ #| A printf-style format string.
+ Str:D $format,
+
+ #| Arguments to substitute into the format string placeholders.
+ *@args,
+) {
+ $!messages.emit({
+ message => self!message($format.sprintf(|@args), 'bold underline red'),
+ level => 0,
+ })
+}
+
+#| Send an alert message.
+multi method alert (
+ #| The message to print.
+ Str:D $message,
+) {
+ $!messages.emit({
+ message => self!message($message, 'bold red'),
+ level => 1,
+ })
+}
+
+#| Send a formatted alert message.
+multi method alert (
+ #| A printf-style format string.
+ Str:D $format,
+
+ #| Arguments to substitute into the format string placeholders.
+ *@args,
+) {
+ $!messages.emit({
+ message => self!message($format.sprintf(|@args), 'bold red'),
+ level => 1,
+ })
+}
+
+#| Send a critical message.
+multi method critical (
+ #| The message to print.
+ Str:D $message,
+) {
+ $!messages.emit({
+ message => self!message($message, 'red'),
+ level => 2,
+ })
+}
+
+#| Send a formatted critical message.
+multi method critical (
+ #| A printf-style format string.
+ Str:D $format,
+
+ #| Arguments to substitute into the format string placeholders.
+ *@args,
+) {
+ $!messages.emit({
+ message => self!message($format.sprintf(|@args), 'red'),
+ level => 2,
+ })
+}
+
+#| Send an error message.
+multi method error (
+ #| The message to print.
+ Str:D $message,
+) {
+ $!messages.emit({
+ message => self!message($message, 'bold yellow'),
+ level => 3,
+ })
+}
+
+#| Send a formatted error message.
+multi method error (
+ #| A printf-style format string.
+ Str:D $format,
+
+ #| Arguments to substitute into the format string placeholders.
+ *@args,
+) {
+ $!messages.emit({
+ message => self!message($format.sprintf(|@args), 'bold yellow'),
+ level => 3,
+ })
+}
+
+#| Send a warning message.
+multi method warning (
+ #| The message to print.
+ Str:D $message,
+) {
+ $!messages.emit({
+ message => self!message($message, 'yellow'),
+ level => 4,
+ })
+}
+
+#| Send a formatted warning message.
+multi method warning (
+ #| A printf-style format string.
+ Str:D $format,
+
+ #| Arguments to substitute into the format string placeholders.
+ *@args,
+) {
+ $!messages.emit({
+ message => self!message($format.sprintf(|@args), 'yellow'),
+ level => 4,
+ })
+}
+
+#| Send a notice message. This is the "normal" level to publish log entries on.
+multi method notice (
+ #| The message to print.
+ Str:D $message
+) {
+ $!messages.emit({
+ message => self!message($message, 'default'),
+ level => 5,
+ })
+}
+
+#| Send a formatted notice message. This is the "normal" level to publish log
+#| entries on.
+multi method notice (
+ #| A printf-style format string.
+ Str:D $format,
+
+ #| Arguments to substitute into the format string placeholders.
+ *@args,
+) {
+ $!messages.emit({
+ message => self!message($format.sprintf(|@args), 'default'),
+ level => 5,
+ })
+}
+
+#| Send an informational message.
+multi method info (
+ #| The message to print.
+ Str:D $message
+) {
+ $!messages.emit({
+ message => self!message($message, 'cyan'),
+ level => 6,
+ })
+}
+
+#| Send a formatted informational message.
+multi method info (
+ #| The printf-style format string.
+ Str:D $format,
+
+ #| Arguments to substitute into the format string placeholders.
+ *@args,
+) {
+ $!messages.emit({
+ message => self!message($format.sprintf(|@args), 'cyan'),
+ level => 6,
+ })
+}
+
+#| Send a debug message.
+multi method debug (
+ #| The message to print.
+ Str:D $message,
+) {
+ $!messages.emit({
+ message => self!message($message, 'black'),
+ level => 7,
+ })
+}
+
+#| Send a formatted debug message.
+multi method debug (
+ #| A printf-style format string.
+ Str:D $format,
+
+ #| Arguments to substitute into the format string placeholders.
+ *@args,
+) {
+ $!messages.emit({
+ message => self!message($format.sprintf(|@args), 'black'),
+ level => 7,
+ })
+}
+
+#| Add an output to the logger.
+multi method add-output (
+ #| The IO::Handle to write log messages to.
+ IO::Handle:D $handle,
+
+ #| The log level for this particular stream.
+ Int() $level where Log::Level::Emergency ≤ * ≤ Log::Level::Debug,
+
+ #| A filter function to apply to any messages sent to the output.
+ Callable :$filter?,
+) {
+ @!outputs.push({
+ :$handle,
+ :$level,
+ :$filter,
+ });
+}
+
+#| Convenience method to get the callee name. This is the package name if one
+#| exists, or the source file name.
+method !callee (
+ #| The depth of which to get the callframe.
+ Int:D $depth = 4,
+
+ --> Str
+) {
+ my $file = callframe($depth).annotations<file>;
+
+ return $file unless $file.ends-with(')');
+
+ $file.words.tail.substr(1, *-1);
+}
+
+#| Convenience method for formatting the message as desired.
+method !message (
+ #| The original message to be logged.
+ Str:D $message,
+
+ #| A human readable identifier for the level.
+ Str:D $color,
+
+ --> Str
+) {
+ colored("{DateTime.now.utc} {self!callee}: $message", $color);
+}
+
+submethod TWEAK
+{
+ # Set up the Supply for messages.
+ $!messages .= new;
+ $!messages.Supply.tap(sub (%payload) {
+ @!outputs
+ .race
+ .grep(%payload<level> ≤ *<level>)
+ .grep({ $_<filter> ?? $_<filter>(%payload).so !! True })
+ .map(*<handle>.say(%payload<message>))
+ ;
+ });
+}
+
+=begin pod
+
+=NAME Log::Colored
+=VERSION 0.0.0
+=AUTHOR Patrick Spek <p.spek@tyil.nl>
+
+=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