<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package Guardian::Logger;
use strict;
use warnings;

use Exporter qw(import);

our @EXPORT_OK = qw(New Log GetLogLevels);

use Sys::Syslog qw(:DEFAULT setlogsock);
use POSIX qw(strftime);

# Hash which stores all supported log levels and their priority.
my %loglevels = (
	'off' =&gt; '0',
	'err' =&gt; '1',
	'info' =&gt; '1',
	'debug' =&gt; '2',
);

# This hash contains the supported log facilities and their corresponding subroutines.
my %logfacilities = (
	"console" =&gt; \&amp;LogFacilityConsole,
	"file" =&gt; \&amp;LogFacilityFile,
	"syslog" =&gt; \&amp;LogFacilitySyslog,
);


#
## The "Init" (Logger) function.
#
## This function is responsible to initialize the Logger as a class based object.
## It has to be called once before logging can be done.
#
## The following arguments must be passed, when initializing a new Logger:
## "LogLevel" and "LogFacility" with valid values from above.
#
sub Init (%) {
	my ( $class, %args ) = @_;
	my $self = \%args;

	# Fail, if some critical arguments are missing.
	unless ((exists($self-&gt;{LogLevel})) &amp;&amp; (exists($self-&gt;{LogFacility}))) {
		die "Could not initialize the Logger: Too less arguments are given.\n";
	}

	# Use bless to make "$self" to an object of class "$class".
	bless($self, $class);

	# Return the class object.
	return $self;
}

#
## The main "Log" function.
#
## This function is used to handle the messages which are generated on various 
## points in the main programm or its modules. Those messages will contain usefull
## information or deeper details about errors.
#
## The Log function takes care about the configured loglevel and transmitts the
## log messages to the configured log facility.
#
sub Log ($$) {
	my $self = shift;
	my ($level, $message) = @_;

	# Check if we got an invalid loglevel.
	unless(exists($loglevels{$level})) {
                &amp;Log("err", "The logger has been called with an invalid loglevel ($level)!\n");
                return;
        }

	# Get value for the current used loglevel.
	my $current_level = $loglevels{$self-&gt;{LogLevel}};

	# Get value for the required loglevel.
	my $required_level = $loglevels{$level};

	# Compare the current and required level to determine,
	# if the message should be handled.
	if ($current_level &gt;= $required_level) {
		# Get the facility, which should be used.
		my $use_facility = $self-&gt;{LogFacility};

		# Transmit log message to the correct log facility.
		$logfacilities{$use_facility}-&gt;($self, $level, $message);
	}
}

#
## GetLogLevels function.
#
## This really simple function just returns the hash which
## contains all supported log levels.
#
sub GetLogLevels () {
	# Nothing to do, just return the loglevels hash.
	return %loglevels;
}

#
## LogFacilityConsole function.
#
## This is a very simple log facility which just prints the given log
## message to STDOUT.
#
sub LogFacilityConsole ($$) {
	my $self = shift;
	my ($type, $message) = @_;

	# Get current date and time and format like: "Jan 01 00:00:01"
	my $now = strftime "%b %e %H:%M:%S", localtime();

	# Print message on STDOUT.
	print STDOUT "$now \[$type\] $message\n";
}

#
## LogFacilitySyslog function.
#
## This log facility sends a given log message to the system log service (syslog).
#
sub LogFacilitySyslog ($$) {
	my $self = shift;
	my ($type, $message) = @_;

	# The syslog function works best with an array based input,
	# so generate one before passing the message details to syslog.
	my @syslog = ("$type", "&lt;$type&gt; $message");

	# Establish the connection to the syslog service.
	openlog('guardian', 'cons,pid', 'user');

	# Send the log message.
	syslog(@syslog);

	# Close the log handle.
	closelog();
}

#
## LogFacilityFile function.
#
## This log facility will write any given log messages to a specified log file.
#
sub LogFacilityFile ($$) {
	my $self = shift;
	my ($type, $message) = @_;

	# Get current date and time and format like: "Jan 01 00:00:01"
	my $now = strftime "%b %e %H:%M:%S", localtime();

	# Open the logfile for writing.
	open(LOGFILE, '&gt;&gt;', $self-&gt;{LogFile}) or die "Could not write to $self-&gt;{LogFile}: $!\n";

	# Write log message to file.
	print LOGFILE "$now \[$type\] $message\n";

	# Close filehandle.
	close(FILE);
}

1;
</pre></body></html>