Mail-MtPolicyd
view release on metacpan or search on metacpan
lib/Mail/MtPolicyd/Plugin/Accounting.pm view on Meta::CPAN
}
has '_single_table_create' => ( is => 'ro', isa => 'HashRef', lazy => 1,
default => sub { {
'mysql' => 'CREATE TABLE %TABLE_NAME% (
`id` int(11) NOT NULL AUTO_INCREMENT,
`key` VARCHAR(255) NOT NULL,
`time` VARCHAR(255) NOT NULL,
`count` INT UNSIGNED NOT NULL,
`count_rcpt` INT UNSIGNED NOT NULL,
`size` INT UNSIGNED NOT NULL,
`size_rcpt` INT UNSIGNED NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `time_key` (`key`, `time`),
KEY(`key`),
KEY(`time`)
) ENGINE=%MYSQL_ENGINE% DEFAULT CHARSET=latin1',
'SQLite' => 'CREATE TABLE %TABLE_NAME% (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`key` VARCHAR(255) NOT NULL,
`time` VARCHAR(255) NOT NULL,
`count` INT UNSIGNED NOT NULL,
`count_rcpt` INT UNSIGNED NOT NULL,
`size` INT UNSIGNED NOT NULL,
`size_rcpt` INT UNSIGNED NOT NULL
)',
} }
);
sub get_table_name {
my ( $self, $field ) = @_;
return( $self->table_prefix . $field );
}
has '_table_definitions' => ( is => 'ro', isa => 'HashRef', lazy => 1,
default => sub {
my $self = shift;
my $tables = {};
foreach my $field ( @{$self->_fields} ) {
my $table_name = $self->get_table_name($field);
$tables->{$table_name} = $self->_single_table_create;
}
return $tables;
},
);
sub get_request_metrics {
my ( $self, $r ) = @_;
my $recipient_count = $r->attr('recipient_count');
my $size = $r->attr('size');
my $metrics = {};
my $rcpt_cnt = defined $recipient_count ? $recipient_count : 1;
$metrics->{'size'} = defined $size ? $size : 0;
$metrics->{'count'} = 1;
$metrics->{'count_rcpt'} = $rcpt_cnt ? $rcpt_cnt : 1;
$metrics->{'size_rcpt'} = $rcpt_cnt ? $size * $rcpt_cnt : $size;
return( $metrics );
}
sub update_accounting {
my ( $self, $field, $key, $metrics ) = @_;
eval {
$self->update_accounting_row($field, $key, $metrics);
};
if( $@ =~ /^accounting row does not exist/ ) {
$self->insert_accounting_row($field, $key, $metrics);
} elsif( $@ ) {
die( $@ );
}
return;
}
sub insert_accounting_row {
my ( $self, $field, $key, $metrics ) = @_;
my $dbh = $self->_db_handle;
my $table_name = $dbh->quote_identifier( $self->get_table_name($field) );
my $values = {
'key' => $key,
'time' => $self->get_timekey,
%$metrics,
};
my $col_str = join(', ', map {
$dbh->quote_identifier($_)
} keys %$values);
my $values_str = join(', ', map {
$dbh->quote($_)
} values %$values);
my $sql = "INSERT INTO $table_name ($col_str) VALUES ($values_str)";
$self->execute_sql($sql);
return;
}
sub update_accounting_row {
my ( $self, $field, $key, $metrics ) = @_;
my $dbh = $self->_db_handle;
my $table_name = $dbh->quote_identifier( $self->get_table_name($field) );
my $where = {
'key' => $key,
'time' => $self->get_timekey,
};
my $values_str = join(', ', map {
$dbh->quote_identifier($_).'='.
$dbh->quote_identifier($_).'+'.$dbh->quote($metrics->{$_})
} keys %$metrics);
my $where_str = join(' AND ', map {
$dbh->quote_identifier($_).'='.$dbh->quote($where->{$_})
} keys %$where );
my $sql = "UPDATE $table_name SET $values_str WHERE $where_str";
my $rows = $dbh->do($sql);
if( $rows == 0 ) {
die('accounting row does not exist');
}
return;
}
__PACKAGE__->meta->make_immutable;
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Mail::MtPolicyd::Plugin::Accounting - mtpolicyd plugin for accounting in sql tables
=head1 VERSION
version 2.05
=head1 SYNOPSIS
<Plugin acct-clients>
module = "Accounting"
# per ip and user
fields = "client_address,sasl_username"
# statistics per month
time_pattern = "%Y-%m"
table_prefix = "acct_"
</Plugin>
This will create a table acct_client_address and a table acct_sasl_username.
If a request is received containing the field the plugin will update the row
in the fields table. The key is the fields value(ip or username) and the time
string build from the time_pattern.
( run in 0.951 second using v1.01-cache-2.11-cpan-524268b4103 )