#! /usr/bin/env false use v6.d; use Log; use Log::Level; #| A simple implementation of Log. unit class Log::Simple 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; #| When enabled, include hostname in the log message. This can be useful when #| running the application redundantly in a cluster with centralized logging. has Bool $.hostname = False; #| Send an emergency message. multi method emergency ( #| The message to print. Str:D $message, ) { $!messages.emit({ message => self!message('emergency', $message), 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('emergency', $format.sprintf(|@args)), level => 0, }) } #| Send an alert message. multi method alert ( #| The message to print. Str:D $message, ) { $!messages.emit({ message => self!message('alert', $message), 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('alert', $format.sprintf(|@args)), level => 1, }) } #| Send a critical message. multi method critical ( #| The message to print. Str:D $message, ) { $!messages.emit({ message => self!message('critical', $message), 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('critical', $format.sprintf(|@args)), level => 2, }) } #| Send an error message. multi method error ( #| The message to print. Str:D $message, ) { $!messages.emit({ message => self!message('error', $message), 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('error', $format.sprintf(|@args)), level => 3, }) } #| Send a warning message. multi method warning ( #| The message to print. Str:D $message, ) { $!messages.emit({ message => self!message('warning', $message), 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('warning', $format.sprintf(|@args)), 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('notice', $message), 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('notice', $format.sprintf(|@args)), level => 5, }) } #| Send an informational message. multi method info ( #| The message to print. Str:D $message ) { $!messages.emit({ message => self!message('info', $message), 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('info', $format.sprintf(|@args)), level => 6, }) } #| Send a debug message. multi method debug ( #| The message to print. Str:D $message, ) { $!messages.emit({ message => self!message('debug', $message), 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('debug', $format.sprintf(|@args)), 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 = 3, --> Str ) { my $file = callframe($depth).annotations; return $file unless $file.ends-with(')'); $file.words.tail.substr(1, *-1); } #| Convenience method for formatting the message as desired. method !message ( #| A human readable identifier for the level. Str:D $level, #| The original message to be logged. Str:D $message, --> Str ) { ( DateTime.now.utc, ($*KERNEL.hostname if $!hostname), self!callee, "<$level>", )».Str.join(' ') ~ ": $message" } submethod TWEAK { # Set up the Supply for messages. $!messages .= new; $!messages.Supply.tap(sub (%payload) { @!outputs .race .grep(%payload ≤ *) .grep({ $_ ?? $_(%payload).so !! True }) .map(*.say(%payload)) ; }); } =begin pod =NAME Log::Simple =VERSION 0.1.0 =AUTHOR Patrick Spek =begin LICENSE Copyright © 2020 This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero 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