1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- package Trog::Log::DBI;
- use strict;
- use warnings;
- use parent qw{Log::Dispatch::DBI};
- use Ref::Util qw{is_arrayref};
- use Capture::Tiny qw{capture_merged};
- use POSIX qw{mktime};
- use POSIX::strptime qw{strptime};
- our ($referer, $ua, $urchin);
- sub create_statement {
- my $self = shift;
- # This is a writable view. Consult schema for its behavior.
- my $sql = "INSERT INTO all_requests (uuid, date, ip_address, user, method, route, referer, ua, code) VALUES (?,?,?,?,?,?,?,?,?)";
- my $sql2 = "INSERT INTO messages (uuid, message) VALUES (?,?)";
- $self->{sth2} = $self->{dbh}->prepare($sql2);
- my $sql3 = "INSERT INTO urchin_requests (request_uuid, utm_source, utm_medium, utm_campaign, utm_term, utm_content) VALUES (?,?,?,?,?,?)";
- $self->{sth3} = $self->{dbh}->prepare($sql3);
- return $self->{dbh}->prepare($sql);
- }
- my %buffer;
- sub log_message {
- my ($self, %params) = @_;
- # Rip apart the message. If it's got any extended info, lets grab that too.
- my $msg = $params{message};
- my $message;
- my ($date, $uuid, $ip, $user, $method, $code, $route) = $msg =~ m!^([\w|\-|:]+) \[INFO\]: RequestId ([\w|\-]+) From ([\w|\.|:]+) \|(\w+)\| (\w+) (\d+) (.+)!;
- # Otherwise, let's mark it down in the "messages" table. This will be deferred until the final write.
- if (!$date) {
- ($date, $uuid, $ip, $user, $message) = $msg =~ m!^([\w|\-|:]+) \[\w+\]: RequestId ([\w|\-]+) From ([\w|\.|:]+) \|(\w+)\| (.+)!;
- $buffer{$uuid} //= [];
- push(@{$buffer{$uuid}}, $message);
- return 1;
- }
- # If this is a mangled log, forget it.
- return unless $date && $uuid;
- # 2024-01-20T22:37:41Z
- # Transform the date into an epoch so we can do math on it
- my $fmt = "%Y-%m-%dT%H:%M:%SZ";
- my @cracked = strptime($date, $fmt);
- #XXX get a dumb warning otherwise
- pop @cracked;
- my $epoch = mktime(@cracked);
- # Allow callers to set quasi-tracking parameters.
- # We only care about this in DB context, as it's only for metrics, which are irrelevant in text logs/debugging.
- $referer //= 'none';
- $ua //= 'none';
- $urchin //= {};
- my $res = $self->{sth}->execute($uuid, $epoch, $ip, $user, $method, $route, $referer, $ua, $code );
- # Dump in the accumulated messages
- if (is_arrayref($buffer{$uuid}) && @{$buffer{$uuid}}) {
- $self->{sth2}->bind_param_array(1, $uuid);
- $self->{sth2}->bind_param_array(2, $buffer{$uuid});
- $self->{sth2}->execute_array({});
- delete $buffer{$uuid};
- }
- # Record urchin data if there is any.
- if (%$urchin && $urchin->{utm_source}) {
- $self->{sth3}->execute($uuid, $urchin->{utm_source}, $urchin->{utm_medium}, $urchin->{utm_campaign}, $urchin->{utm_term}, $urchin->{utm_content});
- }
- return $res;
- }
- 1;
|