[Jifty-commit] r4632 - in jifty/trunk: lib/Jifty/Plugin
lib/Jifty/Plugin/Queries
jifty-commit at lists.jifty.org
jifty-commit at lists.jifty.org
Thu Dec 6 19:20:54 EST 2007
Author: sartak
Date: Thu Dec 6 19:20:53 2007
New Revision: 4632
Added:
jifty/trunk/lib/Jifty/Plugin/Queries/
jifty/trunk/lib/Jifty/Plugin/Queries.pm
jifty/trunk/lib/Jifty/Plugin/Queries/Dispatcher.pm
jifty/trunk/lib/Jifty/Plugin/Queries/View.pm
Modified:
jifty/trunk/ (props changed)
Log:
r48738 at onn: sartak | 2007-12-06 19:20:22 -0500
Add a Queries plugin for examining the db queries made by your app
Added: jifty/trunk/lib/Jifty/Plugin/Queries.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/lib/Jifty/Plugin/Queries.pm Thu Dec 6 19:20:53 2007
@@ -0,0 +1,133 @@
+#!/usr/bin/env perl
+package Jifty::Plugin::Queries;
+use base qw/Jifty::Plugin/;
+use strict;
+use warnings;
+
+our @requests;
+
+=head1 NAME
+
+Jifty::Plugin::Queries
+
+=head1 DESCRIPTION
+
+Query logging and reporting for your Jifty app
+
+=head1 USAGE
+
+Add the following to your site_config.yml
+
+ framework:
+ Plugins:
+ - Queries: {}
+
+This makes the following URLs available:
+
+View the top-level query report (how many queries each request had)
+
+ http://your.app/queries
+
+View the top-level query report, including zero-query requests
+
+ http://your.app/queries/all
+
+View an individual request's detailed query report (which queries were made,
+where, how long they took, etc)
+
+ http://your.app/queries/3
+
+=head2 init
+
+This makes sure that each request is wrapped with query logging.
+
+=cut
+
+sub init {
+ my $self = shift;
+ return if $self->_pre_init;
+
+ Jifty->add_trigger(
+ post_init => \&post_init
+ );
+
+ Jifty::Handler->add_trigger(
+ before_request => \&before_request
+ );
+
+ Jifty::Handler->add_trigger(
+ after_request => \&after_request
+ );
+}
+
+=head2 post_init
+
+This sets up L<Jifty::DBI>'s query logging, and is called at the end of
+C<< Jifty->new >>
+
+=cut
+
+sub post_init {
+ Jifty->handle or return;
+
+ require Carp;
+
+ Jifty->handle->log_sql_statements(1);
+ Jifty->handle->log_sql_hook(QueryPlugin => sub { Carp::longmess });
+}
+
+=head2 before_request
+
+Clears the SQL log so you only get the request's queries
+
+=cut
+
+sub before_request {
+ Jifty->handle or return;
+
+ Jifty->handle->clear_sql_statement_log();
+}
+
+=head2 after_request
+
+Logs the queries made (at level DEBUG)
+
+=cut
+
+sub after_request {
+ Jifty->handle or return;
+
+ my $handler = shift;
+ my $cgi = shift;
+
+ my $total_time = 0;
+ my @log = Jifty->handle->sql_statement_log();
+ for (@log) {
+ my ($time, $statement, $bindings, $duration, $results) = @$_;
+
+ Jifty->log->debug(sprintf 'Query (%.3fs): "%s", with bindings: %s',
+ $duration,
+ $statement,
+ join ', ', @$bindings);
+ $total_time += $duration;
+ }
+
+ push @requests, {
+ id => 1 + @requests,
+ duration => $total_time,
+ url => $cgi->url(-absolute=>1,-path_info=>1),
+ time => scalar gmtime,
+ queries => \@log,
+ };
+}
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2007 Best Practical Solutions
+
+This is free software and may be modified and distributed under the same terms as Perl itself.
+
+=cut
+
+1;
+
Added: jifty/trunk/lib/Jifty/Plugin/Queries/Dispatcher.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/lib/Jifty/Plugin/Queries/Dispatcher.pm Thu Dec 6 19:20:53 2007
@@ -0,0 +1,48 @@
+package Jifty::Plugin::Queries::Dispatcher;
+use warnings;
+use strict;
+
+use Jifty::Dispatcher -base;
+
+# http://your.app/queries -- display full query report
+on '/queries' => run {
+ set 'skip_zero' => 1;
+ show "/queries/all";
+};
+
+# http://your.app/queries/all -- full query report with non-query requests
+on '/queries/all' => run {
+ set 'skip_zero' => 0;
+ show "/queries/all";
+};
+
+# http://your.app/queries/clear -- clear query log
+on '/queries/clear' => run {
+ @Jifty::Plugin::Queries::requests = ();
+ set 'skip_zero' => 1;
+ redirect "/queries";
+};
+
+# http://your.app/queries/xxx -- display query report for request ID xxx
+on '/queries/#' => run {
+ abort(404) if $1 < 1;
+ my $query = $Jifty::Plugin::Queries::requests[$1 - 1]
+ or abort(404);
+ set query => $query;
+ show "/queries/one";
+};
+
+=head1 SEE ALSO
+
+L<Jifty::Plugin::Queries>, L<Jifty::Plugin::Queries::View>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2007 Best Practical Solutions
+
+This is free software and may be modified and distributed under the same terms as Perl itself.
+
+=cut
+
+1;
+
Added: jifty/trunk/lib/Jifty/Plugin/Queries/View.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/lib/Jifty/Plugin/Queries/View.pm Thu Dec 6 19:20:53 2007
@@ -0,0 +1,108 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::Queries::View;
+use Jifty::View::Declare -base;
+use Scalar::Util 'blessed';
+
+=head1 NAME
+
+Jifty::Plugin::Queries::View - Views for database queries
+
+=head1 TEMPLATES
+
+template '/queries/all' => sub {
+ my $skip_zero = get 'skip_zero';
+
+ html {
+ body {
+ h1 { "Queries" }
+ p {
+ if ($skip_zero) {
+ a { attr { href => "/queries/all" }
+ "Show zero-query requests" }
+ }
+ else {
+ a { attr { href => "/queries" }
+ "Hide zero-query requests" }
+ }
+ a { attr { href => "/queries/clear" }
+ "Clear query log" }
+ }
+ hr {}
+
+ table {
+ row {
+ th { "ID" }
+ th { "Queries" }
+ th { "Time taken" }
+ th { "URL" }
+ };
+
+ for (@Jifty::Plugin::Queries::requests)
+ {
+ next if $skip_zero && @{ $_->{queries} } == 0;
+
+ row {
+ cell { a { attr { href => "/queries/$_->{id}" }
+ $_->{id} } }
+
+ cell { scalar @{ $_->{queries} } }
+ cell { $_->{duration} }
+ cell { $_->{url} }
+ };
+ }
+ }
+ }
+ }
+};
+
+template '/queries/one' => sub {
+ my $query = get 'query';
+
+ html {
+ body {
+ h1 { "Queries from Request $query->{id}" }
+ ul {
+ li { "URL: $query->{url}" }
+ li { "At: " . $query->{time} }
+ li { "Time taken: $query->{duration}" }
+ li { "Queries made: " . @{ $query->{queries} } }
+ }
+ p { a { attr { href => "/queries" } "Table of Contents" } };
+
+ for ( @{ $query->{queries} } ) {
+ my ($time, $statement, $bindings, $duration, $misc) = @$_;
+ hr {};
+ h4 { pre { $statement } };
+ ul {
+ li { "At: " . gmtime($time) };
+ li { "Time taken: $duration" };
+ }
+ h5 { "Bindings:" }
+ ol {
+ li { $_ } for @$bindings;
+ }
+ h5 { "Stack trace:" }
+ pre {
+ $misc->{QueryPlugin};
+ }
+ }
+ }
+ }
+};
+
+=head1 SEE ALSO
+
+L<Jifty::Plugin::Queries>, L<Jifty::Plugin::Queries::Dispatcher>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2007 Best Practical Solutions
+
+This is free software and may be modified and distributed under the same terms as Perl itself.
+
+=cut
+
+1;
+
More information about the Jifty-commit
mailing list