Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / network / fms @ dd4afac8

Historique | Voir | Annoter | Télécharger (11,4 ko)

1 0e917431 Zsolt M?ller
#!/usr/bin/perl -w
2
#
3
# Plugin to monitor Flash Media Server connections.
4
#
5
# Parameters:
6
#
7
#       config   (required)
8
#       autoconf (optional - only used by munin-config)
9
#
10
# Requirements:
11
#
12
#       libwww-perl (LWP) Perl library
13
#	      Proc::ProcessTable Perl module
14
#
15
# Tested with:
16
#       Debian 4.x ("Etch")
17
#       Macromedia Flash Media Server 2.0.3 r68
18
#       Adobe Flash Media Server 3.0.1 r123
19
#       Adobe Flash Media Server 3.5.0 r405
20
#
21
# $Log$
22
# Revision 2.1  2009/02/15 19:45:12  muzso
23
# Added option to get stats based on netstat's output instead of FMS Admin
24
# server. Rewrote usage documentation for easier and quicker reading.
25
#
26
# Revision 2.0  2009/01/24 20:03:23  muzso
27
# Completely rewritten. Added ability to autoconfigure, added inline
28
# documentation and brought to the standard of core Munin plugins.
29
#
30
# Revision 1.0  2007/09/12 18:14:43  Johan MATHE
31
# Initial release.
32
#
33
# Usage
34
# -----
35
#
36
# The plugin supports two methods for collecting network connection statistics
37
# for the Flash Media Server:
38
#
39
# a.) Using the getServerStats() call of the HTTP API of Flash Media
40
#     Administration Server. (This is the default.)
41
#
42
# b.) Using the "netstat" command (available on all sorts of Linux/Unix
43
#     operating systems).
44
#
45
# You can configure the plugin to use the latter method by adding the
46
# "use_netstat" variable to the [fms] section in the Munin node plugin config
47
# file.
48
# Eg.
49
#   [fms]
50
#   env.use_netstat yes
51
#
52
# IMHO the netstat method provides a lot more realistic number for FMS
53
# connections, but I kept the FMS Admin stat method as default since that's
54
# the "Adobe supported" way.
55
#
56
# Moreover you can use the plugin with autoconfiguration or by manually
57
# supplying the required parameters (as variables in the Munin node plugin
58
# config file).
59
#
60
# To use autoconfiguration, you've to run the plugin with root privileges, thus
61
# specify the user in the Munin node plugin config file.
62
# So the least you've to do to make this work is to create an [fms] section
63
# in the node plugin config and add "user root".
64
# Eg.
65
#   [fms]
66
#   user root
67
#
68
# For autoconfiguration you'll also need the following Perl module:
69
#
70
#   Proc::ProcessTable - Perl extension to access the unix process table
71
#   http://search.cpan.org/perldoc?Proc::ProcessTable 
72
#
73
# On a Debian/Ubuntu system you can install this with the following command
74
# (if APT is configured properly):
75
#   apt-get install libproc-process-perl
76
#
77
# In Ubuntu and recent Debian (Lenny and later) versions this is renamed to
78
# libproc-processtable-perl, but for now (at the time of writing)
79
# libproc-process-perl still exists as a dummy package to provide backward
80
# compatibility.
81
#
82
# If you're using the default statistic fetching method (the call to the FMS
83
# Admin Server HTTP API), then you'll also need the following Perl module:
84
#
85
#   LWP - The World-Wide Web library for Perl
86
#   Used modules: HTTP::Request, LWP::Simple, LWP::UserAgent
87
#   http://search.cpan.org/perldoc?LWP
88
#
89
# On a Debian/Ubuntu system you can install this with the following command
90
# (if APT is configured properly):
91
#   apt-get install libwww-perl
92
#
93
# For access to the FMS Admin HTTP API you've to publish the "getServerStats()"
94
# call. This means that you've to set "USERS.HTTPCOMMAND_ALLOW" to "true" in
95
# ${FMS_DIR}/conf/fms.ini and in ${FMS_DIR}/conf/Users.xml set the value of the
96
# node "Root/AdminServer/HTTPCommands/Allow" to contain "getServerStats" too
97
# (by default it allows only "ping").
98
#
99
# That's all you've to know about the default (autoconfiguration) method of
100
# running this plugin.
101
#
102
#
103
# As for manual configuration ...
104
#
105
# Follow this example plugin entry in the Munin node plugin config to specify
106
# the FMS Admin server parameters:
107
#   [fms]
108
#   env.fms_admin_host localhost
109
#   env.fms_admin_port 1111
110
#   env.fms_admin_username admin
111
#   env.fms_admin_password the_admin_password
112
#
113
#   Usually fms_admin_host will be localhost (since most people want to monitor
114
#   a local instance of FMS), but of course you can set it to any hostname.
115
#
116
#   It is strongly advised that you restrict access to the Munin node plugin
117
#   config file. It should be readable only by the Munin node daemon since your
118
#   FMS admin password should not be accessible by any other user.
119
#   In case of Debian/Ubuntu the /etc/munin/plugin-conf.d/munin-node file is
120
#   owned by root and the munin-node process runs with root privileges, so the
121
#   correct permission is to have the file readable only by root.
122
#
123
# Manual configuration of the netstat method requires the following Munin node
124
# plugin config:
125
#   [fms]
126
#   env.use_netstat yes
127
#   env.fms_host 192.168.0.1
128
#   env.fms_port 1935
129
#
130
#   The fms_host variable can be skipped if your FMS server listens on all IPs
131
#   and not just a single IP.
132
#   The fms_port variable must contain a comma-separated list of TCP ports that
133
#   your FMS server listens on for incoming connections.
134
#   In a default FMS installation this is the 1935 TCP port, but it can be
135
#   an arbitrary list (eg. 1935,80,443).
136
#
137
#
138
# Note: autoconfiguration works by going through the list of running processes
139
#       and looking for the "fmsadmin" process. If found, we check for the
140
#       existence of the "conf/fms.ini" file in the current working directory
141
#       of the process. This works fine for all tested FMS versions.
142
#       However it is possible that this method is not "universal" enough
143
#       (and it requires the plugin to be run as root too) so using the manual
144
#       configuration is always there as a backup solution.
145
#       The manual config method does not require root privileges for the plugin
146
#       to work.
147
#
148
#       In case something "bad" happens (eg. plugin is run as non-root and
149
#       autoconfiguration is used) the plugin writes some informative message
150
#       to stderr to make debugging easier. This should not affect the normal
151
#       operation of munin-node since only the stdout of the plugins is used
152
#       and that's always kept as munin-node expects.
153
#
154
#
155
#
156
# Magic markers (optional - used by munin-config and installation scripts):
157
#
158
#%# family=auto
159
#%# capabilities=autoconf
160
161
162
163
use strict;
164
use LWP::UserAgent;
165
use LWP::Simple;
166
use Proc::ProcessTable;
167
168
if ( defined($ARGV[0]) and $ARGV[0] eq "config" ) {
169
	print <<'END_CONFIG';
170
graph_title Flash Media Server socket connections
171
graph_args -l 0 --base 1000
172
graph_vlabel active connections
173
graph_category network
174
graph_period second
175
graph_info This graph shows the number of active socket connections to the Flash Media Server.
176
fmserv_c.label connections
177
fmserv_c.type GAUGE
178
fmserv_c.min 0
179
END_CONFIG
180
	exit 0;
181
}
182
183
my ($usenetstat, $fmshost, $fmsport, $adminhost, $adminport, $adminusername, $adminpassword);
184
185
if ( defined($ENV{use_netstat}) and length($ENV{use_netstat}) > 0 and lc($ENV{use_netstat}) ne "no") {
186
	$usenetstat = "yes";
187
} else {
188
	$usenetstat = "no";
189
}
190
if ( defined($ENV{fms_host}) and length($ENV{fms_host}) > 0 ) {
191
	$fmshost = $ENV{fms_host};
192
}
193
if ( defined($ENV{fms_port}) and length($ENV{fms_port}) > 0 ) {
194
	$fmsport = $ENV{fms_port};
195
}
196
if ( defined($ENV{fms_admin_host}) and length($ENV{fms_admin_host}) > 0 ) {
197
	$adminhost = $ENV{fms_admin_host};
198
}
199
if ( defined($ENV{fms_admin_port}) and length($ENV{fms_admin_port}) > 0 ) {
200
	$adminport = $ENV{fms_admin_port};
201
}
202
if ( defined($ENV{fms_admin_username}) and length($ENV{fms_admin_username}) > 0 ) {
203
	$adminusername = $ENV{fms_admin_username};
204
}
205
if ( defined($ENV{fms_admin_password}) and length($ENV{fms_admin_password}) > 0 ) {
206
	$adminpassword = $ENV{fms_admin_password};
207
}
208
209
if ( !( ( $usenetstat eq "yes" and defined($fmshost) and defined($fmsport) ) or ( $usenetstat eq "no" and defined($adminhost) and defined($adminport) and defined($adminusername) and defined($adminpassword) ) ) ) {
210
	# Autoconfiguration:
211
	# 1. Find the "fmsadmin" process and assume that FMS is installed in the
212
	#    current working directory of the process.
213
	# 2. Look for the FMS config file in ${FMS_DIR}/conf/fms.ini.
214
	# 3. Fetch host, port, admin username and password values from the
215
	#    config file.
216
	
217
	# check that plugin is running with root privileges
218
	if ( $> == 0 ) {
219
		my $ProcTable = new Proc::ProcessTable;
220
		PROC_LOOP: foreach my $proc (@{$ProcTable->table}) {
221
			# match any filename starting with "fmsadmin"
222
			# (this way the plugin might work on platforms other
223
			#  than linux too)
224
			if ( defined($proc->{fname}) and $proc->{fname} =~ /^fmsadmin/i and defined($proc->{cwd}) ) {
225
				my $fms_config = $proc->{cwd} . "/conf/fms.ini";
226
				if ( open(my $fp, '<', $fms_config) ) {
227
					while (my $line = <$fp>) {
228
						chomp($line);
229
						if ( $line =~ /^ *SERVER\.ADMIN_USERNAME *= *([^ ].*) *$/ ) {
230
							$adminusername = $1;
231
						} elsif ( $line =~ /^ *SERVER\.ADMIN_PASSWORD *= *([^ ].*) *$/ ) {
232
							$adminpassword = $1;
233
						} elsif ( $line =~ /^ *SERVER\.ADMINSERVER_HOSTPORT *= *([^ ]*)/ ) {
234
							my @data = split(":", $1);
235
							if ( $#data > 0 ) {
236
								if ( defined($data[0]) and length($data[0]) > 0 ) {
237
									$adminhost = $data[0];
238
								} else {
239
									$adminhost = "localhost";
240
								}
241
								$adminport = $data[1];
242
							}
243
						} elsif ( $line =~ /^ *ADAPTOR\.HOSTPORT *= *([^ ]*)/ ) {
244
							my @data = split(":", $1);
245
							if ( $#data > 0 ) {
246
								if ( defined($data[0]) and length($data[0]) > 0 ) {
247
									$fmshost = $data[0];
248
								} else {
249
									$fmshost = "";
250
								}
251
								$fmsport = $data[1];
252
							}
253
						}
254
						# exit the loop if we've got all parameters
255
						last PROC_LOOP if ( $usenetstat eq "yes" and defined($fmshost) and defined($fmsport) ) or ( $usenetstat eq "no" and defined($adminhost) and defined($adminport) and defined($adminusername) and defined($adminpassword) );
256
					}
257
				} else {
258
					print(STDERR "Can't open FMS config file (" . $fms_config . "): $!\n");
259
				}
260
				# exit the loop since we've already found the process
261
				# that we were looking for, we just failed to find
262
				# all required parameters in fms.ini (or failed to
263
				# find fms.ini at all in (cwd of fmsadmin)/conf
264
				last PROC_LOOP;
265
			}
266
		}
267
	} else {
268
		print(STDERR "Plugin must be run with root privileges for autoconfiguration to work!\n");
269
	}
270
}
271
272
if ( defined($ARGV[0]) and $ARGV[0] eq "autoconf" ) {
273
	if ( ( $usenetstat eq "yes" and defined($fmshost) and defined($fmsport) ) or ( $usenetstat eq "no" and defined($adminhost) and defined($adminport) and defined($adminusername) and defined($adminpassword) ) ) {
274
		print("yes\n");
275
		exit 0;
276
	} else {
277
		print("no\n");
278
		exit 1;
279
	}
280
}
281
282
if ( $usenetstat eq "yes" and defined($fmshost) and defined($fmsport) ) {
283
	$fmsport =~ s/,/|/g;
284
	my $sockets = `netstat -n`;
285
	my $regex = ":(" . $fmsport . ")[^0-9]+[^:]*:[0-9]+[^0-9]+.*ESTABLISHED";
286
	if ( defined($fmshost) and length($fmshost) > 0 ) {
287
		$fmshost =~ s/\./\\./g;
288
		$regex = $fmshost . $regex;
289
	}
290
	my $count = 0;
291
	while ( $sockets =~ /$regex/g ) {
292
		$count++;
293
	}
294
	print("fmserv_c.value ${count}\n");
295
} elsif ( $usenetstat eq "no" and defined($adminhost) and defined($adminport) and defined($adminusername) and defined($adminpassword) ) {
296
	my $ua = LWP::UserAgent->new(timeout => 30);
297
	my $url = sprintf("http://%s:%d/admin/getServerStats?auser=%s\&apswd=%s", $adminhost, $adminport, $adminusername, $adminpassword);
298
299
	my $response = $ua->request(HTTP::Request->new('GET', $url));
300
301
	if ( $response->content =~ /<io>.*<connected>[^0-9]*([0-9]+)[^0-9]*<\/connected>.*<\/io>/is ) {
302
		print("fmserv_c.value $1\n");
303
	} else {
304
		print("fmserv_c.value U\n");
305
	}
306
} else {
307
	print(STDERR "Failed to get all parameters needed for the connection to the Flash Media Administration Server!\n");
308
	print("fmserv_c.value U\n");
309
}