* Added Get->date_and_time() method. * Added the 'initialize' parameter to Storage->search_directories() to have a cleaner way of initializing the search directories. Signed-off-by: Digimer <digimer@alteeve.ca>main
parent
7b8cb22de0
commit
dd4fb49e6c
7 changed files with 434 additions and 16 deletions
@ -0,0 +1,163 @@ |
|||||||
|
package AN::Tools::Get; |
||||||
|
# |
||||||
|
# This module contains methods used to handle access to frequently used data. |
||||||
|
# |
||||||
|
|
||||||
|
use strict; |
||||||
|
use warnings; |
||||||
|
use Data::Dumper; |
||||||
|
|
||||||
|
our $VERSION = "3.0.0"; |
||||||
|
my $THIS_FILE = "Get.pm"; |
||||||
|
|
||||||
|
### Methods; |
||||||
|
# date_and_time |
||||||
|
|
||||||
|
=pod |
||||||
|
|
||||||
|
=encoding utf8 |
||||||
|
|
||||||
|
=head1 NAME |
||||||
|
|
||||||
|
AN::Tools::Get |
||||||
|
|
||||||
|
Provides all methods related to logging. |
||||||
|
|
||||||
|
=head1 SYNOPSIS |
||||||
|
|
||||||
|
use AN::Tools; |
||||||
|
|
||||||
|
# Get a common object handle on all AN::Tools modules. |
||||||
|
my $an = AN::Tools->new(); |
||||||
|
|
||||||
|
# Access to methods using '$an->Get->X'. |
||||||
|
# |
||||||
|
# Example using 'date_and_time()'; |
||||||
|
my $foo_path = $an->Get->date_and_time({...}); |
||||||
|
|
||||||
|
=head1 METHODS |
||||||
|
|
||||||
|
Methods in this module; |
||||||
|
|
||||||
|
=cut |
||||||
|
sub new |
||||||
|
{ |
||||||
|
my $class = shift; |
||||||
|
my $self = {}; |
||||||
|
|
||||||
|
bless $self, $class; |
||||||
|
|
||||||
|
return ($self); |
||||||
|
} |
||||||
|
|
||||||
|
# Get a handle on the AN::Tools object. I know that technically that is a sibling module, but it makes more |
||||||
|
# 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; |
||||||
|
|
||||||
|
return ($self->{HANDLE}{TOOLS}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
############################################################################################################# |
||||||
|
# Public methods # |
||||||
|
############################################################################################################# |
||||||
|
|
||||||
|
=head2 date_and_time |
||||||
|
|
||||||
|
This method returns the date and/or time using either the current time, or a specified unix time. |
||||||
|
|
||||||
|
NOTE: This only returns times in 24-hour notation. |
||||||
|
|
||||||
|
|
||||||
|
=head2 Parameters; |
||||||
|
|
||||||
|
=head3 date_only (optional) |
||||||
|
|
||||||
|
If set, only the date will be returned (in C<< yyyy/mm/dd >> format). |
||||||
|
|
||||||
|
=head3 file_name (optional) |
||||||
|
|
||||||
|
When set, the date and/or time returned in a string more useful in file names. Specifically, it will replace spaces with 'C<< _ >>' and 'C<< : >>' and 'C<< / >>' for 'C<< - >>'. This will result in a string in the format like 'C<< yyyy-mm-dd_hh-mm-ss >>'. |
||||||
|
|
||||||
|
=head3 offset (optional) |
||||||
|
|
||||||
|
If set to a signed number, it will add or subtract the number of seconds from the 'C<< use_time >>' before processing. |
||||||
|
|
||||||
|
=head3 use_time (optional) |
||||||
|
|
||||||
|
This can be set to a unix timestamp. If it is not set, the current time is used. |
||||||
|
|
||||||
|
=head3 time_only (optional) |
||||||
|
|
||||||
|
If set, only the time will be returned (in C<< hh:mm:ss >> format). |
||||||
|
|
||||||
|
=cut |
||||||
|
sub date_and_time |
||||||
|
{ |
||||||
|
my $self = shift; |
||||||
|
my $parameter = shift; |
||||||
|
my $an = $self->parent; |
||||||
|
|
||||||
|
my $offset = defined $parameter->{offset} ? $parameter->{offset} : 0; |
||||||
|
my $use_time = defined $parameter->{use_time} ? $parameter->{use_time} : time; |
||||||
|
my $file_name = defined $parameter->{file_name} ? $parameter->{file_name} : 0; |
||||||
|
my $time_only = defined $parameter->{time_only} ? $parameter->{time_only} : 0; |
||||||
|
my $date_only = defined $parameter->{date_only} ? $parameter->{date_only} : 0; |
||||||
|
|
||||||
|
# Are things sane? |
||||||
|
if ($use_time =~ /D/) |
||||||
|
{ |
||||||
|
die "Get->date_and_time() was called with 'use_time' set to: [$use_time]. Only a unix timestamp is allowed.\n"; |
||||||
|
} |
||||||
|
if ($offset =~ /D/) |
||||||
|
{ |
||||||
|
die "Get->date_and_time() was called with 'offset' set to: [$offset]. Only real number is allowed.\n"; |
||||||
|
} |
||||||
|
|
||||||
|
# Do my initial calculation. |
||||||
|
my $return_string = ""; |
||||||
|
my $time = {}; |
||||||
|
my $adjusted_time = $use_time + $offset; |
||||||
|
#print $THIS_FILE." ".__LINE__."; [ Debug ] - adjusted_time: [$adjusted_time]\n"; |
||||||
|
|
||||||
|
# Get the date and time pieces |
||||||
|
($time->{sec}, $time->{min}, $time->{hour}, $time->{mday}, $time->{mon}, $time->{year}, $time->{wday}, $time->{yday}, $time->{isdst}) = localtime($adjusted_time); |
||||||
|
#print $THIS_FILE." ".__LINE__."; [ Debug ] - time->{sec}: [".$time->{sec}."], time->{min}: [".$time->{min}."], time->{hour}: [".$time->{hour}."], time->{mday}: [".$time->{mday}."], time->{mon}: [".$time->{mon}."], time->{year}: [".$time->{year}."], time->{wday}: [".$time->{wday}."], time->{yday}: [".$time->{yday}."], time->{isdst}: [".$time->{isdst}."]\n"; |
||||||
|
|
||||||
|
# Process the raw data |
||||||
|
$time->{pad_hour} = sprintf("%02d", $time->{hour}); |
||||||
|
$time->{mon}++; |
||||||
|
$time->{pad_min} = sprintf("%02d", $time->{min}); |
||||||
|
$time->{pad_sec} = sprintf("%02d", $time->{sec}); |
||||||
|
$time->{year} = ($time->{year} + 1900); |
||||||
|
$time->{pad_mon} = sprintf("%02d", $time->{mon}); |
||||||
|
$time->{pad_mday} = sprintf("%02d", $time->{mday}); |
||||||
|
#print $THIS_FILE." ".__LINE__."; [ Debug ] - time->{pad_hour}: [".$time->{pad_hour}."], time->{pad_min}: [".$time->{pad_min}."], time->{pad_sec}: [".$time->{pad_sec}."], time->{year}: [".$time->{year}."], time->{pad_mon}: [".$time->{pad_mon}."], time->{pad_mday}: [".$time->{pad_mday}."], time->{mon}: [".$time->{mon}."]\n"; |
||||||
|
|
||||||
|
# Now, the date and time separator depends on if 'file_name' is set. |
||||||
|
my $date_separator = $file_name ? "-" : "/"; |
||||||
|
my $time_separator = $file_name ? "-" : ":"; |
||||||
|
my $space_separator = $file_name ? "_" : " "; |
||||||
|
if ($time_only) |
||||||
|
{ |
||||||
|
$return_string = $time->{pad_hour}.$time_separator.$time->{pad_min}.$time_separator.$time->{pad_sec}; |
||||||
|
#print $THIS_FILE." ".__LINE__."; [ Debug ] - return_string: [$return_string]\n"; |
||||||
|
} |
||||||
|
elsif ($date_only) |
||||||
|
{ |
||||||
|
$return_string = $time->{year}.$date_separator.$time->{pad_mon}.$date_separator.$time->{pad_mday}; |
||||||
|
#print $THIS_FILE." ".__LINE__."; [ Debug ] - return_string: [$return_string]\n"; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
$return_string = $time->{year}.$date_separator.$time->{pad_mon}.$date_separator.$time->{pad_mday}.$space_separator.$time->{pad_hour}.$time_separator.$time->{pad_min}.$time_separator.$time->{pad_sec}; |
||||||
|
#print $THIS_FILE." ".__LINE__."; [ Debug ] - return_string: [$return_string]\n"; |
||||||
|
} |
||||||
|
|
||||||
|
return($return_string); |
||||||
|
} |
@ -0,0 +1,188 @@ |
|||||||
|
package AN::Tools::Log; |
||||||
|
# |
||||||
|
# This module contains methods used to handle logging related tasks |
||||||
|
# |
||||||
|
|
||||||
|
use strict; |
||||||
|
use warnings; |
||||||
|
use Data::Dumper; |
||||||
|
|
||||||
|
our $VERSION = "3.0.0"; |
||||||
|
my $THIS_FILE = "Log.pm"; |
||||||
|
|
||||||
|
### Methods; |
||||||
|
# entry |
||||||
|
|
||||||
|
=pod |
||||||
|
|
||||||
|
=encoding utf8 |
||||||
|
|
||||||
|
=head1 NAME |
||||||
|
|
||||||
|
AN::Tools::Log |
||||||
|
|
||||||
|
Provides all methods related to logging. |
||||||
|
|
||||||
|
=head1 SYNOPSIS |
||||||
|
|
||||||
|
use AN::Tools; |
||||||
|
|
||||||
|
# Get a common object handle on all AN::Tools modules. |
||||||
|
my $an = AN::Tools->new(); |
||||||
|
|
||||||
|
# Access to methods using '$an->Log->X'. |
||||||
|
# |
||||||
|
# Example using 'entry()'; |
||||||
|
my $foo_path = $an->Log->entry({...}); |
||||||
|
|
||||||
|
=head1 METHODS |
||||||
|
|
||||||
|
Methods in this module; |
||||||
|
|
||||||
|
=cut |
||||||
|
sub new |
||||||
|
{ |
||||||
|
my $class = shift; |
||||||
|
my $self = {}; |
||||||
|
|
||||||
|
bless $self, $class; |
||||||
|
|
||||||
|
return ($self); |
||||||
|
} |
||||||
|
|
||||||
|
# Get a handle on the AN::Tools object. I know that technically that is a sibling module, but it makes more |
||||||
|
# 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; |
||||||
|
|
||||||
|
return ($self->{HANDLE}{TOOLS}); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
############################################################################################################# |
||||||
|
# Public methods # |
||||||
|
############################################################################################################# |
||||||
|
|
||||||
|
=head2 entry |
||||||
|
|
||||||
|
This method writes an entry to the log file, provided the log file is equal to or higher than the active log level. The exception is if the log entry contains sensitive data, like a password, and 'C<< log::secure >> is set to 'C<< 0 >>' (the default). |
||||||
|
|
||||||
|
Here is a simple example of writing a simple log entry at log log level 1. |
||||||
|
|
||||||
|
$an->Log->entry({file => $THIS_FILE, line => __LINE__, level => 1, key => "log_0001"}); |
||||||
|
|
||||||
|
In the example above, the string will be written to the log file if the active log level is 'C<< 1 >>' or higher and it will use the 'C<< log::language >>' language to translate the string key. |
||||||
|
|
||||||
|
Now a more complex example; |
||||||
|
|
||||||
|
$an->Log->entry({ |
||||||
|
file => $THIS_FILE, |
||||||
|
line => __LINE__, |
||||||
|
level => 2, |
||||||
|
secure => 1, |
||||||
|
language => "jp", |
||||||
|
key => "log_0002", |
||||||
|
variables => { |
||||||
|
password => "foo", |
||||||
|
}, |
||||||
|
}); |
||||||
|
|
||||||
|
In the above example, the log level is set to 'C<< 2 >>' and the 'C<< secure >>' flag is set. We're also logging in Japanese and we are passing a variable into the string key. With the secure flag set, even if the user's log level is 2 or higher, the log entry will only be recorded if the user has set 'C<< log::secure >>' to '1'. |
||||||
|
|
||||||
|
Finally, it is possible to log pre-processed strings (as is done in 'Alert->warning()' and 'Alert->error()'). In this case, the 'C<< raw >>' parameter is used and it contains the processed string. Note that the source file and line number are still pre-pended to the raw message. |
||||||
|
|
||||||
|
$an->Log->entry({ |
||||||
|
file => $THIS_FILE, |
||||||
|
line => __LINE__, |
||||||
|
level => 2, |
||||||
|
raw => "This error can't be translated", |
||||||
|
}); |
||||||
|
|
||||||
|
The above should be used very sparingly, and generally only in places where string processing itself is being logged. |
||||||
|
|
||||||
|
Parameters; |
||||||
|
|
||||||
|
=head3 file (optional) |
||||||
|
|
||||||
|
When set, the string is pre-pended to the log entry. This is generally set to 'C<< $THIS_FILE >>', which itself should contain the file name requesting the log entry. |
||||||
|
|
||||||
|
=head3 key (required) |
||||||
|
|
||||||
|
NOTE: This is not required *if* 'C<< raw >>' is used instead. |
||||||
|
|
||||||
|
This is the string key to use for the log entry. By default, it will be translated into the 'C<< log::language >> language. If the string contains replacement variables, be sure to also use 'C<< variables >>'. |
||||||
|
|
||||||
|
=head3 level (required) |
||||||
|
|
||||||
|
This is the numeric log level of this log entry. It determines if the message is of interest to the user. An entry is only recorded if the user's 'C<< log::level >>' is equal to or higher than this number. This is required, but if it is not passed, 'C<< 2 >>' will be used. |
||||||
|
|
||||||
|
NOTE: The 'C<< log::level >>' might be changed inside certain programs. For example, in ScanCore, the user may set 'C<< scancore::log::level >>' and that will be used to set 'C<< log::level >>'. |
||||||
|
|
||||||
|
Log levels are: |
||||||
|
|
||||||
|
=head4 C<< 0 >> |
||||||
|
|
||||||
|
Critical messages. These will always be logged, and so this log level should very rarely be used. Generally it will be used only by Alert->warning() and Alert->error(). |
||||||
|
|
||||||
|
=head4 C<< 1 >> |
||||||
|
|
||||||
|
Important messages. The default log level is 'C<< 1 >>', so anything at this log level will usually be logged under normal conditions. |
||||||
|
|
||||||
|
=head4 C<< 2 >> |
||||||
|
|
||||||
|
This is the 'debug' log level. It is used by developers while working on a section of code, or in places where the log entries can help in general debugging. |
||||||
|
|
||||||
|
=head4 C<< 3 >> |
||||||
|
|
||||||
|
This is the 'verbose' log level. It will generally generate a significant amount of output and is generally used for most logging. A user will generally only set this log level when trying to debug a problem with an unknown source. |
||||||
|
|
||||||
|
=head4 C<< 4 >> |
||||||
|
|
||||||
|
This is the highest log level, and it will generate a tremendous amount of log entries. This is generally used is loops or recursive functions where the output is significant, but the usefulness of the output is not. |
||||||
|
|
||||||
|
|
||||||
|
=head3 line (optional) |
||||||
|
|
||||||
|
When set, the string is prepended to the log entry, after 'C<< file >> if set, and should be set to C<< __LINE__ >>. It is used to show where in 'C<< file >>' the log entry was made and can assist with debugging. |
||||||
|
|
||||||
|
=head3 raw (optional) |
||||||
|
|
||||||
|
NOTE: This *or* C<< key >> must be passed. |
||||||
|
|
||||||
|
This can contain a string to record to the log file. It is treated as a raw string and is not translated, altered or processed in any way. It will be recorded exactly as-is, provided the log level and secure settings allow for it. |
||||||
|
|
||||||
|
=head3 secure (optional) |
||||||
|
|
||||||
|
When set, this indicates that the log entry might contain sensitive data, like a password. When set, the log entry will only be recorded if 'C<< log::secure >>' is set to '1' *and* the log level is equal to or higher than 'C<< log::level >>'. |
||||||
|
|
||||||
|
=head3 variables (optional) |
||||||
|
|
||||||
|
This is a hash reference containing replacement variables to inject into the 'C<< key >>' string. |
||||||
|
|
||||||
|
=cut |
||||||
|
sub entry |
||||||
|
{ |
||||||
|
my $self = shift; |
||||||
|
my $parameter = shift; |
||||||
|
my $an = $self->parent; |
||||||
|
|
||||||
|
my $file = defined $parameter->{file} ? $parameter->{file} : ""; |
||||||
|
my $key = defined $parameter->{key} ? $parameter->{key} : ""; |
||||||
|
my $level = defined $parameter->{level} ? $parameter->{level} : 2; |
||||||
|
my $line = defined $parameter->{line} ? $parameter->{line} : ""; |
||||||
|
my $raw = defined $parameter->{raw} ? $parameter->{raw} : ""; |
||||||
|
my $secure = defined $parameter->{secure} ? $parameter->{secure} : 0; |
||||||
|
my $variables = defined $parameter->{variables} ? $parameter->{variables} : ""; |
||||||
|
|
||||||
|
if ($level > $an->data->{'log'}{level}) |
||||||
|
{ |
||||||
|
return(1); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
return(0); |
||||||
|
} |
Loading…
Reference in new issue