Skip to content

Commit 370240f

Browse files
author
lajandy
committed
0.10_3270 Sun Aug 9 18:14:10 EDT 2015
- Added more tests (t/2.t). - heliosx_logger_hires_search - Added JSON, pipe-separated, and tab-separated output formats. Added ability to search for multiple specific log priorities. Added more parameter sanity checking.
1 parent ede2776 commit 370240f

File tree

8 files changed

+215
-39
lines changed

8 files changed

+215
-39
lines changed

Diff for: Changes

+7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
Revision history for Perl extension HeliosX::Logger::HiRes.
22

3+
0.10_3270 Sun Aug 9 18:14:10 EDT 2015
4+
- Added more tests (t/2.t).
5+
- heliosx_logger_hires_search - Added JSON, pipe-separated, and
6+
tab-separated output formats. Added ability to search for multiple
7+
specific log priorities. Added more parameter sanity checking.
8+
0.10_2751 Fri Jul 3 14:22:56 2015
9+
- First release to CPAN.
310
0.10_0000 Sun May 17 16:32:58 2015
411
- Initial public version.

Diff for: LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The Artistic License 2.0
22

3-
Copyright (c) 2014 by Logical Helion, LLC.
3+
Copyright (c) 2015 by Logical Helion, LLC.
44

55
Everyone is permitted to copy and distribute verbatim copies
66
of this license document, but changing it is not allowed.

Diff for: MANIFEST

+1
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ sql/heliosx_logger_hires_mysql.sql
1010
sql/heliosx_logger_hires_oracle.sql
1111
sql/heliosx_logger_hires_sqlite.sql
1212
t/1.t
13+
t/2.t

Diff for: Makefile.PL

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ my %eumm_params = (
1212
'Time::HiRes' => 1.86,
1313
'Time::Piece' => 1.12,
1414
'parent' => 0.221,
15+
'JSON::Tiny' => 0.48,
1516
},
1617
EXE_FILES => ['heliosx_logger_hires_search'],
1718
INST_SCRIPT => 'bin',

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ DEPENDENCIES
2424
This module requires these other modules and libraries:
2525

2626
* Helios 2.80 or later
27+
* JSON::Tiny 0.48 or later
2728
* Time::HiRes 1.86 or later
2829
* Time::Piece 1.12 or later
2930
* parent 0.221 or later

Diff for: heliosx_logger_hires_search

+156-37
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@ use warnings;
66
use Getopt::Long;
77
use Time::Local;
88
use Time::Piece;
9+
use JSON::Tiny qw(encode_json decode_json);
10+
$JSON::Tiny::TRUE = 1;
11+
$JSON::Tiny::FALSE = 0;
912

1013
use Helios::ObjectDriver;
1114
use Helios::LogEntry::Levels ':all';
1215
use Helios::JobType;
1316
use HeliosX::Logger::HiRes::LogEntry;
1417

15-
our $VERSION = '0.10_2751';
18+
our $VERSION = '0.10_3270';
1619

