Hello all,
I am trying to parse BSD Syslog format time stamps, like this one:
Sep 1 05:39:02
Using the DateTime::Format::Strptime class, the call is failing with
the following result, when I use the format string '%b %d %H:%M:%S'.
There is no use providing a month name (Sep) without providing a year.
at /homes/megahall/workspace/montage/src/Yahoo/Montage/WelfParser.pm line 55
Searching for the error on the Internet even with the "(Sep)" removed
does not return any meaningful results.
I am wondering what I can do to fix this issue so I can get DateTime
working, or if there is a workaround of some sort. It does not seem
reasonable to croak or return undef time object because then there is
no way to set a valid year using a member function plus some external
year logic.
In addition, when trying to debug using the default on_error undef
setup, I discovered it is not possible to see this error message, and
that the $object->errstr() method mentioned in the documentation does
not seem to exist. Grepping the perl lib folder did not reveal it
either and I got an error trying to call it as well.
Further information below.
Thanks,
Matthew.
In the grep output; only a documentation passage is mentioned. This is
the passage from the documentation:
This is the default behavior. The module will return undef whenever it
gets upset. The error can be accessed using the $object->errstr method.
This is the ideal behaviour for interactive use where a user might
provide an illegal pattern or a date that doesn't match the pattern.
Here are my package versions.
DateTime-Format-Builder-0.7901_02
DateTime-Format-Epoch-0.10_01
DateTime-Format-ISO8601-0.0601_01
DateTime-Format-Strptime-1.0702_02
DateTime-Locale-0.42_01
DateTime-TimeZone-1.01_01
DateTime-0.5000_01
Here is a code snippet.
my @date_time_formats = (
# BSD: 'Mmm DD HH:MM:SS'
['BSD Syslog' , new DateTime::Format::Strptime(pattern => '%b %d
%H:%M:%S' , locale => 'en_US', time_zone => 'GMT', diagnostic =>
$diagnostic, on_error => 'croak')],
);
sub welf_time {
my ($time_str) = @_;
$log->debug("process time_str [$time_str]");
my $date_time;
my $type;
my $parser;
for (my $i = 0; $i < scalar(@date_time_formats); $i++) {
eval {
$type = $date_time_formats[$i][0];
$parser = $date_time_formats[$i][1];
$log->trace("call parser [$type]");
$date_time = $parser->parse_datetime($time_str);
$log->trace("return parser [$type] result [" . display($date_time)
. "] errstr [" . display($parser->errstr()) . "]");
};
if ($@) {
$log->info("parser [$type] experienced exception {...@}\n");
}
}
$log->log(!defined($date_time)? $WARN : $TRACE,
"processed time_str [$time_str] into date_time [" . display($date_time)
. "]");
if (!defined($date_time)) {
$date_time = DateTime->now();
}
return $date_time->epoch();
}
Below is the log4perl output, along with diagnostic enabled on the
parser.
[2010/09/01 20:06:30] [WelfParser.pm:44] [DEBUG]
process time_str [Sep 1 05:39:02]
[2010/09/01 20:06:30] [WelfParser.pm:53] [TRACE]
call parser [BSD Syslog]
Entered = Sep 1 05:39:02
Parser = ($month_name, $day, $hour_24, $minute, $second) =
$time_string =~ /(\S+) ([\d ]?\d) ([\d ]?\d):([\d ]?\d):([\d ]?\d)/
dow_name =
month_name = Sep
century =
day = 1
hour_24 = 05
hour_12 =
doy =
month =
minute = 39
ampm =
second = 02
nanosecond =
week_sun_0 =
dow_sun_0 =
dow_mon_1 =
week_mon_1 =
year_100 =
year =
ce_year =
tz_offset =
tz_olson =
timezone =
epoch =
iso_week_year =
iso_week_year_100 =
Using timezone DateTime::TimeZone::UTC=HASH(0x9162350).
[2010/09/01 20:06:30] [WelfParser.pm:61] [INFO]
parser [BSD Syslog] experienced exception {
There is no use providing a month name (Sep) without providing a year.
at /homes/megahall/workspace/montage/src/Yahoo/Montage/WelfParser.pm line 55
}
[2010/09/01 20:06:30] [WelfParser.pm:65] [WARN]
processed time_str [Sep 1 05:39:02] into date_time [undef]