/[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.4 - (hide annotations)
Sat Mar 29 07:16:00 2003 UTC (21 years, 1 month ago) by joko
Branch: MAIN
Changes since 1.3: +5 -2 lines
minor update: changed default log-file-name to 'perl_app.log'

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

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