package App::Office::CMS::Util::Logger;
use strict;
use warnings;
use Log::Handler;
use Moo;
use Types::Standard qw/Any Str/;
# We don't use:
# extends 'App::Office::CSM::Database::Base';
# because our sub log is different.
has creator =>
(
is => 'rw',
isa => Any,
);
has db =>
(
is => 'rw',
isa => Any,
);
has engine =>
(
is => 'rw',
isa => Str,
);
has logger =>
(
is => 'rw',
isa => Any,
);
has time_option =>
(
is => 'rw',
isa => Str,
);
our $VERSION = '0.93';
# -----------------------------------------------
sub BUILD
{
my($self) = @_;
my($config) = $self -> db -> config;
# Because SQLite won't allow the logger -> add() without
# the log table having been created, we ensure that it is.
$self -> create_log_table_if_necessary;
$self -> logger(Log::Handler -> new);
# We just need driver for Log::Hanlder V 0.68 and below, which cause an uninitialized warning
# when the driver option is not set.
# Expected format of dsn: dbi:Pg:dbname=cms.
(my($driver) = $$config{dsn}) =~ s/^.+?:(.+?):.+$/$1/;
$self -> logger -> add
(
dbi =>
{
columns => [qw/level message/],
data_source => $$config{dsn},
driver => $driver,
maxlevel => $$config{max_log_level},
message_pattern => [qw/%L %m/],
message_layout => '%m',
minlevel => $$config{min_log_level},
newline => 0,
password => $$config{password},
persistent => 0,
table => 'log',
user => $$config{username},
values => [qw/%level %message/],
});
} # End of BUILD.
# --------------------------------------------------
# Warning: Duplicate from from Database.pm.
sub create_log_table
{
my($self) = @_;
my($table_name) = 'log';
my($primary_key) = $self -> creator -> generate_primary_key_sql($table_name);
my($engine) = $self -> engine;
my($time_option) = $self -> time_option;
my($result) = $self -> creator -> create_table(<<SQL);
create table $table_name
(
id $primary_key,
level varchar(9) not null,
message varchar(255) not null,
timestamp timestamp $time_option not null default current_timestamp
) $engine
SQL
} # End of create_log_table.
# -----------------------------------------------
sub create_log_table_if_necessary
{
my($self) = @_;
my($table_sth) = $self -> db -> dbh -> table_info(undef, undef, '%', 'TABLE');
my($count);
my($table_data, $table_name, %table_name);
for $table_data (@{$table_sth -> fetchall_arrayref({})})
{
$table_name{$$table_data{TABLE_NAME} } = 1;
}
if (! $table_name{log})
{
require DBIx::Admin::CreateTable;
$self -> creator(DBIx::Admin::CreateTable -> new(dbh => $self -> db -> dbh, verbose => 0) );
$self -> engine($self -> creator -> db_vendor =~ /(?:Mysql)/i ? 'engine=innodb' : '');
$self -> time_option($self -> creator -> db_vendor =~ /(?:Postgres)/i ? '(0) without time zone' : '');
$self -> create_log_table;
}
} # End of create_log_table_if_necessary.
# -----------------------------------------------
# This is adapted from App::Office::CMS::Controller.
sub log
{
my($self, $level, $s) = @_;
$level ||= 'info';
$self -> logger -> $level($s || '');
} # End of log.
# --------------------------------------------------
1;