2214e477e10d2cdd0c29b40337537d081debf000
[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         "file" => \&LogFacilityFile,
23         "syslog" => \&LogFacilitySyslog,
24 );
25
26
27 #
28 ## The "Init" (Logger) function.
29 #
30 ## This function is responsible to initialize the Logger as a class based object.
31 ## It has to be called once before logging can be done.
32 #
33 ## The following arguments must be passed, when initializing a new Logger:
34 ## "LogLevel" and "LogFacility" with valid values from above.
35 #
36 sub Init (%) {
37         my ( $class, %args ) = @_;
38         my $self = \%args;
39
40         # Fail, if some critical arguments are missing.
41         unless ((exists($self->{LogLevel})) && (exists($self->{LogFacility}))) {
42                 die "Could not initialize the Logger: Too less arguments are given.\n";
43         }
44
45         # Use bless to make "$self" to an object of class "$class".
46         bless($self, $class);
47
48         # Return the class object.
49         return $self;
50 }
51
52 #
53 ## The main "Log" function.
54 #
55 ## This function is used to handle the messages which are generated on various 
56 ## points in the main programm or its modules. Those messages will contain usefull
57 ## information or deeper details about errors.
58 #
59 ## The Log function takes care about the configured loglevel and transmitts the
60 ## log messages to the configured log facility.
61 #
62 sub Log ($$) {
63         my $self = shift;
64         my ($level, $message) = @_;
65
66         # Check if we got an invalid loglevel.
67         unless(exists($loglevels{$level})) {
68                 &Log("err", "The logger has been called with an invalid loglevel ($level)!\n");
69                 return;
70         }
71
72         # Get value for the current used loglevel.
73         my $current_level = $loglevels{$self->{LogLevel}};
74
75         # Get value for the required loglevel.
76         my $required_level = $loglevels{$level};
77
78         # Compare the current and required level to determine,
79         # if the message should be handled.
80         if ($current_level >= $required_level) {
81                 # Get the facility, which should be used.
82                 my $use_facility = $self->{LogFacility};
83
84                 # Transmit log message to the correct log facility.
85                 $logfacilities{$use_facility}->($self, $level, $message);
86         }
87 }
88
89 #
90 ## GetLogLevels function.
91 #
92 ## This really simple function just returns the hash which
93 ## contains all supported log levels.
94 #
95 sub GetLogLevels () {
96         # Nothing to do, just return the loglevels hash.
97         return %loglevels;
98 }
99
100 #
101 ## LogFacilityConsole function.
102 #
103 ## This is a very simple log facility which just prints the given log
104 ## message to STDOUT.
105 #
106 sub LogFacilityConsole ($$) {
107         my $self = shift;
108         my ($type, $message) = @_;
109
110         # Print message on STDOUT.
111         print STDOUT "\[$type\] $message\n";
112 }
113
114 #
115 ## LogFacilitySyslog function.
116 #
117 ## This log facility sends a given log message to the system log service (syslog).
118 #
119 sub LogFacilitySyslog ($$) {
120         my $self = shift;
121         my ($type, $message) = @_;
122
123         # The syslog function works best with an array based input,
124         # so generate one before passing the message details to syslog.
125         my @syslog = ("$type", "<$type> $message");
126
127         # Establish the connection to the syslog service.
128         openlog('guardian', 'cons,pid', 'user');
129
130         # Send the log message.
131         syslog(@syslog);
132
133         # Close the log handle.
134         closelog();
135 }
136
137 #
138 ## LogFacilityFile function.
139 #
140 ## This log facility will write any given log messages to a specified log file.
141 #
142 sub LogFacilityFile ($$) {
143         my $self = shift;
144         my ($type, $message) = @_;
145
146         # Open the logfile for writing.
147         open(LOGFILE, '>>', $self->{LogFile}) or die "Could not write to $self->{LogFile}: $!\n";
148
149         # Write log message to file.
150         print LOGFILE "\[$type\] $message\n";
151
152         # Close filehandle.
153         close(FILE);
154 }
155
156 1;