Hi! Please consider following me on twitter: @hanekomu.
2009年06月11日
Sending DBI trace output to FirePHP with HTTP::Engine
As promised last time, here is a complete example of how to send DBI trace output to FirePHP in an HTTP::Engine demo web application.
First we create a very small example SQLite database. Let's model a company
that has two departments with two employees each. Create a file called
create.sql and enter the following SQL commands:
CREATE TABLE departments (
id INTEGER PRIMARY KEY,
name TEXT
);
CREATE TABLE employees (
id INTEGER PRIMARY KEY,
name TEXT,
department_id INTEGER
);
INSERT INTO departments (id, name) VALUES (1, 'publishing');
INSERT INTO departments (id, name) VALUES (2, 'accounting');
INSERT INTO employees (id, name, department_id)
VALUES (1, 'Yamamura Masayoshi', 1);
INSERT INTO employees (id, name, department_id)
VALUES (2, 'Ueda Akira', 1);
INSERT INTO employees (id, name, department_id)
VALUES (3, 'Matsumoto Daichi', 2);
INSERT INTO employees (id, name, department_id)
VALUES (4, 'Yasuda Ryota', 2);
Now we create the database itself:
sqlite3 kaisha.db <create.sql
The web application is pretty simple as well. We create an
HTTP::Engine object and run it; the handler connects to the
database, runs a simple query, creates an HTML table from the results and sends
it in a response back to the engine.
#!/usr/bin/env perl use strict; use warnings; use DBI; use HTTP::Engine; use HTTP::Engine::FirePHP; my $engine = HTTP::Engine->new( interface => { module => 'ServerSimple', args => { host => 'localhost', port => '1984', }, request_handler => \&handler, }, )->run; sub handler { my $req = shift; my $dbh = DBI->connect('dbi:SQLite:dbname=kaisha.db', '', ''); my $res = HTTP::Engine::Response->new; $dbh->trace(2, $res->get_fire_php_fh); my $r = $dbh->selectall_arrayref(' SELECT E.name, D.name FROM employees E, departments D WHERE D.id = E.department_id '); $dbh->disconnect; my $body = "<table>\n" . (join "\n" => map { sprintf "<tr><td>%s</td><td>%s</td></tr>\n", @$_ } @$r ) . "</table>\n"; $res->status(200); $res->body($body); $res; }
The relevant command to send DBI trace output to FirePHP is:
$dbh->trace(2, $res->get_fire_php_fh);
In version 0.02, HTTP::Engine::FirePHP gives
HTTP::Engine::Response the method get_fire_php_fh,
which will return a filehandle that has been opened to a PerlIO::via::ToFirePHP layer, so you don't even need to do
that manually anymore.
With this one line, DBI knows that it should trace all calls and send the trace output to the filehandle. The trace output will automatically be put into the HTTP response headers so FirePHP can display them. Here is what the Firebug console looks like when we make a request to the server:
Tags: DBI, FirePHP, HTTP::Engine, web.
posted at: 14:54 | path: /dev | permalink | 0 comments | 0 trackbacks
Log to FirePHP via an PerlIO layer
I have released PerlIO::via::ToFirePHP. This PerlIO
layer sends everything it receives to FirePHP. When constructing a filehandle
using this layer using open(), you need to pass an object of type
FirePHP::Dispatcher that has been initialized with a
HTTP::Headers object.
use PerlIO::via::ToFirePHP; my $fire_php = FirePHP::Dispatcher->new(HTTP::Headers->new); open my $fh, '>:via(ToFirePHP)', $fire_php;
Everything you print on the filehandle will be sent to FirePHP.
A typical use of this PerlIO layer is to send DBI trace output to FirePHP:
use PerlIO::via::ToFirePHP; my $dbh = DBI->connect(...); open my $fh, '>:via(ToFirePHP)', FirePHP::Dispatcher->new($http_headers_object); $dbh->trace(2, $fh);
Now the trace output of all calls to that database handle will be sent to FirePHP.
The PerlIO layer is implemented in PerlIO::via::ToFirePHP
instead of just PerlIO::via::FirePHP because of a bug in
PerlIO::via in perl 5.10.0 and earlier versions. If we used just
PerlIO::via::FirePHP, we would not be able to use the shorthand
layer notation of open my $fh, ':>via(FirePHP), $fire_php.
PerlIO::via would look for a PUSHED method in
package FirePHP. There is no such method, but because FirePHP::Dispatcher has been loaded, the namespace
FirePHP has been autovivified. So PerlIO::via would
stop looking. This bug seems to be fixed in perl 5.10.1.
In the next article I will show a complete example of how to send
DBI trace output to FirePHP in an HTTP::Engine
demo web application.
posted at: 12:05 | path: /dev | permalink | 1 comment | 0 trackbacks
2009年06月07日
Logging to Firefox with HTTP::Engine::FirePHP
I have released HTTP::Engine::FirePHP on CPAN; the development version is on Github.
If you are developing a web application and don't want to or can't check the error log, the traditional way is to include debug messages in the HTML page. However, this messes up the layout and mixes content with logging; the two really need to be separate.
FirePHP is a Firebug plugin which enables you to log to your Firebug Console by sending certain HTTP headers in the HTTP response. FirePHP is not just useful for PHP, though; any server-side application that can manipulate HTTP headers can log to Firebug.
The FirePHP response headers use the Wildfire protocol. The CPAN module FirePHP::Dispatcher can generate these headers.
This module then integrates FirePHP::Dispatcher with HTTP::Engine. By simply using this module,
HTTP::Engine::Response gets a fire_php() accessor
through which you can log to FirePHP.
Here is an example:
#!/usr/bin/env perl use strict; use warnings; use Data::Dumper; use HTTP::Engine; use HTTP::Engine::Response; use HTTP::Engine::FirePHP; HTTP::Engine->new( interface => { module => 'ServerSimple', args => { host => 'localhost', port => '10012', }, request_handler => sub { my $req = shift; my $res = HTTP::Engine::Response->new(body => 'Hello'); $res->fire_php->info('Hello from HTTP::Engine'); $res->fire_php->warn(sprintf 'path was %s', $req->uri->path); $res->fire_php->log(Dumper $req); $res; }, }, )->run;
When you load the response into Firefox, open the Firebug Console and you will find the logged messages there.
When you restart the HTTP::Engine-based server, be sure to do a
shift-reload of the relevant page in Firefox; this ensures that headers aren't
cached. If you don't do this, you might see remnant headers from previous
responses.
Tags: FirePHP, HTTP::Engine, web.
posted at: 14:54 | path: /dev | permalink | 0 comments | 0 trackbacks
2009年05月02日
Perlbal article
As spotted by Korean Perl hacker @saillinux, there is an article called "The Juggler: Scaling your website with the Perlbal web server" about the reverse proxy load balancer and web server Perlbal in PDF format; it was published by Linux Magazine in November 2007.
Tags: web.
posted at: 17:21 | path: /misc | permalink | 0 comments | 0 trackbacks

