1# $Id: /mirror/gungho/lib/Gungho/Log/Dispatch.pm 31120 2007-11-26T13:23:50.152702Z lestrrat $ 2# 3# Copyright (c) 2007 Daisuke Maki <daisuke@endeworks.jp> 4# All rights reserved. 5 6package Gungho::Log::Dispatch; 7use strict; 8use warnings; 9use base qw(Gungho::Log); 10use Log::Dispatch; 11 12__PACKAGE__->mk_accessors($_) for qw(dispatch); 13 14BEGIN 15{ 16 foreach my $level qw(debug info notice warning error critical alert emergency) { 17 eval "sub $level { shift->dispatch->$level(\@_) }"; die if $@; 18 } 19} 20 21sub setup 22{ 23 my $self = shift; 24 my $c = shift; 25 26 $self->next::method($c); 27 28 my $config = $self->config || {}; 29 my $list = $config->{logs}; 30 31 if ($list && ref $list ne 'ARRAY') { 32 $list = [ $list ]; 33 } 34 35 my %args = (); 36 if (my $callbacks = $config->{callbacks}) { 37 if (ref $callbacks ne 'ARRAY') { 38 $callbacks = [ $callbacks ]; 39 } 40 foreach my $name (@$callbacks) { 41 my $cb = ref $name eq 'CODE' ? $name : do { 42 no strict 'refs'; 43 \&{$name}; 44 }; 45 if ($cb) { 46 $args{callbacks} ||= []; 47 push @{ $args{callbacks} }, $cb; 48 } 49 } 50 } 51 if (! $args{callbacks}) { 52 $args{callbacks} = sub { 53 my %args = @_; 54 my $message = $args{message}; 55 if ($message !~ /\n$/) { 56 $message =~ s/$/\n/; 57 } 58 return sprintf('[%s:%s] %s', $args{level}, $$, $message); 59 }; 60 } 61 if ($c->config->{debug}) { 62 $args{min_level} = 'debug'; 63 } else { 64 $args{min_level} ||= 'critical'; 65 } 66 $args{min_level} ||= $c->config->{debug} ? 'debug' : 'critical'; 67 my $dispatch = Log::Dispatch->new(%args); 68 foreach my $config (map { +{ %$_ } } @$list) { 69 my $module = delete $config->{module} || die "no module specified"; 70 if ($module !~ s/^\+//) { 71 $module = "Log::Dispatch::$module"; 72 } 73 Class::Inspector->loaded($module) || $module->require || die "Could not load module $module"; 74 if ($c->config->{debug}) { 75 $config->{min_level} = 'debug'; 76 } else { 77 $config->{min_level} ||= $args{min_level}; 78 } 79 $dispatch->add( $module->new(%$config) ); 80 } 81 $self->dispatch($dispatch); 82} 83 841; 85 86__END__ 87 88=head1 NAME 89 90Gungho::Log::Dispatch - Log::Dispatch-Based Log For Gungho 91 92=head1 SYNOPSIS 93 94 # in your Gungho config 95 log: 96 module: Dispatch 97 config: 98 logs: 99 - module: Screen 100 min_level: debug 101 name: stderr 102 stderr: 1 103 - module: File 104 min_level: info 105 filename: /path/tofilename 106 mode: append 107 108 # ... or somewhere in your code .. 109 use Gungho::Log::Dispatch; 110 111 my $log = Gungho::Log::Dispatch->new(); 112 $log->setup($c, { 113 logs => [ 114 { module => 'Screen', 115 min_level => 'debug', 116 name => 'stderr', 117 stderr => 1 118 }, 119 { module => 'File', 120 min_level => 'info', 121 filename => '/path/to/filename' 122 mode => 'append' 123 } 124 ] 125 }); 126 127=head1 DESCRIPTION 128 129This is the main log class for Gungho. It gives you the full power of 130Log::Dispatch for your needs. 131 132To use, specify something like this in your config: 133 134 log: 135 module: Dispatch 136 config: 137 logs: 138 - module: File 139 min_level: info 140 filename: /path/to/filename 141 name: logfile 142 143Each entry in the C<logs> section specifies one Log::Dispatch type. The 144C<module> parameter is taken as the Log::Dispatch subclass name, and it will 145be prefixed with the string "Log::Dispatch::". All other parameters are 146passed directly to the constructor. 147 148You may specify multiple logs to be added to the Log::Dispatch object. 149See the documentation for Log::Dispatch for details. 150 151To log, access the log object from $c: 152 153 $c->log->debug("This is a debug message"); 154 $c->log->emergency("This is an emergency message"); 155 156=head1 CAVEATS 157 158Do NOT use Log::Dispatch::File::Locked if you're running Gungho in a 159multi-process environment. It's obvious if you think about it, but this is a 160hard-to-debug problem because File::Locked will simply sit on its flock() 161wait while 1 Gungho process will merrily go processing requests. 162 163=head1 METHODS 164 165=head2 setup($c, \%config) 166 167Sets up the module 168 169=head2 debug 170 171=head2 info 172 173=head2 notice 174 175=head2 warning 176 177=head2 error 178 179=head2 critical 180 181=head2 alert 182 183=head2 emergency 184 185Logs to each level 186 187=cut