/[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.5 - (hide annotations)
Tue May 13 08:40:15 2003 UTC (21 years ago) by joko
Branch: MAIN
Changes since 1.4: +5 -2 lines
minor update: renamed attribute

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

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