diff --git a/lib/BurguillosInfo/Controller/Metrics.pm b/lib/BurguillosInfo/Controller/Metrics.pm index 05ed9e8..2d0ebd2 100644 --- a/lib/BurguillosInfo/Controller/Metrics.pm +++ b/lib/BurguillosInfo/Controller/Metrics.pm @@ -37,8 +37,10 @@ sub stats { } my $data = $tracking->get_global_data($self); my $data_per_url = $tracking->get_data_for_urls($self); + my $google_data = $tracking->get_google_data($self); $self->_filter_data_per_url($data_per_url); - $self->render(tracking_data => $data, tracking_by_url => $data_per_url); + $self->_filter_data_per_url($google_data); + $self->render(tracking_data => $data, tracking_by_url => $data_per_url, google_data => $google_data); } sub _filter_data_per_url($self, $data_per_url) { diff --git a/lib/BurguillosInfo/DB/Migrations.pm b/lib/BurguillosInfo/DB/Migrations.pm index 0bfb85f..a860028 100644 --- a/lib/BurguillosInfo/DB/Migrations.pm +++ b/lib/BurguillosInfo/DB/Migrations.pm @@ -6,29 +6,31 @@ use strict; use warnings; sub MIGRATIONS { - return ( - 'CREATE TABLE options ( - name TEXT PRIMARY KEY, - value TEXT - )', - 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp"', - 'CREATE TABLE paths ( - path TEXT PRIMARY KEY, - first_seen timestamp DEFAULT NOW() - )', - 'CREATE TABLE requests ( - uuid UUID DEFAULT uuid_generate_v4(), - remote_address TEXT NOT NULL, - user_agent TEXT NOT NULL, - params JSON NOT NULL, - date timestamp DEFAULT NOW(), - path TEXT, - FOREIGN KEY (path) REFERENCES paths(path) - )', + return ( + 'CREATE TABLE options ( + name TEXT PRIMARY KEY, + value TEXT + )', + 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp"', + 'CREATE TABLE paths ( + path TEXT PRIMARY KEY, + first_seen timestamp DEFAULT NOW() + )', + 'CREATE TABLE requests ( + uuid UUID DEFAULT uuid_generate_v4(), + remote_address TEXT NOT NULL, + user_agent TEXT NOT NULL, + params JSON NOT NULL, + date timestamp DEFAULT NOW(), + path TEXT, + FOREIGN KEY (path) REFERENCES paths(path) + )', 'ALTER TABLE paths ADD column last_seen TIMESTAMP;', 'ALTER TABLE paths ALTER COLUMN last_seen SET DEFAULT NOW();', 'ALTER TABLE requests ADD PRIMARY KEY (uuid)', 'CREATE INDEX request_extra_index on requests (date, path);', - ); + 'ALTER TABLE requests ADD column referer text;', + 'CREATE INDEX request_referer_index on requests (referer);', + ); } 1; diff --git a/lib/BurguillosInfo/Tracking.pm b/lib/BurguillosInfo/Tracking.pm index b92fc78..0df9b18 100644 --- a/lib/BurguillosInfo/Tracking.pm +++ b/lib/BurguillosInfo/Tracking.pm @@ -19,7 +19,6 @@ SELECT COUNT(DISTINCT (remote_address, user_agent)) FROM requests EOF - sub new { my $class = shift; $app = shift; @@ -27,7 +26,7 @@ sub new { return bless {}, $class; } -sub _add_path($self, $url) { +sub _add_path ( $self, $url ) { my $dbh = BurguillosInfo::DB->connect($app); $dbh->do( <<'EOF', undef, $url ); INSERT INTO paths (path) VALUES($1) @@ -36,9 +35,9 @@ ON CONFLICT (path) DO EOF } -sub _update_null_last_seen_paths_if_any($self) { +sub _update_null_last_seen_paths_if_any ($self) { my $dbh = BurguillosInfo::DB->connect($app); - $dbh->do( <<'EOF', undef); + $dbh->do( <<'EOF', undef ); UPDATE paths SET last_seen = requests_for_path.last_date @@ -51,12 +50,14 @@ WHERE paths.last_seen IS NULL AND requests_for_path.path = paths.path; EOF } -sub _register_request_query($self, $remote_address, $user_agent, $params_json, $path) { +sub _register_request_query ( $self, $remote_address, $user_agent, + $params_json, $path, $referer ) +{ my $dbh = BurguillosInfo::DB->connect($app); $dbh->do( - <<'EOF', undef, $remote_address, $user_agent, $params_json, $path ); -INSERT INTO requests(remote_address, user_agent, params, path) - VALUES (?, ?, ?, ?); + <<'EOF', undef, $remote_address, $user_agent, $params_json, $path, $referer ); +INSERT INTO requests(remote_address, user_agent, params, path, referer) + VALUES (?, ?, ?, ?, ?); EOF } @@ -64,78 +65,121 @@ sub register_request { my $self = shift; my $c = shift; my $path = $c->req->url->path; - my $dbh = BurguillosInfo::DB->connect($app); + my $dbh = BurguillosInfo::DB->connect($app); $self->_add_path($path); $self->_update_null_last_seen_paths_if_any(); my $remote_address = $c->tx->remote_address; my $user_agent = $c->req->headers->user_agent; + my $referer = $c->req->headers->referer // ''; my $params_json = encode_json( $c->req->params->to_hash ); - $self->_register_request_query($remote_address, $user_agent, $params_json, $path); - say "Registered $remote_address with user agent $user_agent visited $path with $params_json"; + $self->_register_request_query( $remote_address, $user_agent, $params_json, + $path, $referer ); + say +"Registered $remote_address with user agent $user_agent visited $path with $params_json"; } - sub get_global_data { - my $self = shift; - my $c = shift; - my $app = $c->app; - my $dbh = BurguillosInfo::DB->connect($app); - my $data = $dbh->selectrow_hashref(<<"EOF", undef); +sub get_global_data { + my $self = shift; + my $c = shift; + my $app = $c->app; + my $dbh = BurguillosInfo::DB->connect($app); + my $data = $dbh->selectrow_hashref( <<"EOF", undef ); SELECT - ( - $SELECT_GLOBAL - where date > NOW() - interval '1 day' - ) as unique_ips_last_24_hours, - ( - $SELECT_GLOBAL - where date > NOW() - interval '1 week' - ) as unique_ips_last_week, - ( - $SELECT_GLOBAL - where date > NOW() - interval '1 month' - ) as unique_ips_last_month; + ( + $SELECT_GLOBAL + where date > NOW() - interval '1 day' + ) as unique_ips_last_24_hours, + ( + $SELECT_GLOBAL + where date > NOW() - interval '1 week' + ) as unique_ips_last_week, + ( + $SELECT_GLOBAL + where date > NOW() - interval '1 month' + ) as unique_ips_last_month; EOF - return $data; - } + return $data; +} - sub get_data_for_urls { - my $self = shift; - my $c = shift; - my $app = $c->app; - my $dbh = BurguillosInfo::DB->connect($app); - my $data = $dbh->selectall_arrayref(<<"EOF", {Slice => {}}); -SELECT paths.path, - ( - $SELECT_GLOBAL - where requests.path = paths.path and date > NOW() - interval '1 hour' - ) as unique_ips_last_1_hour, - ( - $SELECT_GLOBAL - where requests.path = paths.path and date > NOW() - interval '3 hour' - ) as unique_ips_last_3_hours, - ( - $SELECT_GLOBAL - where requests.path = paths.path and date > NOW() - interval '6 hour' - ) as unique_ips_last_6_hours, - ( - $SELECT_GLOBAL - where requests.path = paths.path and date > NOW() - interval '12 hour' - ) as unique_ips_last_12_hours, - ( - $SELECT_GLOBAL - where requests.path = paths.path and date > NOW() - interval '1 day' - ) as unique_ips_last_24_hours, - ( - $SELECT_GLOBAL - where requests.path = paths.path and date > NOW() - interval '1 week' - ) as unique_ips_last_week, - ( - $SELECT_GLOBAL - where requests.path = paths.path and date > NOW() - interval '1 month' - ) as unique_ips_last_month +my $GOOGLE_SELECT = "$SELECT_GLOBAL +where requests.path = paths.path + and requests.referer IS NOT NULL + and requests.referer ~* '^https?://(?:www\\.)?google\\.\\w' + and date > NOW()"; + +sub get_google_data { + my $self = shift; + my $c = shift; + my $app = $c->app; + my $dbh = BurguillosInfo::DB->connect($app); + my $data = $dbh->selectall_arrayref(<<"EOF", { Slice => {} } ); + SELECT paths.path, + ( + $GOOGLE_SELECT - interval '1 hour' + ) as unique_ips_last_1_hour, + ( + $GOOGLE_SELECT - interval '3 hour' + ) as unique_ips_last_3_hours, + ( + $GOOGLE_SELECT - interval '6 hour' + ) as unique_ips_last_6_hours, + ( + $GOOGLE_SELECT - interval '12 hour' + ) as unique_ips_last_12_hours, + ( + $GOOGLE_SELECT - interval '1 day' + ) as unique_ips_last_24_hours, + ( + $GOOGLE_SELECT - interval '1 week' + ) as unique_ips_last_week, + ( + $GOOGLE_SELECT - interval '1 month' + ) as unique_ips_last_month FROM paths WHERE paths.last_seen > NOW() - INTERVAL '1 month'; EOF - return $data; + return $data; +} + +sub get_data_for_urls { + my $self = shift; + my $c = shift; + my $app = $c->app; + my $dbh = BurguillosInfo::DB->connect($app); + my $data = $dbh->selectall_arrayref( <<"EOF", { Slice => {} } ); +SELECT paths.path, + ( + $SELECT_GLOBAL + where requests.path = paths.path and date > NOW() - interval '1 hour' + ) as unique_ips_last_1_hour, + ( + $SELECT_GLOBAL + where requests.path = paths.path and date > NOW() - interval '3 hour' + ) as unique_ips_last_3_hours, + ( + $SELECT_GLOBAL + where requests.path = paths.path and date > NOW() - interval '6 hour' + ) as unique_ips_last_6_hours, + ( + $SELECT_GLOBAL + where requests.path = paths.path and date > NOW() - interval '12 hour' + ) as unique_ips_last_12_hours, + ( + $SELECT_GLOBAL + where requests.path = paths.path and date > NOW() - interval '1 day' + ) as unique_ips_last_24_hours, + ( + $SELECT_GLOBAL + where requests.path = paths.path and date > NOW() - interval '1 week' + ) as unique_ips_last_week, + ( + $SELECT_GLOBAL + where requests.path = paths.path and date > NOW() - interval '1 month' + ) as unique_ips_last_month +FROM paths +WHERE paths.last_seen > NOW() - INTERVAL '1 month'; +EOF + return $data; } 1; diff --git a/templates/metrics/stats.html.ep b/templates/metrics/stats.html.ep index 4409907..482da25 100644 --- a/templates/metrics/stats.html.ep +++ b/templates/metrics/stats.html.ep @@ -32,4 +32,30 @@ %} +

Google data.

+ + + + + + + + + + + +% for my $row (@$google_data) { + + + + + + + + + + +%} +
PathVisitors 1hVisitors 3hVisitors 6hVisitors 12hVisitors 24hVisitors weekVisitors month
<%="${base_url}$row->{path}"%><%=$row->{unique_ips_last_1_hour}%><%=$row->{unique_ips_last_3_hours}%><%=$row->{unique_ips_last_6_hours}%><%=$row->{unique_ips_last_12_hours}%><%=$row->{unique_ips_last_24_hours}%><%=$row->{unique_ips_last_week}%><%=$row->{unique_ips_last_month}%>
+