Permalink
Browse files

Added logging support via Log::Any; now requires Log::Any.

  • Loading branch information...
1 parent 68b1ddd commit 525d430f3d760001092e11cf1ecffe2240e6a899 @rizen rizen committed Mar 3, 2010
Showing with 39 additions and 14 deletions.
  1. +3 −1 Changes
  2. +2 −2 dist.ini
  3. +27 −5 lib/JSON/RPC/Dispatcher.pm
  4. +7 −6 lib/JSON/RPC/Dispatcher/App.pm
View
@@ -1,7 +1,9 @@
0.0400 2010-03-03
- - Output stack trace on unhandled exceptions.
- Added exception handling for when procs don't throw exceptions, but also don't return valid content.
- Eliminated Sub::Name dependency.
+ - Now requires Plack 0.9913.
+ - Merged miyagawa's patch for updated Plack.
+ - Added logging support via Log::Any; now requires Log::Any.
0.0300 2009-12-28
- Got rid of the notion of "advanced" methods in favor of a cleaner way to throw errors.
View
@@ -7,11 +7,11 @@ copyright_holder = Plain Black Corporation
[@Classic]
[Prereq]
-Plack = 0.9023
-Plack::Request = 0.09
+Plack = 0.9913
Moose = 0.93
JSON = 2.16
Test::More = 0
+Log::Any = 0.11
[MetaNoIndex]
folder = author.t
View
@@ -6,7 +6,8 @@ JSON::RPC::Dispatcher - A JSON-RPC 2.0 server.
=head1 SYNOPSIS
- # app.psgi
+In F<app.psgi>:
+
use JSON::RPC::Dispatcher;
my $rpc = JSON::RPC::Dispatcher->new;
@@ -69,6 +70,17 @@ You can also throw error messages rather than just C<die>ing, which will throw a
B<NOTE:> If you don't care about setting error codes and just want to set an error message, you can simply C<die> in your RPC and your die message will be inserted into the C<error_data> method.
+=head2 Logging
+
+JSON::RPC::Dispatcher allows for logging via L<Log::Any>. This way you can set up logs with L<Log::Dispatch>, L<Log::Log4perl>, or any other logging system that L<Log::Any> supports now or in the future. It's relatively easy to set up. In your F<app.psgi> simply add a block like this:
+
+ use Log::Any::Adapter;
+ use Log::Log4perl;
+ Log::Log4perl::init('/path/to/log4perl.conf');
+ Log::Any::Adapter->set('Log::Log4perl');
+
+That's how easy it is to start logging. You'll of course still need to configure the F<log4perl.conf> file, which goes well beyond the scope of this document. And you'll also need to install L<Log::Any::Adapter::Log4perl> to use this example.
+
=cut
@@ -78,6 +90,7 @@ extends qw(Plack::Component);
use Plack::Request;
use JSON;
use JSON::RPC::Dispatcher::Procedure;
+use Log::Any qw($log);
#--------------------------------------------------------
has error_code => (
@@ -207,7 +220,7 @@ sub handle_procedures {
my @responses;
my $rpcs = $self->rpcs;
foreach my $proc (@{$procs}) {
- my $is_notification = ($proc->id eq '') ? 1 : 0;
+ my $is_notification = (defined $proc->id && $proc->id ne '') ? 0 : 1;
unless ($proc->has_error_code) {
my $rpc = $rpcs->{$proc->method};
if (defined $rpc) {
@@ -228,16 +241,22 @@ sub handle_procedures {
# deal with result
if ($@ && ref($@) eq 'ARRAY') {
$proc->error(@{$@});
+ $log->error($@->[1]);
+ $log->debug($@->[2]);
}
elsif ($@) {
my $error = $@;
if ($error->can('error') && $error->can('trace')) {
- $error = $error->error . "\n". $error->trace->as_string;
+ $error = $error->error;
+ $log->fatal($error->error);
+ $log->trace($error->trace->as_string);
}
elsif ($error->can('error')) {
$error = $error->error;
+ $log->fatal($error);
}
elsif (ref $error ne '' && ref $error ne 'HASH' && ref $error ne 'ARRAY') {
+ $log->fatal($error);
$error = ref $error;
}
$proc->internal_error($error);
@@ -280,6 +299,7 @@ sub call {
my ($self, $env) = @_;
my $request = Plack::Request->new($env);
+ $log->info("REQUEST: ".$request->content) if $log->is_info;
my $procs = $self->acquire_procedures($request);
my $rpc_response;
@@ -301,7 +321,7 @@ sub call {
if ($rpc_response) {
my $json = eval{to_json($rpc_response)};
if ($@) {
- warn "JSON repsonse error: ".$@;
+ $log->warn("JSON repsonse error: ".$@);
$json = to_json({
jsonrpc => "2.0",
error => {
@@ -315,9 +335,11 @@ sub call {
$response->content_type('application/json-rpc');
$response->content_length(bytes::length($json));
$response->body($json);
+ $log->info("RESPONSE: ".$response->body) if $log->is_info;
}
else { # is a notification only request
$response->status(204);
+ $log->info('RESPONSE: Notification Only');
}
return $response->finalize;
}
@@ -327,8 +349,8 @@ sub call {
L<Moose>
L<JSON>
L<Plack>
-L<Plack::Request>
L<Test::More>
+L<Log::Any>
=head1 TODO
@@ -9,7 +9,8 @@ JSON::RPC::Dispatcher::App - A base class for creating object oriented apps with
=head1 SYNOPSIS
- # create your app
+Create your module:
+
package MyApp;
use Moose;
@@ -39,7 +40,8 @@ JSON::RPC::Dispatcher::App - A base class for creating object oriented apps with
1;
- # app.psgi
+Then your plack F<app.psgi>:
+
MyApp->new->to_app;
=head1 DESCRIPTION
@@ -76,7 +78,8 @@ When you subclass you can easily add your own attributes using L<Moose>'s C<has>
1;
- # app.psgi
+In F<app.psgi>:
+
my $db = DBI->connect(...);
MyApp->new(db=>$db)->to_app;
@@ -134,6 +137,4 @@ JSON::RPC::Dispatcher is Copyright 2009-2010 Plain Black Corporation (L<http://w
=cut
-no Moose;
-__PACKAGE__->meta->make_immutable;
-
+1;

0 comments on commit 525d430

Please sign in to comment.