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