1720
our @LOG_PRIORITIES = qw(EMERG ALERT CRIT ERR WARNING NOTICE INFO DEBUG);
1821
our %LOG_PRIORITY_MAP = (
@@ -28,14 +31,16 @@ our %LOG_PRIORITY_MAP = (
2831
our $LIMIT_DEFAULT = 50;
2932

3033
our ($OPT_START_DATE, $OPT_END_DATE, $OPT_HOSTNAME, $OPT_PID, $OPT_JOBID,
31-
$OPT_JOBTYPE, $OPT_SERVICE, $OPT_PRIORITY, $OPT_MESSAGE, $OPT_LIMIT,
32-
$OPT_SORT, $OPT_TAIL, $OPT_FOLLOW);
34+
$OPT_JOBTYPE, $OPT_SERVICE, @OPT_PRIORITY, $OPT_MESSAGE, $OPT_LIMIT,
35+
$OPT_SORT, $OPT_TAIL, $OPT_FOLLOW, $OPT_OUTPUT_FORMAT);
3336
our ($OPT_HELP, $OPT_VERSION, $OPT_DEBUG);
3437

35-
our $DEBUG_MODE = 0;
36-
our $FOLLOW_MODE = 0;
37-
our $TAIL_MODE = 0;
38-
our $LAST_LOGID = 0;
38+
our $DEBUG_MODE = 0;
39+
our $FOLLOW_MODE = 0;
40+
our $TAIL_MODE = 0;
41+
our $LAST_LOGID = 0;
42+
our $OUTPUT_FORMAT = 'log';
43+
our $OUTPUT_SEPARATOR = '';
3944

4045
GetOptions(
4146
"start-date=s" => \$OPT_START_DATE,
@@ -47,13 +52,15 @@ GetOptions(
4752
"jobtype=s" => \$OPT_JOBTYPE,
4853
"service=s" => \$OPT_SERVICE,
4954
"message=s" => \$OPT_MESSAGE,
50-
"priority=s" => \$OPT_PRIORITY,
55+
"priority=s" => \@OPT_PRIORITY,
5156

5257
"n|lines|limit=i" => \$OPT_LIMIT,
5358
"sort=s" => \$OPT_SORT,
5459
"tail" => \$OPT_TAIL,
5560
"follow" => \$OPT_FOLLOW,
5661

62+
"output-format=s" => \$OPT_OUTPUT_FORMAT,
63+
5764
"help" => \$OPT_HELP,
5865
"version" => \$OPT_VERSION,
5966
"debug" => \$OPT_DEBUG,
@@ -94,45 +101,89 @@ if ($OPT_PID) {
94101
}
95102

96103
if ($OPT_JOBID) {
97-
$search_opts{jobid} = $OPT_JOBID;
104+
if ($OPT_JOBID !~ /\D/) {
105+
$search_opts{jobid} = $OPT_JOBID;
106+
} else {
107+
print STDERR "ERROR: Not a valid jobid: ",$OPT_JOBID,"\n";
108+
exit(1);
109+
}
98110
}
99111

100112
if ($OPT_HOSTNAME) {
101-
$search_opts{host} = $OPT_HOSTNAME;
113+
if ( length($OPT_HOSTNAME) < 256 ) {
114+
$search_opts{host} = $OPT_HOSTNAME;
115+
} else {
116+
print STDERR "ERROR: Not a valid hostname: ", $OPT_HOSTNAME,"\n";
117+
exit(1);
118+
}
102119
}
103120

104121
if ($OPT_SERVICE) {
105-
$search_opts{service} = $OPT_SERVICE;
122+
if ($OPT_SERVICE =~ /^[A-Za-z]([A-Za-z0-9_\-]|:{2})*[A-Za-z0-9_\-]$/) {
123+
$search_opts{service} = $OPT_SERVICE;
124+
} else {
125+
print STDERR "ERROR: Not a valid service name: ",$OPT_SERVICE,"\n";
126+
exit(1);
127+
}
106128
}
107129

108130
if ($OPT_JOBTYPE) {
109-
my $jt = Helios::JobType->lookup(name => $OPT_JOBTYPE);
110-
$search_opts{jobtypeid} = $jt->getJobtypeid();
131+
eval {
132+
if (length($OPT_JOBTYPE) > 255) { die("Jobtype too long."); }
133+
my $jt = Helios::JobType->lookup(name => $OPT_JOBTYPE);
134+
if (!defined($jt)) { die("Jobtype not found."); }
135+
$search_opts{jobtypeid} = $jt->getJobtypeid();
136+
1;
137+
} or do {
138+
print STDERR "ERROR: Not a valid jobtype: ", $OPT_JOBTYPE,"\n";
139+
exit(1);
140+
};
111141
}
112142

113-
if ($OPT_PRIORITY) {
114-
my $p = uc($OPT_PRIORITY);
115-
if ( defined $LOG_PRIORITY_MAP{$p} ) {
116-
$search_opts{priority} = $LOG_PRIORITY_MAP{$p};
117-
118-
}
143+
if ( scalar @OPT_PRIORITY ) {
144+
my @p = split(/,/, join(','=> @OPT_PRIORITY) );
145+
if (scalar @p == 1) {
146+
if ( defined $LOG_PRIORITY_MAP{$p[0]} ) {
147+
$search_opts{priority} = $LOG_PRIORITY_MAP{$p[0]};
148+
} else {
149+
print STDERR "ERROR: Not a valid priority: ",$p[0],"\n";
150+
exit(1);
151+
}
152+
} elsif ( scalar @p > 1) {
153+
my @p_opts;
154+
foreach my $p (@p) {
155+
$p = uc($p);
156+
if ( defined $LOG_PRIORITY_MAP{$p} ) {
157+
push(@p_opts, $LOG_PRIORITY_MAP{$p});
158+
} else {
159+
print STDERR "ERROR: Not a valid priority: ",$p,"\n";
160+
exit(1);
161+
}
162+
}
163+
$search_opts{priority} = \@p_opts;
164+
} else {
165+
print STDERR "ERROR: Not a valid priority: ",join(','=> @OPT_PRIORITY),"\n";
166+
exit(1);
167+
}
119168
}
120169

170+
# set the default limit NOW, before we process the date and
171+
# other options that can modify the limit
121172
my $limit = $LIMIT_DEFAULT;
122173

123174
if ($OPT_START_DATE || $OPT_END_DATE) {
124175
my $sd_epoch = '';
125176
my $ed_epoch = '';
126177

127-
if ($OPT_START_DATE) {
178+
if ($OPT_START_DATE && $OPT_START_DATE =~ /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}$/) {
128179
# convert Ts and Zs to spaces
129180
my ($sd, $st) = split(/[ T]/, $OPT_START_DATE);
130181
my ($yyyy, $mm, $dd) = split('-', $sd);
131182
my ($hh24, $mi, $ss) = split(':', $st);
132183
$sd_epoch = timelocal($ss, $mi, $hh24, $dd, $mm - 1, $yyyy);
133184
}
134185

135-
if ($OPT_END_DATE) {
186+
if ($OPT_END_DATE && $OPT_END_DATE =~ /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}$/) {
136187
# convert Ts and Zs to spaces
137188
my ($ed, $et) = split(/[ T]/, $OPT_END_DATE);
138189
my ($yyyy, $mm, $dd) = split('-', $ed);
@@ -155,9 +206,15 @@ if ($OPT_START_DATE || $OPT_END_DATE) {
155206

156207
}
157208

158-
209+
# handle -n/--limit/--lines
159210
if ($OPT_LIMIT) {
160-
$limit = $OPT_LIMIT;
211+
if ($OPT_LIMIT !~ /\D/) {
212+
$limit = $OPT_LIMIT;
213+
} else {
214+
print STDERR "ERROR: Not a valid limit: ",$OPT_LIMIT,"\n";
215+
exit(1);
216+
}
217+
161218
}
162219

163220
# Follow Mode
@@ -173,16 +230,43 @@ if ($FOLLOW_MODE) {
173230
}
174231
}
175232

233+
# output format switches
234+
if ($OPT_OUTPUT_FORMAT) {
235+
my $fmt = uc($OPT_OUTPUT_FORMAT);
236+
SWITCH : {
237+
if ($fmt eq 'PIPE') {
238+
$OUTPUT_FORMAT = 'pipe';
239+
$OUTPUT_SEPARATOR = '|';
240+
last;
241+
}
242+
if ($fmt eq 'TAB') {
243+
$OUTPUT_FORMAT = 'tab';
244+
$OUTPUT_SEPARATOR = "\t";
245+
last;
246+
}
247+
if ($fmt eq 'JSON') {
248+
$OUTPUT_FORMAT = 'json';
249+
last;
250+
}
251+
# default
252+
print STDERR "ERROR: Not a valid output format: ",$OPT_OUTPUT_FORMAT,"\n";
253+
exit(1);
254+
}
255+
if ($FOLLOW_MODE) {
256+
print STDERR "ERROR: --follow will not work with --output-format=",$OPT_OUTPUT_FORMAT,"\n";
257+
exit(1);
258+
}
259+
260+
}
176261

177-
#[] t
262+
#[]t
178263
if ($DEBUG_MODE) {
179264
print "SEARCH OPTIONS:\n";
180265
foreach my $opt (sort keys %search_opts) {
181-
print $opt,' => ',$search_opts{opt},"\n";
266+
print $opt,' => ',$search_opts{$opt},"\n";
182267
}
183268
}
184269

185-
186270
eval {
187271
my $drvr = Helios::ObjectDriver->getDriver();
188272
my @logs = $drvr->search('HeliosX::Logger::HiRes::LogEntry' =>
@@ -194,19 +278,51 @@ eval {
194278
@logs = reverse @logs;
195279
}
196280

281+
# we have results; get them to the user
197282
foreach ( @logs ) {
283+
# fix up some of the info to make it presentable
198284
my $tp = localtime $_->log_time;
199285
my ($sec, $fract) = split(/\./, $_->log_time);
200286
my $date = $tp->ymd.' '.$tp->hms.'.'.$fract;
201287
my $jobinfo = $_->jobid ? ' [Jobid '.$_->jobid.']' : '';
202288
$LAST_LOGID = $_->logid;
203-
print $_->logid.' ' if $DEBUG_MODE; #[]t
204-
print '[',$date,'] ',$_->host,' ',$_->service,'[',$_->pid,']: ',$LOG_PRIORITIES[$_->priority],$jobinfo,' ',$_->message,"\n";
205-
}
206-
289+
290+
# output the log message in the format the user asked for
291+
SWITCH: {
292+
293+
# output: JSON
294+
if ($OUTPUT_FORMAT eq 'json') {
295+
296+
my $log_struct = {
297+
logid => $_->logid,
298+
logdate => $date,
299+
host => $_->host,
300+
service => $_->service,
301+
pid => $_->pid,
302+
priority => $LOG_PRIORITIES[$_->priority],
303+
jobid => $_->jobid,
304+
message => $_->message,
305+
};
306+
print encode_json($log_struct),"\n";
307+
last;
308+
}
309+
310+
# output: delimited values
311+
if ($OUTPUT_FORMAT eq 'tab' || $OUTPUT_FORMAT eq 'pipe') {
312+
print $_->logid.$OUTPUT_SEPARATOR if $DEBUG_MODE;
313+
print join($OUTPUT_SEPARATOR => ($date, $_->host, $_->service, $_->pid, $LOG_PRIORITIES[$_->priority], $_->jobid ? $_->jobid : '', $_->message)), "\n";
314+
last;
315+
}
316+
317+
# default output: log
318+
print $_->logid.' ' if $DEBUG_MODE; #[]t
319+
print '[',$date,'] ',$_->host,' ',$_->service,'[',$_->pid,']: ',$LOG_PRIORITIES[$_->priority],$jobinfo,' ',$_->message,"\n";
320+
321+
}
322+
}
207323
1;
208324
} or do {
209-
print STDERR $@,"\n";
325+
print STDERR 'ERROR: ',$@,"\n";
210326
exit (42);
211327
};
212328

@@ -230,10 +346,10 @@ if ($FOLLOW_MODE) {
230346
}
231347
1;
232348
} or do {
233-
print STDERR $@, "\n";
234-
exit(42);
349+
print STDERR 'ERROR: ',$@, "\n";
350+
exit(1);
235351
};
236-
sleep 1;
352+
sleep 5;
237353
}
238354
}
239355

@@ -250,7 +366,7 @@ heliosx_logger_hires_search - search the Helios high resolution log
250366
heliosx_logger_hires_search --jobid=12345
251367
252368
# heliosx_logger_hires_search normally displays only the first 50 messages
253-
# use the -n option to increase/decrease that limit
369+
# use the -n or --lines option to increase/decrease that limit
254370
heliosx_logger_hires_search --jobid=12345 -n 100
255371
256372
# display the last 10 MyService errors, sorted by most recent first
@@ -267,7 +383,7 @@ heliosx_logger_hires_search - search the Helios high resolution log
267383
268384
# display the last 100 log messages logged by MyService,
269385
# then follow the log and display any new MyService messages
270-
heliosx_logger_hires_search --service=MyService --t -n 100 -f
386+
heliosx_logger_hires_search --service=MyService -t -n 100 -f
271387
272388
=head1 DESCRIPTION
273389
@@ -354,7 +470,7 @@ include NOTICE messages logged by the service agent daemon; if you want to
354470
limit the messages to those associated with a particular job, use --service
355471
with the --jobtype switch.
356472
357-
=head2 --priority=priority_name
473+
=head2 --priority=priority_name[,priority_name][,priority_name]...
358474
359475
Display only log messages of a given priority. The priority names are:
360476
@@ -378,6 +494,9 @@ Display only log messages of a given priority. The priority names are:
378494
379495
=back
380496
497+
To search for log messages of multiple, specific priorities, separate them on
498+
the command line by spaces or specify multiple --priority options.
499+
381500
=head1 AUTHOR
382501
383502
Andrew Johnson, E<lt>lajandy at cpan dot orgE<gt>

Diff for: lib/HeliosX/Logger/HiRes.pm

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use Helios::LogEntry::Levels ':all';
1212
use Helios::Error::LoggingError;
1313
use HeliosX::Logger::HiRes::LogEntry;
1414

15-
our $VERSION = '0.10_2751';
15+
our $VERSION = '0.10_3270';
1616

1717
=head1 NAME
1818

0 commit comments

Comments
 (0)