Add "Logger" module.
[people/stevee/guardian.git] / modules / Logger.pm
1 package Guardian::Logger;
2 use strict;
3 use warnings;
4
5 use Exporter qw(import);
6
7 our @EXPORT_OK = qw(New Log GetLogLevels);
8
9 use Sys::Syslog qw(:DEFAULT setlogsock);
10
11 # Hash which stores all supported log levels and their priority.
12 my %loglevels = (
13         'off' => '0',
14         'err' => '1',
15         'info' => '1',
16         'debug' => '2',
17 );
18
19 # This hash contains the supported log facilities and their corresponding subroutines.
20 my %logfacilities = (
21         "console" => \&LogFacilityConsole,
22         "syslog" => \&LogFacilitySyslog,
23 );
24
25
26 #
27 ## The "New" (Logger) function.
28 #
29 ## This function is responsible to initialize the Logger as a class based object.
30 ## It has to be called once before logging can be done.
31 #
32 ## The following arguments must be passed, when initializing a new Logger:
33 ## "LogLevel" and "LogFacility" with valid values from above.
34 #
35 sub New (%) {
36         my ( $class, %args ) = @_;
37         my $self = \%args;
38
39         # Fail, if some critical arguments are missing.
40         unless ((exists($self->{LogLevel})) && (exists($self->{LogFacility}))) {
41                 die "Could not initialize the Logger: Too less arguments are given.\n";
42         }
43
44         # Use bless to make "$self" to an object of class "$class".
45         bless($self, $class);
46
47         # Return the class object.
48         return $self;
49 }
50
51 #
52 ## The main "Log" function.
53 #
54 ## This function is used to handle the messages which are generated on various 
55 ## points in the main programm or its modules. Those messages will contain usefull
56 ## information or deeper details about errors.
57 #
58 ## The Log function takes care about the configured loglevel and transmitts the
59 ## log messages to the configured log facility.
60 #
61 sub Log ($$) {
62         my $self = shift;
63         my ($level, $message) = @_;
64
65         # Check if we got an invalid loglevel.
66         unless(exists($loglevels{$level})) {
67                 &Log("err", "The logger has been called with an invalid loglevel ($level)!\n");
68                 return;
69         }
70
71         # Get value for the current used loglevel.
72         my $current_level = $loglevels{$self->{LogLevel}};
73
74         # Get value for the required loglevel.
75         my $required_level = $loglevels{$level};
76
77         # Compare the current and required level to determine,
78         # if the message should be handled.
79         if ($current_level >= $required_level) {
80                 # Get the facility, which should be used.
81                 my $use_facility = $self->{LogFacility};
82
83                 # Transmit log message to the correct log facility.
84                 $logfacilities{$use_facility}->($level, $message);
85         }
86 }
87
88 #
89 ## The Update (Logger) settings function
90 #
91 ## This function is used to update the object settings of the
92 ## initialized Logger class.
93 #
94 sub Update (%) {
95         my ($self, %args) = @_;
96
97         # Map the new hash keys and values to the existing one inside
98         # the class.
99         map { $self->{ $_ } = $args{ $_ } } keys %args;
100 }
101
102 #
103 ## GetLogLevels function.
104 #
105 ## This really simple function just returns the hash which
106 ## contains all supported log levels.
107 #
108 sub LogLevels () {
109         # Nothing to do, just return the loglevels hash.
110         return %loglevels;
111 }
112
113 #
114 ## LogFacilityConsole function.
115 #
116 ## This is a very simple log facility which just prints the given log
117 ## message to STDOUT.
118 #
119 sub LogFacilityConsole ($$) {
120         my ($type, $message) = @_;
121
122         # Print message on STDOUT.
123         print STDOUT "\[$type\] $message\n";
124 }
125
126 #
127 ## LogFacilitySyslog function.
128 #
129 ## This log facility sends a given log message to the system log service (syslog).
130 #
131 sub LogFacilitySyslog ($$) {
132         my ($type, $message) = @_;
133
134         # The syslog function works best with an array based input,
135         # so generate one before passing the message details to syslog.
136         my @syslog = ("$type", "<$type> $message");
137
138         # Establish the connection to the syslog service.
139         openlog('guardian', 'cons,pid', 'user');
140
141         # Send the log message.
142         syslog(@syslog);
143
144         # Close the log handle.
145         closelog();
146 }
147
148 1;