/[cvs]/nfo/perl/libs/DesignPattern/Logger.pm
ViewVC logotype

Annotation of /nfo/perl/libs/DesignPattern/Logger.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (hide annotations)
Thu Feb 20 21:06:27 2003 UTC (21 years, 3 months ago) by joko
Branch: MAIN
Changes since 1.1: +176 -5 lines
+ configurable by package globals
+ standalone mode (object creation via 'new')
+ some comments
+ Log::Dispatch gets configured inside here now
+ coordinated stack tracing
+ convenient shortcut methods resembling the syslog levels

1 joko 1.1 ## ------------------------------------------------------------------------
2 joko 1.2 ## $Id: Logger.pm,v 1.1 2003/02/19 00:34:52 joko Exp $
3 joko 1.1 ## ------------------------------------------------------------------------
4 joko 1.2 ## $Log: Logger.pm,v $
5     ## Revision 1.1 2003/02/19 00:34:52 joko
6     ## + initial commit, again refactored to this place
7     ##
8 joko 1.1 ## Revision 1.3 2003/02/18 18:33:59 joko
9     ## + fix: just logs if possible
10     ##
11     ## Revision 1.2 2003/02/18 16:37:22 joko
12     ## + fix: ...::Hardwired is an optional module
13     ##
14     ## Revision 1.1 2003/02/18 15:57:34 joko
15     ## + initial commit, refactored from DesignPattern::Object::Logger
16     ##
17     ## Revision 1.2 2003/02/14 14:20:42 joko
18     ## + decreased default log-level to debug
19     ##
20     ## Revision 1.1 2002/12/22 14:17:38 joko
21     ## + initial check-in, refactored
22     ##
23     ## Revision 1.1 2002/12/19 01:14:48 cvsjoko
24     ## + initial check-in
25     ##
26     ## ------------------------------------------------------------------------
27    
28    
29     package DesignPattern::Logger;
30    
31     use strict;
32     use warnings;
33    
34     use Data::Dumper;
35     use Log::Dispatch;
36     use Log::Dispatch::Screen;
37     use Log::Dispatch::Config;
38     use Cwd;
39     use DesignPattern::Object;
40    
41 joko 1.2 use vars qw(
42     $LEVEL_DEFAULT
43     $ENABLE_NAMESPACE
44     $NAMESPACE_LEVEL
45     $ENABLE_METHODS
46     $METHOD_LEVELS
47     $TRACE_STACK_LEVELS
48     );
49    
50     # default behaviour
51     $LEVEL_DEFAULT = 'debug';
52     $ENABLE_NAMESPACE = 1;
53     $NAMESPACE_LEVEL = undef;
54     $ENABLE_METHODS = 0;
55     $METHOD_LEVELS = [3];
56     $TRACE_STACK_LEVELS = [];
57    
58 joko 1.1
59     # TODO: review, revise and rewire this!
60     #my $logger = Log::Dispatch::Config->instance;
61    
62     sub __init {
63     my $self = shift;
64     my $action = shift;
65     my $message = shift;
66     #my $options = shift; # ??? or: $self->{__logger}->{options} already...?
67    
68     # configure
69     if (!$self->{__logger}->{configured}) {
70     $self->{__logger}->{configured} = 1;
71     $self->_configure_LogDispatch();
72     }
73    
74     # set passed-in arguments
75     $self->{__logger}->{action} = $action;
76     $self->{__logger}->{message} = $message;
77    
78 joko 1.2 # trace
79     #my $tmp = caller(2);
80     #print Dumper($tmp);
81     #exit;
82    
83    
84     # handle caller
85    
86     # determine class- and subroutinename of context calling us
87     # this task can be controlled by tuning its behaviour
88     # this can be changed by setting
89     # DesignPattern::Logger::...
90     # ...
91     # ...
92     my $calling_class;
93     my $calling_sub;
94    
95    
96     # Default behaviour is:
97     # Use classname from $self and suppress subroutine name.
98     # In case of using this together with DesignPattern::Bridge,
99     # the classnames of child objects are suppressed.
100     # Instead, the classname of the parent container object
101     # gets used *always*.
102     $calling_class = '';
103     $calling_sub = '';
104    
105     # Log class names (en-/disabled, take from specified level)
106     if ($ENABLE_NAMESPACE) {
107     $calling_class = ref $self;
108     if ($NAMESPACE_LEVEL) {
109     my @entry = caller($NAMESPACE_LEVEL);
110     $calling_class = $entry[0];
111     }
112     }
113    
114     # Log method names (en-/disabled, multi-level)
115     if ($ENABLE_METHODS) {
116     my @methods;
117     foreach (@{$METHOD_LEVELS}) {
118     (my $c_package, my $c_filename, my $c_line, my $c_subroutine, my $c_hasargs,
119     my $c_wantarray, my $c_evaltext, my $c_is_require, my $c_hints, my $c_bitmask) = caller($_);
120     $c_subroutine =~ s/.*:://;
121     push @methods, $c_subroutine;
122     }
123     $calling_sub = join(': ', @methods);
124     }
125    
126    
127    
128 joko 1.1 # set default arguments
129 joko 1.2 $self->{__logger}->{classname} = $calling_class;
130     $self->{__logger}->{functionname} = $calling_sub;
131     # FIXME: deprecate this!
132 joko 1.1 $self->{__logger}->{caller} = caller;
133    
134     # set default values
135     $self->{__logger}->{action} ||= '';
136     $self->{__logger}->{options}->{tag} ||= '';
137    
138 joko 1.2 # FIXME: deprecate this!
139 joko 1.1 #$self->{__logger}->{level} ||= 'info';
140 joko 1.2 #$self->{__logger}->{level} ||= 'debug';
141     $self->{__logger}->{level} ||= $LEVEL_DEFAULT;
142    
143     # handle stacktrace
144     foreach (@$TRACE_STACK_LEVELS) {
145     #print "trace-level: ", $_, "\n";
146     #(my $c_package, my $c_filename, my $c_line, my $c_subroutine, my $c_hasargs,
147     #my $c_wantarray, my $c_evaltext, my $c_is_require, my $c_hints, my $c_bitmask) = caller($_);
148     my @entry = caller($_);
149     push @{$self->{__logger}->{trace}->{stack}}, \@entry;
150     }
151 joko 1.1
152     }
153    
154     sub __out {
155     my $self = shift;
156     my $message = shift;
157    
158     # if message given here, append to message stored inside object
159     $self->{__logger}->{message} .= ' - ' . $message if $message;
160    
161     # TODO: refactor this:
162     # - push '$self->__get_prefix()' to additional log-entry-metadata, don't show it on/in any console/logfile output
163     #$logger->log( level => $self->{__logger}->{level}, message => $self->__get_prefix_long() . $message );
164     #$logger->log( level => $self->{__logger}->{level}, message => $message );
165     #$logger->warning( __PACKAGE__ . "->_skip: '$caller' (mixed into '$classname'): ($options->{tag}) $message.");
166     #$self->{__logger}->{instance}->log( level => $self->{__logger}->{level}, message => $self->__get_prefix_short() . $self->{__logger}->{message} );
167 joko 1.2 #$self->{__logger}->{instance}->log( level => $self->{__logger}->{level}, message => $self->__get_prefix_module() . $self->{__logger}->{message} );
168     $self->{__logger}->{instance}->log( level => $self->{__logger}->{level}, message => $self->__get_prefix_best() . $self->{__logger}->{message} );
169 joko 1.1 }
170    
171    
172     sub __handle_options {
173     my $self = shift;
174     #my $options = shift; # ??? or: $self->{__logger}->{options} already...?
175     }
176    
177     sub __get_prefix_long {
178     my $self = shift;
179     return __PACKAGE__ . "->$self->{__logger}->{action}: '$self->{__logger}->{caller}' (mixed into '$self->{__logger}->{classname}'): ($self->{__logger}->{options}->{tag}) - ";
180     }
181    
182     sub __get_prefix_short {
183     my $self = shift;
184     my $tag_append = '';
185     $tag_append = "$self->{__logger}->{options}->{tag} - " if $self->{__logger}->{options}->{tag};
186     return $self->{__logger}->{classname} . "->$self->{__logger}->{action}: $tag_append";
187     }
188    
189     sub __get_prefix_module {
190     my $self = shift;
191     my $tag_append = '';
192     $tag_append = "$self->{__logger}->{options}->{tag} - " if $self->{__logger}->{options}->{tag};
193     return $self->{__logger}->{classname} . ": $tag_append";
194     }
195    
196    
197 joko 1.2 sub __get_prefix_best {
198     my $self = shift;
199     my $namespace = $self->{__logger}->{classname};
200     my $method = '';
201     my $tag_append = '';
202     #$namespace = $namespace . ": " if $namespace;
203     $method = "->" . $self->{__logger}->{functionname} if $self->{__logger}->{functionname};
204     #$method .= ': ' if $method;
205     $tag_append = "$self->{__logger}->{options}->{tag} - " if $self->{__logger}->{options}->{tag};
206    
207     my @line;
208     push @line, $namespace if $namespace;
209     push @line, $method if $method;
210     push @line, $tag_append if $tag_append;
211    
212     #print Dumper(@line);
213    
214     #return join(': ', @line);
215     my $result = join('', @line);
216     $result .= ': ' if $result;
217    
218     return $result;
219    
220     }
221    
222    
223 joko 1.1 sub log {
224     my $self = shift;
225     my $message = shift;
226    
227     # automagically instantiate the object if not there
228     # TODO: do this by creating a dummy object inheriting from DesignPattern::Logger,
229     # for now this just don't work because which dummy one to take: Data::Code::Null?
230     #if (! ref $self) {
231     # $self = DesignPattern::Object->fromPackage('DesignPattern::Logger');
232     #}
233    
234     $self->{__logger}->{level} = shift; # TODO: implement propagation of this into Log::Dispatch-object '$logger'!
235     $self->{__logger}->{options} = shift; # TODO: implement additional behaviours: e.g. { exit => 1 } would exit after tracedump
236    
237     #$self->__init('log', $message);
238     $self->__init('log', $message);
239     $self->__out();
240    
241     }
242    
243     sub skip {
244     my $self = shift;
245     my $message = shift;
246     my $condition = shift;
247     $self->{__logger}->{level} = shift; # TODO: implement propagation of this into Log::Dispatch-object '$logger'!
248     $self->{__logger}->{options} = shift; # TODO: implement additional behaviours: e.g. { exit => 1 } would exit after tracedump
249    
250     my $classname = ref $self;
251     my $caller = caller;
252    
253     $self->{__logger}->{options}->{tag} ||= '';
254    
255     if ($condition) {
256     # V1:
257     #$logger->warning( __PACKAGE__ . "->_skip: '$caller' (mixed into '$classname'): ($options->{tag}) $message.");
258     # V2:
259     $self->__init('skip', $message);
260     $self->__out();
261     return 1;
262     }
263     }
264    
265     sub trace {
266     my $self = shift;
267     my $message = shift;
268     my $data = shift;
269     my $condition = shift;
270     $self->{__logger}->{level} = shift; # TODO: implement propagation of this into Log::Dispatch-object '$logger'!
271     $self->{__logger}->{options} = shift; # TODO: implement additional behaviours: e.g. { exit => 1 } would exit after tracedump
272    
273     my $classname = ref $self;
274     my $caller = caller;
275    
276     $self->{__logger}->{options}->{tag} ||= '';
277    
278     # don't do _any_ tracing if disabled
279     return if $self->{TRACE_DISABLED};
280    
281     # overwrite condition with local configured want-TRACE
282     $condition ||= $self->{TRACE};
283    
284     # dump data
285     my $result = 0;
286     if ($condition) {
287     $message .= " - " . Dumper($data);
288    
289     # V1:
290     # $self->__init('trace');
291     # $logger->info( __PACKAGE__ . "->trace: '$caller' (mixed into '$classname'): ($options->{tag}) $message.");
292    
293     # V2:
294     $self->__init('trace', $message);
295     $self->__out();
296    
297     $result = 1;
298     } else {
299     $result = 0;
300     }
301    
302     # handle additional options
303     if ($self->{TRACE_OPTIONS}) {
304     exit if $self->{__logger}->{options}->{exit};
305     }
306    
307     return $result;
308     }
309    
310    
311     sub _configure_LogDispatch {
312     my $self = shift;
313    
314     my $configurator = DesignPattern::Object->fromPackage('Log::Dispatch::Configurator::Hardwired');
315    
316     # FIXME?
317     my $basepath = cwd() . '/..';
318    
319     # configure custom logHandler
320    
321     if ($configurator) {
322    
323     $configurator->{file_filename} = "$basepath/var/log/logfile.txt";
324     $configurator->{screen_min_level} = 'info';
325    
326     if ($self->{quiet}) {
327     $configurator->{screen_min_level} = 8;
328     }
329    
330     if ($self->{debug}) {
331     $configurator->{screen_min_level} = 'debug';
332     }
333    
334     if ($self->{verbose}) {
335     $configurator->{verbose} = 1;
336     }
337    
338     Log::Dispatch::Config->configure($configurator);
339     $self->{__logger}->{instance} = Log::Dispatch::Config->instance;
340    
341     } else {
342    
343     #Log::Dispatch::Config->configure();
344     #Log::Dispatch->configure();
345     #$self->{__logger}->{instance} = Log::Dispatch->new;
346     $self->{__logger}->{instance} = Log::Dispatch::Screen->new( name => 'screen', 'min_level' => 'debug', stderr => 1 );
347    
348     }
349    
350    
351     }
352 joko 1.2
353     sub configure_logger {
354     my $self = shift;
355    
356     # automagically instantiate the object if not there
357     # TODO: do this by creating a dummy object inheriting from DesignPattern::Logger,
358     # for now this just don't work because which dummy one to take: Data::Code::Null?
359     if (! ref $self) {
360     $self = DesignPattern::Object->fromPackage('DesignPattern::Logger');
361     }
362    
363     #print "logconfig\n";
364     $self->_configure_LogDispatch();
365     }
366    
367    
368    
369     # for standalone use
370     sub new { my $class = shift; my $self = {}; bless $self, $class; }
371    
372     # convenient shortcuts
373     # FIXME: create these automagically by mungling with symbolic references
374     # or: make this object tied to recieve kinda events on method calls
375    
376     sub debug {
377     my $self = shift;
378     my $message = shift;
379     $self->log($message, 'debug');
380     }
381    
382     sub warning {
383     my $self = shift;
384     my $message = shift;
385     $self->log($message, 'warning');
386     }
387    
388     sub info {
389     my $self = shift;
390     my $message = shift;
391     $self->log($message, 'info');
392     }
393    
394     sub notice {
395     my $self = shift;
396     my $message = shift;
397     $self->log($message, 'notice');
398     }
399    
400    
401    
402     =pod
403    
404     =head1 TODO
405    
406     o $TRACE_STACK_LEVELS (traces stack history)
407     o $ENABLE_DEBUG (en-/disables level 'debug')
408     o $ENABLE_LOG (en-/disables logging completely)
409    
410    
411     =cut
412    
413 joko 1.1
414     1;
415     __END__

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed