line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Net::Tomcat; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
16462
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
40
|
|
4
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
25
|
|
5
|
|
|
|
|
|
|
|
6
|
1
|
|
|
1
|
|
531
|
use LWP; |
|
1
|
|
|
|
|
37813
|
|
|
1
|
|
|
|
|
34
|
|
7
|
1
|
|
|
1
|
|
471
|
use Net::Tomcat::JVM; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
22
|
|
8
|
1
|
|
|
1
|
|
346
|
use Net::Tomcat::Server; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
31
|
|
9
|
1
|
|
|
1
|
|
331
|
use Net::Tomcat::Connector; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
20
|
|
10
|
1
|
|
|
1
|
|
362
|
use Net::Tomcat::Connector::Scoreboard; |
|
1
|
|
|
|
|
11
|
|
|
1
|
|
|
|
|
23
|
|
11
|
1
|
|
|
1
|
|
423
|
use Net::Tomcat::Connector::Statistics; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
1455
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
our $VERSION = '0.02'; |
14
|
|
|
|
|
|
|
our @ATTR = qw(username password hostname); |
15
|
|
|
|
|
|
|
our $ATTR = { |
16
|
|
|
|
|
|
|
username => { required => 1 }, |
17
|
|
|
|
|
|
|
password => { required => 1 }, |
18
|
|
|
|
|
|
|
hostname => { required => 1 }, |
19
|
|
|
|
|
|
|
port => { required => 0, default => 8080 }, |
20
|
|
|
|
|
|
|
proto => { required => 0, default => 'http' }, |
21
|
|
|
|
|
|
|
app_status_url => { required => 0, default => '/manager/html/list'}, |
22
|
|
|
|
|
|
|
server_status_url => { required => 0, default => '/manager/status/all'}, |
23
|
|
|
|
|
|
|
refresh_interval => { required => 0, default => 3600 }, |
24
|
|
|
|
|
|
|
}; |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
sub new { |
27
|
0
|
|
|
0
|
1
|
|
my ( $class, %args ) = @_; |
28
|
0
|
|
|
|
|
|
my $self = bless {}, $class; |
29
|
|
|
|
|
|
|
|
30
|
0
|
|
|
|
|
|
for ( keys %{ $ATTR } ) { |
|
0
|
|
|
|
|
|
|
31
|
0
|
0
|
0
|
|
|
|
$ATTR->{$_}->{required} and ( defined $args{$_} or die "Mandatory parameter $_ not supplied in constructor\n" ); |
32
|
0
|
|
0
|
|
|
|
$self->{$_} = ( $args{$_} or $ATTR->{$_}->{default} ) |
33
|
|
|
|
|
|
|
} |
34
|
|
|
|
|
|
|
|
35
|
0
|
|
|
|
|
|
$self->{__ua} = LWP::UserAgent->new(); |
36
|
|
|
|
|
|
|
|
37
|
0
|
|
|
|
|
|
return $self |
38
|
|
|
|
|
|
|
} |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
sub __request { |
41
|
0
|
|
|
0
|
|
|
my ( $self, $url ) = @_; |
42
|
|
|
|
|
|
|
|
43
|
0
|
|
|
|
|
|
my $res = $self->{__ua}->get( "$self->{proto}://$self->{username}:$self->{password}" |
44
|
|
|
|
|
|
|
. "\@$self->{hostname}:$self->{port}$url" ); |
45
|
|
|
|
|
|
|
|
46
|
0
|
0
|
|
|
|
|
$res->is_success and return $res->content; |
47
|
|
|
|
|
|
|
|
48
|
0
|
|
|
|
|
|
$self->{error} = 'Unable to retrieve content: ' . $res->status_line; |
49
|
|
|
|
|
|
|
|
50
|
0
|
|
|
|
|
|
return 0 |
51
|
|
|
|
|
|
|
} |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
sub __is_valid { |
54
|
0
|
|
|
0
|
|
|
my ( $self, $o ) = @_; |
55
|
0
|
|
0
|
|
|
|
return ( defined $o and ( time - $o->{__timestamp} < $self->{refresh_interval} ) ? 1 : 0 ) |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
sub server { |
59
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
60
|
0
|
0
|
|
|
|
|
$self->__is_valid( $self->{__server} ) or $self->__get_server_status; |
61
|
0
|
|
|
|
|
|
return $self->{__server} |
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
sub jvm { |
65
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
66
|
0
|
0
|
|
|
|
|
$self->__is_valid( $self->{__jvm} ) or $self->__get_jvm_status; |
67
|
0
|
|
|
|
|
|
return $self->{__jvm} |
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
sub connector { |
71
|
0
|
|
|
0
|
1
|
|
my ( $self, $connector ) = @_; |
72
|
|
|
|
|
|
|
|
73
|
0
|
|
|
|
|
|
for ( $self->connectors ) { |
74
|
0
|
0
|
|
|
|
|
return $_ if ( $_->name eq $connector ) |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
0
|
|
|
|
|
|
warn "Connector '$connector' not defined\n"; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
sub connectors { |
81
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
82
|
0
|
0
|
0
|
|
|
|
defined $self->{__connectors} |
83
|
|
|
|
|
|
|
and ( time - $self->{__connector_timestamp} < $self->{refresh_interval} ) |
84
|
|
|
|
|
|
|
or $self->__get_server_status; |
85
|
|
|
|
|
|
|
|
86
|
0
|
|
|
|
|
|
return @{ $self->{__connectors} } |
|
0
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
sub __get_server_status { |
90
|
0
|
|
|
0
|
|
|
my $self = shift; |
91
|
0
|
|
|
|
|
|
$self->__parse_server_status ( $self->__request( $self->{server_status_url} ) ); |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
sub __get_jvm_status { |
95
|
0
|
|
|
0
|
|
|
my $self = shift; |
96
|
0
|
|
|
|
|
|
$self->__parse_server_status ( $self->__request( $self->{server_status_url} ) ); |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
sub __get_app_list { |
100
|
0
|
|
|
0
|
|
|
my $self = shift; |
101
|
0
|
|
|
|
|
|
my $s = $self->__request( $self->{app_status_url} ) |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
sub __parse_server_status { |
105
|
0
|
|
|
0
|
|
|
my ( $self, $s ) = @_; |
106
|
|
|
|
|
|
|
|
107
|
0
|
0
|
|
|
|
|
grep { /Server Status/ } $s or return ( $self->{error} = 'Unable to retrieve server status' ); |
|
0
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
|
109
|
0
|
|
|
|
|
|
my @c = split /<\/table>/, $s; |
110
|
|
|
|
|
|
|
|
111
|
0
|
|
|
|
|
|
$self->__process_server_information( grep { /Server Information/ } @c ); |
|
0
|
|
|
|
|
|
|
112
|
0
|
|
|
|
|
|
$self->__process_jvm_information( grep { /JVM<\/h1>/ } @c ); |
|
0
|
|
|
|
|
|
|
113
|
0
|
|
|
|
|
|
$self->__process_connector_information( grep { /JVM<\/h1>/ } split /\n/, $s ); |
|
0
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
sub __process_server_information { |
117
|
0
|
|
|
0
|
|
|
my ( $self, $s ) = @_; |
118
|
|
|
|
|
|
|
|
119
|
0
|
|
|
|
|
|
my @c = grep { / |
|
|
0
|
|
|
|
|
|
|
120
|
0
|
|
|
|
|
|
my ( @k, @v, %a ); |
121
|
|
|
|
|
|
|
|
122
|
0
|
|
|
|
|
|
for ( @c ) { |
123
|
0
|
0
|
|
|
|
|
if ( /header-center/ ) { push @k, __strip_and_clean( $_ ) } |
|
0
|
|
|
|
|
|
|
124
|
0
|
0
|
|
|
|
|
if ( /row-center/ ) { push @v, __strip( $_ ) } |
|
0
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
|
127
|
0
|
|
|
|
|
|
@a{ @k } = @v; |
128
|
0
|
|
|
|
|
|
$self->{__server} = Net::Tomcat::Server->new( %a ); |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
sub __process_jvm_information { |
132
|
0
|
|
|
0
|
|
|
my ( $self, $s ) = @_; |
133
|
|
|
|
|
|
|
|
134
|
0
|
|
|
|
|
|
( $s ) = grep { /JVM/ } ( split /<\/p>/, $s ); |
|
0
|
|
|
|
|
|
|
135
|
0
|
|
|
|
|
|
$self->{__jvm} = Net::Tomcat::JVM->new( __extract_fields( $s ) ); |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
sub __process_connector_information { |
139
|
0
|
|
|
0
|
|
|
my ( $self, $s ) = @_; |
140
|
0
|
|
|
|
|
|
my @c = grep { /<\/table>/ } split //, $s; |
|
0
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
|
142
|
0
|
|
|
|
|
|
for ( @c ) { |
143
|
0
|
0
|
|
|
|
|
next unless /<.*/; |
144
|
0
|
|
|
|
|
|
my ( $c_name, $c_stats ) = split /<\/h1>/; |
145
|
0
|
|
|
|
|
|
( $c_stats, my $c_scoreboard ) = split /<\/p>/, $c_stats; |
146
|
0
|
|
|
|
|
|
$c_name = __strip( $c_name ); |
147
|
0
|
|
|
|
|
|
$c_stats = Net::Tomcat::Connector::Statistics->new( __extract_fields( $c_stats ) ); |
148
|
0
|
|
|
|
|
|
$c_scoreboard = __process_scoreboard( $c_scoreboard ); |
149
|
0
|
|
|
|
|
|
push @{ $self->{__connectors} }, |
|
0
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
Net::Tomcat::Connector->new( |
151
|
|
|
|
|
|
|
name => $c_name, |
152
|
|
|
|
|
|
|
stats => $c_stats, |
153
|
|
|
|
|
|
|
scoreboard => $c_scoreboard |
154
|
|
|
|
|
|
|
); |
155
|
0
|
|
|
|
|
|
$self->{__connector_timestamp} = time; |
156
|
|
|
|
|
|
|
} |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
sub __process_scoreboard { |
160
|
0
|
|
|
0
|
|
|
my $s = shift; |
161
|
0
|
|
|
|
|
|
my @c = grep { !/<\/table>/ } split /<\/tr>/, $s; |
|
0
|
|
|
|
|
|
|
162
|
0
|
|
|
|
|
|
my @v = split /<\/th>/, ( shift @c ); |
163
|
0
|
|
|
|
|
|
@v = [ map { __strip_and_clean( $_ ) } @v ]; |
|
0
|
|
|
|
|
|
|
164
|
0
|
|
|
|
|
|
my ( %a ); |
165
|
|
|
|
|
|
|
|
166
|
0
|
|
|
|
|
|
for ( @c ) { |
167
|
0
|
|
|
|
|
|
my @f = split /<\/td>/; |
168
|
0
|
|
|
|
|
|
@f = map { __strip( $_ ) } @f; |
|
0
|
|
|
|
|
|
|
169
|
0
|
|
|
|
|
|
push @v, [ @f ] |
170
|
|
|
|
|
|
|
} |
171
|
|
|
|
|
|
|
|
172
|
0
|
|
|
|
|
|
return Net::Tomcat::Connector::Scoreboard->new( @v ) |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
sub __extract_fields { |
176
|
0
|
|
|
0
|
|
|
my $s = shift; |
177
|
0
|
|
|
|
|
|
$s =~ s/([A-Z]{1}[a-z]{1})/_$1/g; |
178
|
0
|
|
|
|
|
|
my @c = ( split /_/, $s ); |
179
|
0
|
|
|
|
|
|
my ( @k, @v, %a ); |
180
|
|
|
|
|
|
|
|
181
|
0
|
|
|
|
|
|
for ( @c ) { |
182
|
0
|
|
|
|
|
|
my ( $k, $v ) = split /:/; |
183
|
0
|
0
|
0
|
|
|
|
next unless $k and $v; |
184
|
0
|
|
|
|
|
|
push @k, __strip_and_clean( $k ); |
185
|
0
|
|
|
|
|
|
push @v, __strip( $v ); |
186
|
|
|
|
|
|
|
} |
187
|
|
|
|
|
|
|
|
188
|
0
|
|
|
|
|
|
@a{ @k } = @v; |
189
|
0
|
|
|
|
|
|
return %a |
190
|
|
|
|
|
|
|
} |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
sub __strip { |
193
|
0
|
|
|
0
|
|
|
my $s = shift; |
194
|
0
|
|
|
|
|
|
$s =~ s|<.+?>||g; |
195
|
0
|
|
|
|
|
|
$s =~ s/^\s+|\s+$//g; |
196
|
0
|
|
|
|
|
|
return $s |
197
|
|
|
|
|
|
|
} |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
sub __strip_and_clean { |
200
|
0
|
|
|
0
|
|
|
my $s = shift; |
201
|
0
|
|
|
|
|
|
$s = __strip( $s ); |
202
|
0
|
|
|
|
|
|
$s =~ s| |_|g; |
203
|
0
|
|
|
|
|
|
$s = lc( $s ); |
204
|
0
|
|
|
|
|
|
return $s |
205
|
|
|
|
|
|
|
} |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
1; |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
__END__ |