You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
577 lines
21 KiB
577 lines
21 KiB
7 years ago
|
package Anvil::Tools::Alert;
|
||
8 years ago
|
#
|
||
|
# This module contains methods used to handle alerts and errors.
|
||
|
#
|
||
|
|
||
|
use strict;
|
||
|
use warnings;
|
||
7 years ago
|
use Scalar::Util qw(weaken isweak);
|
||
8 years ago
|
|
||
|
our $VERSION = "3.0.0";
|
||
|
my $THIS_FILE = "Alert.pm";
|
||
|
|
||
|
### Methods;
|
||
8 years ago
|
# check_alert_sent
|
||
8 years ago
|
# error
|
||
8 years ago
|
# register_alert
|
||
8 years ago
|
|
||
|
=pod
|
||
|
|
||
|
=encoding utf8
|
||
|
|
||
|
=head1 NAME
|
||
|
|
||
7 years ago
|
Anvil::Tools::Alert
|
||
8 years ago
|
|
||
|
Provides all methods related warnings and alerts.
|
||
|
|
||
|
=head1 SYNOPSIS
|
||
|
|
||
7 years ago
|
use Anvil::Tools;
|
||
8 years ago
|
|
||
7 years ago
|
# Get a common object handle on all Anvil::Tools modules.
|
||
|
my $anvil = Anvil::Tools->new();
|
||
8 years ago
|
|
||
7 years ago
|
# Access to methods using '$anvil->Alert->X'. Example using 'find';
|
||
|
my $foo_path = $anvil->Storage->find({file => "foo"});
|
||
8 years ago
|
|
||
|
=head1 METHODS
|
||
|
|
||
|
Methods in the core module;
|
||
|
|
||
|
=cut
|
||
|
|
||
|
sub new
|
||
|
{
|
||
|
my $class = shift;
|
||
|
my $self = {};
|
||
|
|
||
|
bless $self, $class;
|
||
|
|
||
|
return ($self);
|
||
|
}
|
||
|
|
||
7 years ago
|
# Get a handle on the Anvil::Tools object. I know that technically that is a sibling module, but it makes more
|
||
8 years ago
|
# sense in this case to think of it as a parent.
|
||
|
sub parent
|
||
|
{
|
||
|
my $self = shift;
|
||
|
my $parent = shift;
|
||
|
|
||
|
$self->{HANDLE}{TOOLS} = $parent if $parent;
|
||
|
|
||
7 years ago
|
# Defend against memory leads. See Scalar::Util'.
|
||
|
if (not isweak($self->{HANDLE}{TOOLS}))
|
||
|
{
|
||
|
weaken($self->{HANDLE}{TOOLS});;
|
||
|
}
|
||
|
|
||
8 years ago
|
return ($self->{HANDLE}{TOOLS});
|
||
|
}
|
||
|
|
||
|
|
||
|
#############################################################################################################
|
||
|
# Public methods #
|
||
|
#############################################################################################################
|
||
|
|
||
|
|
||
8 years ago
|
=head2 check_alert_sent
|
||
|
|
||
|
This is used by scan agents that need to track whether an alert was sent when a sensor dropped below/rose above a set alert threshold. For example, if a sensor alerts at 20°C and clears at 25°C, this will be called when either value is passed. When passing the warning threshold, the alert is registered and sent to the user. Once set, no further warning alerts are sent. When the value passes over the clear threshold, this is checked and if an alert was previously registered, it is removed and an "all clear" message is sent. In this way, multiple alerts will not go out if a sensor floats around the warning threshold and a "cleared" message won't be sent unless a "warning" message was previously sent.
|
||
|
|
||
8 years ago
|
If there is a problem, C<< !!error!! >> is returned.
|
||
8 years ago
|
|
||
|
Parameters;
|
||
|
|
||
|
=head3 modified_date (optional)
|
||
|
|
||
|
By default, this is set to C<< sys::db_timestamp >>. If you want to force a different timestamp, you can do so with this parameter.
|
||
|
|
||
|
=head3 name (required)
|
||
|
|
||
|
This is the name of the alert. So for an alert related to a critically high temperature, this might get set to C<< temperature_high_critical >>. It is meant to compliment the C<< record_locator >> parameter.
|
||
|
|
||
|
=head3 record_locator
|
||
|
|
||
|
This is a record locator, which generally allows a given alert to be tied to a given source. For example, an alert related to a temperature might use C<< an-a01n01.alteeve.com:cpu1_temperature >>.
|
||
|
|
||
|
=head3 set_by (required)
|
||
|
|
||
|
This is a string, usually the name of the program, that set the alert. Usuall this is simple C<< $THIS_FILE >> or C<< $0 >>.
|
||
|
|
||
|
=head3 type (required)
|
||
|
|
||
|
This is set to C<< set >> or C<< clear >>.
|
||
|
|
||
|
If set to C<< set >>, C<< 1 >> will be returned if this is the first time we've tried to set this alert. If the alert was set before, C<< 0 >> is returned.
|
||
|
|
||
|
If set to C<< clear >>, C<< 1 >> will be returned if this is the alert existed and was cleared. If the alert didn't exist (and thus didn't need to be cleared), C<< 0 >> is returned.
|
||
|
|
||
|
=cut
|
||
|
sub check_alert_sent
|
||
|
{
|
||
|
my $self = shift;
|
||
|
my $parameter = shift;
|
||
7 years ago
|
my $anvil = $self->parent;
|
||
8 years ago
|
|
||
7 years ago
|
my $modified_date = $parameter->{modified_date} ? $parameter->{modified_date} : $anvil->data->{sys}{db_timestamp};
|
||
8 years ago
|
my $name = $parameter->{name} ? $parameter->{name} : "";
|
||
|
my $record_locator = $parameter->{record_locator} ? $parameter->{record_locator} : "";
|
||
|
my $set_by = $parameter->{set_by} ? $parameter->{set_by} : "";
|
||
|
my $type = $parameter->{type} ? $parameter->{type} : "";
|
||
7 years ago
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
|
||
8 years ago
|
modified_date => $modified_date,
|
||
|
name => $name,
|
||
|
record_locator => $record_locator,
|
||
|
set_by => $set_by,
|
||
|
type => $type,
|
||
|
}});
|
||
|
|
||
|
# Do we have a timestamp?
|
||
|
if (not $modified_date)
|
||
|
{
|
||
|
# Nope
|
||
7 years ago
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0093"});
|
||
8 years ago
|
return("!!error!!");
|
||
8 years ago
|
}
|
||
|
|
||
|
# Do we have an alert name?
|
||
|
if (not $name)
|
||
|
{
|
||
|
# Nope
|
||
7 years ago
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Alert->check_alert_sent()", parameter => "name" }});
|
||
8 years ago
|
return("!!error!!");
|
||
8 years ago
|
}
|
||
|
|
||
|
# Do we have an record locator?
|
||
|
if (not $record_locator)
|
||
|
{
|
||
|
# Nope
|
||
7 years ago
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Alert->check_alert_sent()", parameter => "record_locator" }});
|
||
8 years ago
|
return("!!error!!");
|
||
8 years ago
|
}
|
||
|
|
||
|
# Do we know who is setting this??
|
||
|
if (not $set_by)
|
||
|
{
|
||
|
# Nope
|
||
7 years ago
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Alert->check_alert_sent()", parameter => "set_by" }});
|
||
8 years ago
|
return("!!error!!");
|
||
8 years ago
|
}
|
||
|
|
||
|
# Are we setting or clearing?
|
||
|
if (not $type)
|
||
|
{
|
||
|
# Neither...
|
||
7 years ago
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0097"});
|
||
8 years ago
|
return("!!error!!");
|
||
8 years ago
|
}
|
||
|
|
||
|
# This will get set to '1' if an alert is added or removed.
|
||
|
my $set = 0;
|
||
|
|
||
|
my $query = "
|
||
|
SELECT
|
||
|
COUNT(*)
|
||
|
FROM
|
||
|
alert_sent
|
||
|
WHERE
|
||
7 years ago
|
alert_sent_host_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($anvil->data->{sys}{host_uuid})."
|
||
8 years ago
|
AND
|
||
7 years ago
|
alert_set_by = ".$anvil->data->{sys}{use_db_fh}->quote($set_by)."
|
||
8 years ago
|
AND
|
||
7 years ago
|
alert_record_locator = ".$anvil->data->{sys}{use_db_fh}->quote($record_locator)."
|
||
8 years ago
|
AND
|
||
7 years ago
|
alert_name = ".$anvil->data->{sys}{use_db_fh}->quote($name)."
|
||
8 years ago
|
;";
|
||
7 years ago
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { query => $query }});
|
||
8 years ago
|
|
||
8 years ago
|
# Now, if this is type=set, register the alert if it doesn't exist. If it is type=clear, remove the
|
||
|
# alert if it exists.
|
||
7 years ago
|
my $count = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
|
||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
|
||
8 years ago
|
type => $type,
|
||
8 years ago
|
count => $count,
|
||
8 years ago
|
}});
|
||
|
if (($type eq "set") && (not $count))
|
||
|
{
|
||
|
### New alert
|
||
|
# Make sure this host is in the database... It might not be on the very first run of ScanCore
|
||
|
# before the peer exists (tried to connect to the peer, fails, tries to send an alert, but
|
||
|
# this host hasn't been added because it is the very first attempt to connect...)
|
||
7 years ago
|
if (not $anvil->data->{sys}{host_is_in_db})
|
||
8 years ago
|
{
|
||
|
my $query = "
|
||
|
SELECT
|
||
|
COUNT(*)
|
||
|
FROM
|
||
|
hosts
|
||
|
WHERE
|
||
7 years ago
|
host_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($anvil->data->{sys}{host_uuid})."
|
||
8 years ago
|
;";
|
||
7 years ago
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { query => $query }});
|
||
8 years ago
|
|
||
7 years ago
|
my $count = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
|
||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { count => $count }});
|
||
8 years ago
|
|
||
|
if (not $count)
|
||
|
{
|
||
|
# Too early, we can't set an alert.
|
||
7 years ago
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "alert", key => "log_0098", variables => {
|
||
7 years ago
|
type => $type,
|
||
|
set_by => $set_by,
|
||
|
record_locator => $record_locator,
|
||
|
name => $name,
|
||
|
modified_date => $modified_date,
|
||
8 years ago
|
}});
|
||
8 years ago
|
return("!!error!!");
|
||
8 years ago
|
}
|
||
|
else
|
||
|
{
|
||
7 years ago
|
$anvil->data->{sys}{host_is_in_db} = 1;
|
||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { 'sys::host_is_in_db' => $anvil->data->{sys}{host_is_in_db} }});
|
||
8 years ago
|
}
|
||
|
}
|
||
|
|
||
|
$set = 1;
|
||
|
my $query = "
|
||
|
INSERT INTO
|
||
|
alert_sent
|
||
|
(
|
||
|
alert_sent_host_uuid,
|
||
|
alert_set_by,
|
||
|
alert_record_locator,
|
||
|
alert_name,
|
||
|
modified_date
|
||
|
) VALUES (
|
||
7 years ago
|
".$anvil->data->{sys}{use_db_fh}->quote($anvil->data->{sys}{host_uuid}).",
|
||
|
".$anvil->data->{sys}{use_db_fh}->quote($set_by).",
|
||
|
".$anvil->data->{sys}{use_db_fh}->quote($record_locator).",
|
||
|
".$anvil->data->{sys}{use_db_fh}->quote($name).",
|
||
|
".$anvil->data->{sys}{use_db_fh}->quote($anvil->data->{sys}{db_timestamp})."
|
||
8 years ago
|
);
|
||
|
";
|
||
7 years ago
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
|
||
8 years ago
|
query => $query,
|
||
|
set => $set,
|
||
|
}});
|
||
7 years ago
|
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
|
||
8 years ago
|
}
|
||
|
elsif (($type eq "clear") && ($count))
|
||
|
{
|
||
|
# Alert previously existed, clear it.
|
||
|
$set = 1;
|
||
|
my $query = "
|
||
|
DELETE FROM
|
||
|
alert_sent
|
||
|
WHERE
|
||
7 years ago
|
alert_sent_host_uuid = ".$anvil->data->{sys}{use_db_fh}->quote($anvil->data->{sys}{host_uuid})."
|
||
8 years ago
|
AND
|
||
7 years ago
|
alert_set_by = ".$anvil->data->{sys}{use_db_fh}->quote($set_by)."
|
||
8 years ago
|
AND
|
||
7 years ago
|
alert_record_locator = ".$anvil->data->{sys}{use_db_fh}->quote($record_locator)."
|
||
8 years ago
|
AND
|
||
7 years ago
|
alert_name = ".$anvil->data->{sys}{use_db_fh}->quote($name)."
|
||
8 years ago
|
;";
|
||
7 years ago
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
|
||
8 years ago
|
query => $query,
|
||
|
set => $set,
|
||
|
}});
|
||
7 years ago
|
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
|
||
8 years ago
|
}
|
||
|
|
||
7 years ago
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { set => $set }});
|
||
8 years ago
|
return($set);
|
||
|
}
|
||
|
|
||
|
=head2 register_alert
|
||
|
|
||
|
This registers an alert to be sent later.
|
||
|
|
||
8 years ago
|
If anything goes wrong, C<< !!error!! >> will be returned.
|
||
8 years ago
|
|
||
|
=cut
|
||
|
sub register_alert
|
||
|
{
|
||
|
my $self = shift;
|
||
|
my $parameter = shift;
|
||
7 years ago
|
my $anvil = $self->parent;
|
||
8 years ago
|
|
||
|
my $header = defined $parameter->{header} ? $parameter->{header} : 1;
|
||
|
my $level = defined $parameter->{level} ? $parameter->{level} : "warning";
|
||
|
my $message_key = defined $parameter->{message_key} ? $parameter->{message_key} : "";
|
||
|
my $message_variables = defined $parameter->{message_variables} ? $parameter->{message_variables} : "";
|
||
|
my $set_by = defined $parameter->{set_by} ? $parameter->{set_by} : "";
|
||
|
my $sort = defined $parameter->{'sort'} ? $parameter->{'sort'} : 9999;
|
||
|
my $title_key = defined $parameter->{title_key} ? $parameter->{title_key} : "title_0003";
|
||
|
my $title_variables = defined $parameter->{title_variables} ? $parameter->{title_variables} : "";
|
||
7 years ago
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
||
8 years ago
|
header => $header,
|
||
|
level => $level,
|
||
|
message_key => $message_key,
|
||
|
message_variables => $message_variables,
|
||
|
set_by => $set_by,
|
||
|
'sort' => $sort,
|
||
|
title_key => $title_key,
|
||
|
title_variables => $title_variables,
|
||
|
}});
|
||
|
|
||
|
if (not $set_by)
|
||
|
{
|
||
7 years ago
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Alert->register_alert()", parameter => "set_by" }});
|
||
8 years ago
|
return("!!error!!");
|
||
8 years ago
|
}
|
||
|
if (not $message_key)
|
||
|
{
|
||
7 years ago
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Alert->register_alert()", parameter => "message_key" }});
|
||
8 years ago
|
return("!!error!!");
|
||
8 years ago
|
}
|
||
|
if (($header) && (not $title_key))
|
||
|
{
|
||
7 years ago
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0101"});
|
||
8 years ago
|
return("!!error!!");
|
||
8 years ago
|
}
|
||
|
|
||
|
# zero-pad sort numbers so that they sort properly.
|
||
8 years ago
|
$sort = sprintf("%04d", $sort);
|
||
7 years ago
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { alert_sort => $sort }});
|
||
8 years ago
|
|
||
|
# Convert the hash of title variables and message variables into '!!x!y!!,!!a!b!!,...' strings.
|
||
8 years ago
|
if (ref($title_variables) eq "HASH")
|
||
8 years ago
|
{
|
||
8 years ago
|
foreach my $key (sort {$a cmp $b} keys %{$title_variables})
|
||
8 years ago
|
{
|
||
8 years ago
|
$title_variables->{$key} = "--" if not defined $title_variables->{$key};
|
||
|
$title_variables .= "!!$key!".$title_variables->{$key}."!!,";
|
||
8 years ago
|
}
|
||
|
}
|
||
8 years ago
|
if (ref($message_variables) eq "HASH")
|
||
8 years ago
|
{
|
||
8 years ago
|
foreach my $key (sort {$a cmp $b} keys %{$message_variables})
|
||
8 years ago
|
{
|
||
8 years ago
|
$message_variables->{$key} = "--" if not defined $message_variables->{$key};
|
||
|
$message_variables .= "!!$key!".$message_variables->{$key}."!!,";
|
||
8 years ago
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
# In most cases, no one is listening to 'debug' or 'info' level alerts. If that is the case here,
|
||
|
# don't record the alert because it can cause the history.alerts table to grow needlessly. So find
|
||
|
# the lowest level log level actually being listened to and simply skip anything lower than that.
|
||
|
# 5 == debug
|
||
|
# 1 == critical
|
||
|
my $lowest_log_level = 5;
|
||
7 years ago
|
foreach my $integer (sort {$a cmp $b} keys %{$anvil->data->{alerts}{recipient}})
|
||
8 years ago
|
{
|
||
|
# We want to know the alert level, regardless of whether the recipient is an email of file
|
||
|
# target.
|
||
|
my $this_level;
|
||
7 years ago
|
if ($anvil->data->{alerts}{recipient}{$integer}{email})
|
||
8 years ago
|
{
|
||
|
# Email recipient
|
||
7 years ago
|
$this_level = ($anvil->data->{alerts}{recipient}{$integer}{email} =~ /level="(.*?)"/)[0];
|
||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { this_level => $this_level }});
|
||
8 years ago
|
}
|
||
7 years ago
|
elsif ($anvil->data->{alerts}{recipient}{$integer}{file})
|
||
8 years ago
|
{
|
||
|
# File target
|
||
7 years ago
|
$this_level = ($anvil->data->{alerts}{recipient}{$integer}{file} =~ /level="(.*?)"/)[0];
|
||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { this_level => $this_level }});
|
||
8 years ago
|
}
|
||
|
|
||
7 years ago
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { this_level => $this_level }});
|
||
8 years ago
|
if ($this_level)
|
||
|
{
|
||
7 years ago
|
$this_level = $anvil->Alert->convert_level_name_to_number({level => $this_level});
|
||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
||
8 years ago
|
this_level => $this_level,
|
||
|
lowest_log_level => $lowest_log_level,
|
||
|
}});
|
||
|
if ($this_level < $lowest_log_level)
|
||
|
{
|
||
|
$lowest_log_level = $this_level;
|
||
7 years ago
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { lowest_log_level => $lowest_log_level }});
|
||
8 years ago
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# Now get the numeric value of this alert and return if it is higher.
|
||
7 years ago
|
my $this_level = $anvil->Alert->convert_level_name_to_number({level => $level});
|
||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
|
||
8 years ago
|
alert_level => $level,
|
||
8 years ago
|
this_level => $this_level,
|
||
|
lowest_log_level => $lowest_log_level,
|
||
|
}});
|
||
|
if ($this_level > $lowest_log_level)
|
||
|
{
|
||
|
# Return.
|
||
7 years ago
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0102", variables => { message_key => $message_key }});
|
||
8 years ago
|
return(0);
|
||
|
}
|
||
|
|
||
|
# Always INSERT. ScanCore removes them as they're acted on (copy is left in history.alerts).
|
||
|
my $query = "
|
||
|
INSERT INTO
|
||
|
alerts
|
||
|
(
|
||
|
alert_uuid,
|
||
|
alert_host_uuid,
|
||
|
alert_set_by,
|
||
|
alert_level,
|
||
|
alert_title_key,
|
||
|
alert_title_variables,
|
||
|
alert_message_key,
|
||
|
alert_message_variables,
|
||
|
alert_sort,
|
||
|
alert_header,
|
||
|
modified_date
|
||
|
) VALUES (
|
||
7 years ago
|
".$anvil->data->{sys}{use_db_fh}->quote($anvil->Get->uuid()).",
|
||
|
".$anvil->data->{sys}{use_db_fh}->quote($anvil->data->{sys}{host_uuid}).",
|
||
|
".$anvil->data->{sys}{use_db_fh}->quote($set_by).",
|
||
|
".$anvil->data->{sys}{use_db_fh}->quote($level).",
|
||
|
".$anvil->data->{sys}{use_db_fh}->quote($title_key).",
|
||
|
".$anvil->data->{sys}{use_db_fh}->quote($title_variables).",
|
||
|
".$anvil->data->{sys}{use_db_fh}->quote($message_key).",
|
||
|
".$anvil->data->{sys}{use_db_fh}->quote($message_variables).",
|
||
|
".$anvil->data->{sys}{use_db_fh}->quote($sort).",
|
||
|
".$anvil->data->{sys}{use_db_fh}->quote($header).",
|
||
|
".$anvil->data->{sys}{use_db_fh}->quote($anvil->data->{sys}{db_timestamp})."
|
||
8 years ago
|
);
|
||
|
";
|
||
7 years ago
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
|
||
|
$anvil->Database->write({query => $query, source => $THIS_FILE, line => __LINE__});
|
||
8 years ago
|
|
||
|
return(0);
|
||
|
}
|
||
|
|
||
8 years ago
|
=head2 error
|
||
|
|
||
|
=cut
|
||
|
|
||
|
# Later, this will support all the translation and logging methods. For now, just print the error and exit.
|
||
|
sub error
|
||
|
{
|
||
|
my $self = shift;
|
||
|
my $parameter = shift;
|
||
7 years ago
|
my $anvil = $self->parent;
|
||
|
# $anvil->Log->entry({log_level => 2, title_key => "tools_log_0001", title_variables => { function => "error" }, message_key => "tools_log_0002", file => $THIS_FILE, line => __LINE__});
|
||
8 years ago
|
#
|
||
|
# # Setup default values
|
||
7 years ago
|
# my $title_key = $parameter->{title_key} ? $parameter->{title_key} : $anvil->String->get({key => "an_0004"});
|
||
8 years ago
|
# my $title_variables = $parameter->{title_variables} ? $parameter->{title_variables} : "";
|
||
7 years ago
|
# my $message_key = $parameter->{message_key} ? $parameter->{message_key} : $anvil->String->get({key => "an_0005"});
|
||
8 years ago
|
# my $message_variables = $parameter->{message_variables} ? $parameter->{message_variables} : "";
|
||
|
# my $code = $parameter->{code} ? $parameter->{code} : 1;
|
||
7 years ago
|
# my $file = $parameter->{file} ? $parameter->{file} : $anvil->String->get({key => "an_0006"});
|
||
8 years ago
|
# my $line = $parameter->{line} ? $parameter->{line} : "";
|
||
|
# #print "$THIS_FILE ".__LINE__."; title_key: [$title_key], title_variables: [$title_variables], message_key: [$message_key], message_variables: [$message_variables], code: [$code], file: [$file], line: [$line]\n";
|
||
|
#
|
||
|
# # It is possible for this to become a run-away call, so this helps
|
||
|
# # catch when that happens.
|
||
7 years ago
|
# $anvil->_error_count($anvil->_error_count + 1);
|
||
|
# if ($anvil->_error_count > $anvil->_error_limit)
|
||
8 years ago
|
# {
|
||
|
# print "Infinite loop detected while trying to print an error:\n";
|
||
|
# print "- title_key: [$title_key]\n";
|
||
|
# print "- title_variables: [$title_variables]\n";
|
||
|
# print "- message_key: [$message_key]\n";
|
||
|
# print "- message_variables: [$title_variables]\n";
|
||
|
# print "- code: [$code]\n";
|
||
|
# print "- file: [$file]\n";
|
||
|
# print "- line: [$line]\n";
|
||
|
# die "Infinite loop detected while trying to print an error, exiting.\n";
|
||
|
# }
|
||
|
#
|
||
|
# # If the 'code' is empty and 'message' is "error_\d+", strip that code
|
||
|
# # off and use it as the error code.
|
||
|
# #print "$THIS_FILE ".__LINE__."; code: [$code], message_key: [$message_key]\n";
|
||
|
# if ((not $code) && ($message_key =~ /error_(\d+)/))
|
||
|
# {
|
||
|
# $code = $1;
|
||
|
# #print "$THIS_FILE ".__LINE__."; code: [$code], message_key: [$message_key]\n";
|
||
|
# }
|
||
|
#
|
||
|
# # If the title is a key, translate it.
|
||
|
# #print "$THIS_FILE ".__LINE__."; title_key: [$title_key]\n";
|
||
|
# if ($title_key =~ /\w+_\d+$/)
|
||
|
# {
|
||
7 years ago
|
# $title_key = $anvil->String->get({
|
||
8 years ago
|
# key => $title_key,
|
||
|
# variables => $title_variables,
|
||
|
# });
|
||
|
# #print "$THIS_FILE ".__LINE__."; title_key: [$title_key]\n";
|
||
|
# }
|
||
|
#
|
||
|
# # If the message is a key, translate it.
|
||
|
# #print "$THIS_FILE ".__LINE__."; message_key: [$message_key]\n";
|
||
|
# if ($message_key =~ /\w+_\d+$/)
|
||
|
# {
|
||
7 years ago
|
# $message_key = $anvil->String->get({
|
||
8 years ago
|
# key => $message_key,
|
||
|
# variables => $message_variables,
|
||
|
# });
|
||
|
# #print "$THIS_FILE ".__LINE__."; message_key: [$message_key]\n";
|
||
|
# }
|
||
|
#
|
||
|
# # Set my error string
|
||
7 years ago
|
# my $fatal_heading = $anvil->String->get({key => "an_0002"});
|
||
8 years ago
|
# #print "$THIS_FILE ".__LINE__."; fatal_heading: [$fatal_heading]\n";
|
||
|
#
|
||
7 years ago
|
# my $readable_line = $anvil->Readable->comma($line);
|
||
8 years ago
|
# #print "$THIS_FILE ".__LINE__."; readable_line: [$readable_line]\n";
|
||
|
#
|
||
|
# ### TODO: Copy this to 'warning'.
|
||
|
# # At this point, the title and message keys are the actual messages.
|
||
7 years ago
|
# my $error = "\n".$anvil->String->get({
|
||
8 years ago
|
# key => "an_0007",
|
||
|
# variables => {
|
||
|
# code => $code,
|
||
|
# heading => $fatal_heading,
|
||
|
# file => $file,
|
||
|
# line => $readable_line,
|
||
|
# title => $title_key,
|
||
|
# message => $message_key,
|
||
|
# },
|
||
|
# })."\n\n";
|
||
|
# #print "$THIS_FILE ".__LINE__."; error: [$error]\n";
|
||
|
#
|
||
|
# # Set the internal error flags
|
||
7 years ago
|
# $anvil->Alert->_set_error($error);
|
||
|
# $anvil->Alert->_set_error_code($code);
|
||
8 years ago
|
#
|
||
|
# # Append "exiting" to the error string if it is fatal.
|
||
7 years ago
|
# $error .= $anvil->String->get({key => "an_0008"})."\n";
|
||
8 years ago
|
#
|
||
|
# # Write a copy of the error to the log.
|
||
7 years ago
|
# $anvil->Log->entry({file => $THIS_FILE, level => 0, raw => $error});
|
||
8 years ago
|
#
|
||
|
# # If this is a browser calling us, print the footer so that the loading pinwheel goes away.
|
||
|
# if ($ENV{'HTTP_REFERER'})
|
||
|
# {
|
||
7 years ago
|
# $anvil->Striker->_footer();
|
||
8 years ago
|
# }
|
||
|
#
|
||
|
# # Don't actually die, but do print the error, if fatal errors have been globally disabled (as is done
|
||
|
# # in the tests).
|
||
7 years ago
|
# if (not $anvil->Alert->no_fatal_errors)
|
||
8 years ago
|
# {
|
||
|
# if ($ENV{'HTTP_REFERER'})
|
||
|
# {
|
||
|
# print "<pre>\n";
|
||
7 years ago
|
# print "$error\n" if not $anvil->Alert->no_fatal_errors;
|
||
8 years ago
|
# print "</pre>\n";
|
||
|
# }
|
||
|
# else
|
||
|
# {
|
||
7 years ago
|
# print "$error\n" if not $anvil->Alert->no_fatal_errors;
|
||
8 years ago
|
# }
|
||
7 years ago
|
# $anvil->data->{sys}{footer_printed} = 1;
|
||
|
# $anvil->nice_exit({exit_code => $code});
|
||
8 years ago
|
# }
|
||
|
#
|
||
|
# return ($code);
|
||
|
}
|
||
|
|
||
|
1;
|