Project

General

Profile

Download (29.2 KB) Statistics
| Branch: | Tag: | Revision:
1 b0a5b824 Seth Mos
<?php
2
/* $Id$ */
3
/*
4
  Copyright (C) 2008 Seth Mos
5
  All rights reserved.
6
7
  Redistribution and use in source and binary forms, with or without
8
  modification, are permitted provided that the following conditions are met:
9
10
1. Redistributions of source code must retain the above copyright notice,
11
  this list of conditions and the following disclaimer.
12
13
  2. Redistributions in binary form must reproduce the above copyright
14
  notice, this list of conditions and the following disclaimer in the
15
  documentation and/or other materials provided with the distribution.
16
17
  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18
  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19
  AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20
  AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
21
  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
  POSSIBILITY OF SUCH DAMAGE.
27
28
  */
29
30 523855b0 Scott Ullrich
/*
31
	pfSense_BUILDER_BINARIES:	/bin/rm	/usr/bin/nice	/usr/local/bin/rrdtool	/bin/cd
32
	pfSense_MODULE:	rrd
33
*/
34
35 b0a5b824 Seth Mos
/* include all configuration functions */
36
37
function dump_rrd_to_xml($rrddatabase, $xmldumpfile) {
38 d9acea75 Scott Ullrich
	$rrdtool = "/usr/bin/nice -n20 /usr/local/bin/rrdtool";
39 1b25fc27 Seth Mos
	if(file_exists($xmldumpfile))
40 e256e9d4 smos
		mwexec("rm {$xmldumpfile}");
41 1b25fc27 Seth Mos
42 b0a5b824 Seth Mos
	exec("$rrdtool dump {$rrddatabase} {$xmldumpfile} 2>&1", $dumpout, $dumpret);
43
	if ($dumpret <> 0) {
44
		$dumpout = implode(" ", $dumpout);
45 adc986ed Seth Mos
		log_error("RRD dump failed exited with $dumpret, the error is: $dumpout");
46 b0a5b824 Seth Mos
	}
47
	return($dumpret);
48
}
49
50
function create_new_rrd($rrdcreatecmd) {
51
	$rrdcreateoutput = array();
52
	$rrdcreatereturn = 0;
53
	exec("$rrdcreatecmd 2>&1", $rrdcreateoutput, $rrdcreatereturn);
54
	if ($rrdcreatereturn <> 0) {
55
		$rrdcreateoutput = implode(" ", $rrdcreateoutput);
56 adc986ed Seth Mos
		log_error("RRD create failed exited with $rrdcreatereturn, the error is: $rrdcreateoutput");
57 b0a5b824 Seth Mos
	}
58
	return $rrdcreatereturn;
59
}
60
61
function migrate_rrd_format($rrdoldxml, $rrdnewxml) {
62 fdd20aba Scott Ullrich
	if(!file_exists("/tmp/rrd_notice_sent.txt")) {
63
		exec("echo 'Converting RRD configuration to new format.  This might take a bit...' | wall");
64
		touch("/tmp/rrd_notice_sent.txt");
65
	}
66 b0a5b824 Seth Mos
	$numrraold = count($rrdoldxml['rra']);
67
	$numdsold = count($rrdoldxml['ds']);
68
	$numrranew = count($rrdnewxml['rra']);
69
	$numdsnew = count($rrdnewxml['ds']);
70 adc986ed Seth Mos
	log_error("Import RRD has $numdsold DS values and $numrraold RRA databases, new format RRD has $numdsnew DS values and $numrranew RRA databases");
71 b0a5b824 Seth Mos
	
72
	/* add data sources not found in the old array from the new array */
73
	$i = 0;
74
	foreach($rrdnewxml['ds'] as $ds) {
75
		if(!is_array($rrdoldxml['ds'][$i])) {
76
			$rrdoldxml['ds'][$i] = $rrdnewxml['ds'][$i];
77 d9e896fa Seth Mos
			/* set unknown values to 0 */
78
			$rrdoldxml['ds'][$i]['last_ds'] = " 0.0000000000e+00 ";
79
			$rrdoldxml['ds'][$i]['value'] = " 0.0000000000e+00 ";
80
			$rrdoldxml['ds'][$i]['unknown_sec'] = "0";
81 b0a5b824 Seth Mos
		}
82
		$i++;
83
	}
84
85
	$i = 0;
86
	$rracountold = count($rrdoldxml['rra']);
87
	$rracountnew = count($rrdnewxml['rra']);
88
	/* process each RRA, which contain a database */
89
	foreach($rrdnewxml['rra'] as $rra) {
90
		if(!is_array($rrdoldxml['rra'][$i])) {
91
			$rrdoldxml['rra'][$i] = $rrdnewxml['rra'][$i];
92
		}
93
94
		$d = 0;
95
		/* process cdp_prep */
96
		$cdp_prep = $rra['cdp_prep'];
97
		foreach($cdp_prep['ds'] as $ds) {
98
			if(!is_array($rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d])) {
99
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d] = $rrdnewxml['rra'][$i]['cdp_prep']['ds'][$d];
100 d9e896fa Seth Mos
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['primary_value'] = " 0.0000000000e+00 ";
101
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['secondary_value'] = " 0.0000000000e+00 ";
102
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['value'] = " 0.0000000000e+00 ";
103
				$rrdoldxml['rra'][$i]['cdp_prep']['ds'][$d]['unknown_datapoints'] = "0";
104 b0a5b824 Seth Mos
			}
105
			$d++;
106
		}
107
108
		/* process database */
109
		$rows = $rra['database'];
110
		$k = 0;
111
		$rowcountold = count($rrdoldxml['rra'][$i]['database']['row']);
112
		$rowcountnew = count($rrdnewxml['rra'][$i]['database']['row']);
113 ddc26847 Seth Mos
		$rowcountdiff = $rowcountnew - $rowcountold;
114
		/* save old rows for a bit before we put the required empty rows before it */
115
		$rowsdata = $rows;
116
		$rowsempty = array();
117
		$r = 0;
118 ae4dce62 Seth Mos
		while($r < $rowcountdiff) {
119 ddc26847 Seth Mos
			$rowsempty[] = $rrdnewxml['rra'][$i]['database']['row'][$r];
120
			$r++;
121
		}
122
		$rows = $rowsempty + $rowsdata;
123 b0a5b824 Seth Mos
		/* now foreach the rows in the database */
124
		foreach($rows['row'] as $row) {
125
			if(!is_array($rrdoldxml['rra'][$i]['database']['row'][$k])) {
126
				$rrdoldxml['rra'][$i]['database']['row'][$k] = $rrdnewxml['rra'][$i]['database']['row'][$k];
127
			}
128
			$m = 0;
129
			$vcountold = count($rrdoldxml['rra'][$i]['database']['row'][$k]['v']);
130
			$vcountnew = count($rrdnewxml['rra'][$i]['database']['row'][$k]['v']);
131
			foreach($row['v'] as $value) {
132
				if(empty($rrdoldxml['rra'][$i]['database']['row'][$k]['v'][$m])) {
133 ed3ea464 Seth Mos
					if(isset($valid)) {
134
						$rrdoldxml['rra'][$i]['database']['row'][$k]['v'][$m] = "0.0000000000e+00 ";
135
					} else {
136
						$rrdoldxml['rra'][$i]['database']['row'][$k]['v'][$m] = $rrdnewxml['rra'][$i]['database']['row'][$k]['v'][$m];
137
					}
138
				} else {
139
					if($value <> " NaN ") {
140
						$valid = true;
141
					} else {
142
						$valid = false;
143
					}
144 b0a5b824 Seth Mos
				}
145
				$m++;
146
			}
147
			$k++;
148
		}
149
		$i++;
150
	}
151
152
	$numrranew = count($rrdoldxml['rra']);
153
	$numdsnew = count($rrdoldxml['ds']);
154 adc986ed Seth Mos
	log_error("The new RRD now has $numdsnew DS values and $numrranew RRA databases");
155 b0a5b824 Seth Mos
	return $rrdoldxml;
156
}
157
158 ea4bc46f Seth Mos
function enable_rrd_graphing() {
159
	global $config, $g, $altq_list_queues;
160
161
	if($g['booting']) 
162
		echo "Generating RRD graphs...";
163
164
	$rrddbpath = "/var/db/rrd/";
165
	$rrdgraphpath = "/usr/local/www/rrd";
166
167
	$traffic = "-traffic.rrd";
168
	$packets = "-packets.rrd";
169
	$states = "-states.rrd";
170
	$wireless = "-wireless.rrd";
171
	$queues = "-queues.rrd";
172
	$queuesdrop = "-queuedrops.rrd";
173
	$spamd = "-spamd.rrd";
174
	$proc = "-processor.rrd";
175
	$mem = "-memory.rrd";
176 ec51a222 thompsa
	$cellular = "-cellular.rrd";
177 ea4bc46f Seth Mos
178 d9acea75 Scott Ullrich
	$rrdtool = "/usr/bin/nice -n20 /usr/local/bin/rrdtool";
179 ea4bc46f Seth Mos
	$netstat = "/usr/bin/netstat";
180
	$awk = "/usr/bin/awk";
181
	$tar = "/usr/bin/tar";
182
	$pfctl = "/sbin/pfctl";
183
	$sysctl = "/sbin/sysctl";
184
	$php = "/usr/local/bin/php";
185
	$top = "/usr/bin/top";
186
	$spamd_gather = "/usr/local/bin/spamd_gather_stats.php";
187
	$ifconfig = "/sbin/ifconfig";
188
189
	$rrdtrafficinterval = 60;
190
	$rrdwirelessinterval = 60;
191
	$rrdqueuesinterval = 60;
192
	$rrdqueuesdropinterval = 60;
193
	$rrdpacketsinterval = 60;
194
	$rrdstatesinterval = 60;
195
	$rrdspamdinterval = 60;
196
	$rrdlbpoolinterval = 60;
197
	$rrdprocinterval = 60;
198
	$rrdmeminterval = 60;
199 ec51a222 thompsa
	$rrdcellularinterval = 60;
200 ea4bc46f Seth Mos
201
	$trafficvalid = $rrdtrafficinterval * 2;
202
	$wirelessvalid = $rrdwirelessinterval * 2;
203
	$queuesvalid = $rrdqueuesinterval * 2;
204
	$queuesdropvalid = $rrdqueuesdropinterval * 2;
205
	$packetsvalid = $rrdpacketsinterval * 2;
206
	$statesvalid = $rrdstatesinterval*2;
207
	$spamdvalid = $rrdspamdinterval * 2;
208
	$lbpoolvalid = $rrdlbpoolinterval * 2;
209
	$procvalid = $rrdlbpoolinterval * 2;
210
	$memvalid = $rrdmeminterval * 2;
211 ec51a222 thompsa
	$cellularvalid = $rrdcellularinterval * 2;
212 ea4bc46f Seth Mos
213
	/* Asume GigE for now */
214
	$downstream = 125000000;
215
	$upstream = 125000000;
216
217
	/* read the shaper config */
218
	read_altq_config();
219
220
	$rrdrestore = "";
221
	$rrdreturn = "";
222
223
	if (isset ($config['rrd']['enable'])) {
224
225
		/* create directory if needed */
226
		if (!is_dir("$rrddbpath")) {
227
			mkdir("$rrddbpath", 0755);
228
		}
229
230
		if ($g['booting']) {
231
			if ($g['platform'] != "pfSense") {
232
				/* restore the databases, if we have one */
233
				if (file_exists("{$g['cf_conf_path']}/rrd.tgz")) {
234
					exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/rrd.tgz 2>&1", $rrdrestore, $rrdreturn);
235
					$rrdrestore = implode(" ", $rrdrestore);
236
					if($rrdreturn <> 0) {
237
						log_error("RRD restore failed exited with $rrdreturn, the error is: $rrdrestore\n");
238
					}
239
				}
240
			}
241
		}
242
243
		/* db update script */
244
		$rrdupdatesh = "#!/bin/sh\n";
245
		$rrdupdatesh .= "\n";
246
		$rrdupdatesh .= "counter=1\n";
247
		$rrdupdatesh .= "while [ \"\$counter\" -ne 0 ]\n";
248
		$rrdupdatesh .= "do\n";
249
		$rrdupdatesh .= "";
250
251
		$i = 0;
252 4563d12f Seth Mos
		$ifdescrs = get_configured_interface_with_descr();
253
		$ifdescrs['ipsec'] = "IPsec";
254
255
		foreach ($ifdescrs as $ifname => $ifdescr) {
256 65615d89 Seth Mos
			$temp = get_real_interface($ifname);
257
			if($temp <> "") {
258
				$realif = $temp;
259
			}
260 ea4bc46f Seth Mos
261
			/* TRAFFIC, set up the rrd file */
262
			if (!file_exists("$rrddbpath$ifname$traffic")) {
263
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$traffic --step $rrdtrafficinterval ";
264
				$rrdcreate .= "DS:inpass:COUNTER:$trafficvalid:0:$downstream ";
265
				$rrdcreate .= "DS:outpass:COUNTER:$trafficvalid:0:$upstream ";
266
				$rrdcreate .= "DS:inblock:COUNTER:$trafficvalid:0:$downstream ";
267
				$rrdcreate .= "DS:outblock:COUNTER:$trafficvalid:0:$upstream ";
268
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
269
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
270
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
271 e8021eea Seth Mos
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
272 ea4bc46f Seth Mos
273
				create_new_rrd($rrdcreate);
274
			}
275
276
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
277
			if($g['booting']) {
278 e256e9d4 smos
				mwexec("$rrdtool update $rrddbpath$ifname$traffic N:U:U:U:U");
279 ea4bc46f Seth Mos
			}
280
281
			$rrdupdatesh .= "\n";
282
			$rrdupdatesh .= "# polling traffic for interface $ifname $realif \n";
283
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$traffic N:\\\n";
284
			$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '/In4\/Pass|Out4\/Pass/ {printf \$6 \":\"}'`\\\n";
285
			$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '/In4\/Block|Out4\/Block/ {printf \$6 \":\"}'|sed -e 's/.\$//'`\n";
286
287
			/* PACKETS, set up the rrd file */
288
			if (!file_exists("$rrddbpath$ifname$packets")) {
289
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$packets --step $rrdpacketsinterval ";
290
				$rrdcreate .= "DS:inpass:COUNTER:$packetsvalid:0:$downstream ";
291
				$rrdcreate .= "DS:outpass:COUNTER:$packetsvalid:0:$upstream ";
292
				$rrdcreate .= "DS:inblock:COUNTER:$packetsvalid:0:$downstream ";
293
				$rrdcreate .= "DS:outblock:COUNTER:$packetsvalid:0:$upstream ";
294
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
295
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
296
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
297 e8021eea Seth Mos
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
298 ea4bc46f Seth Mos
299
				create_new_rrd($rrdcreate);
300
			}
301
302
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
303
			if($g['booting']) {
304 e256e9d4 smos
				mwexec("$rrdtool update $rrddbpath$ifname$packets N:U:U:U:U");
305 ea4bc46f Seth Mos
			}
306
307
			$rrdupdatesh .= "\n";
308
			$rrdupdatesh .= "# polling packets for interface $ifname $realif \n";
309
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$packets N:\\\n";
310
			$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '/In4\/Pass|Out4\/Pass/ {printf \$4 \":\"}'`\\\n";
311
			$rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '/In4\/Block|Out4\/Block/ {printf \$4 \":\"}'|sed -e 's/.\$//'`\n";
312
313
			/* WIRELESS, set up the rrd file */
314
			if($config['interfaces'][$ifname]['wireless']['mode'] == "bss") {
315
				if (!file_exists("$rrddbpath$ifname$wireless")) {
316
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$wireless --step $rrdwirelessinterval ";
317
					$rrdcreate .= "DS:snr:GAUGE:$wirelessvalid:0:1000 ";
318
					$rrdcreate .= "DS:rate:GAUGE:$wirelessvalid:0:1000 ";
319
					$rrdcreate .= "DS:channel:GAUGE:$wirelessvalid:0:1000 ";
320
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
321
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
322
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
323 e8021eea Seth Mos
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
324 ea4bc46f Seth Mos
	
325
					create_new_rrd($rrdcreate);
326
				}
327
328
				/* enter UNKNOWN values in the RRD so it knows we rebooted. */
329
				if($g['booting']) {
330 e256e9d4 smos
					mwexec("$rrdtool update $rrddbpath$ifname$wireless N:U:U:U");
331 ea4bc46f Seth Mos
				}
332
333
				$rrdupdatesh .= "\n";
334
				$rrdupdatesh .= "# polling wireless for interface $ifname $realif \n";
335
				$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$wireless N:\\\n";
336 3e7dfc05 Seth Mos
				$rrdupdatesh .= "`$ifconfig {$realif} list sta| $awk 'gsub(\"M\", \"\") {getline 2;print substr(\$5, 0, length(\$5)-2) \":\" $4 \":\" $3}'`\n";
337 ea4bc46f Seth Mos
			}
338
339
				/* QUEUES, set up the queues databases */
340
				if ($altq_list_queues[$ifname]) {
341
					$altq =& $altq_list_queues[$ifname];
342
					/* NOTE: Is it worth as its own function?! */
343
					switch ($altq->GetBwscale()) {
344
                                        case "Gb":
345
                                        	$factor = 1024 * 1024 * 1024;
346
                                                break;
347
                                        case "Mb":
348
                                                $factor = 1024 * 1024;
349
                                                break;
350
                                        case "Kb":
351
                                                $factor = 1024;
352
                                                break;
353
                                        case "b":
354
                                        default:
355
                                                $factor = 1;
356
                                                break;
357
                                        }
358
					$qbandwidth = $altq->GetBandwidth() * $factor;
359
					if ($qbandwidth <=0)
360
						$qbandwidth = 100 * 1000 * 1000; /* 100Mbit */
361
					$qlist =& $altq->get_queue_list($notused);
362
					if (!file_exists("$rrddbpath$ifname$queues")) {
363
						$rrdcreate = "$rrdtool create $rrddbpath$ifname$queues --step $rrdqueuesinterval ";
364
						/* loop list of shaper queues */
365
						$q = 0;
366
						foreach ($qlist as $qname => $q) {
367
							$rrdcreate .= "DS:$qname:COUNTER:$queuesvalid:0:$qbandwidth ";
368
						}
369
370
						$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
371
						$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
372
						$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
373 e8021eea Seth Mos
						$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
374 ea4bc46f Seth Mos
375
						create_new_rrd($rrdcreate);
376
					}
377
378
					if (!file_exists("$rrddbpath$ifname$queuesdrop")) {
379
						$rrdcreate = "$rrdtool create $rrddbpath$ifname$queuesdrop --step $rrdqueuesdropinterval ";
380
						/* loop list of shaper queues */
381
						$q = 0;
382
						foreach ($qlist as $qname => $q) {
383
							$rrdcreate .= "DS:$qname:COUNTER:$queuesdropvalid:0:$qbandwidth ";
384
						}
385
386
						$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
387
						$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
388
						$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
389 e8021eea Seth Mos
						$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
390 ea4bc46f Seth Mos
391
						create_new_rrd($rrdcreate);
392
					}
393
394
					if($g['booting']) {
395
						$rrdqcommand = "-t ";
396
						$rrducommand = "N";
397
						$q = 0;
398
						foreach ($qlist as $qname => $q) {
399
							if($q == 0) {
400
								$rrdqcommand .= "{$qname}";
401
							} else {
402
								$rrdqcommand .= ":{$qname}";
403
							}
404
							$q++;
405
							$rrducommand .= ":U";
406
						}
407
						mwexec("$rrdtool update $rrddbpath$ifname$queues $rrdqcommand $rrducommand");
408
						mwexec("$rrdtool update $rrddbpath$ifname$queuesdrop $rrdqcommand $rrducommand");
409
					}
410
411
					/* awk function to gather shaper data */
412
					/* yes, it's special */
413
					$rrdupdatesh .= "` pfctl -vsq -i {$realif} | awk 'BEGIN {printf \"$rrdtool update $rrddbpath$ifname$queues \" } ";
414
					$rrdupdatesh .= "{ ";
415
					$rrdupdatesh .= "if ((\$1 == \"queue\") && ( \$2 ~ /^q/ )) { ";
416
					$rrdupdatesh .= "dsname = dsname \":\" \$2 ; ";
417
					$rrdupdatesh .= "q=1; ";
418
					$rrdupdatesh .= "} ";
419
					$rrdupdatesh .= "else if ((\$4 == \"bytes:\") && ( q == 1 ) ) { ";
420
					$rrdupdatesh .= "dsdata = dsdata \":\" \$5 ; ";
421
					$rrdupdatesh .= "q=0; ";
422
					$rrdupdatesh .= "} ";
423
					$rrdupdatesh .= "} END { ";
424
					$rrdupdatesh .= "dsname = substr(dsname,2); ";
425
					$rrdupdatesh .= "dsdata = substr(dsdata,2); ";
426
					$rrdupdatesh .= "printf \"-t \" dsname \" N:\" dsdata }' ";
427
					$rrdupdatesh .= "dsname=\"\" dsdata=\"\"`\n\n";
428
429
					$rrdupdatesh .= "` pfctl -vsq -i {$realif} | awk 'BEGIN {printf \"$rrdtool update $rrddbpath$ifname$queuesdrop \" } ";
430
					$rrdupdatesh .= "{ ";
431
					$rrdupdatesh .= "if ((\$1 == \"queue\") && ( \$2 ~ /^q/ )) { ";
432
					$rrdupdatesh .= "dsname = dsname \":\" \$2 ; ";
433
					$rrdupdatesh .= "q=1; ";
434
					$rrdupdatesh .= "} ";
435
					$rrdupdatesh .= "else if ((\$4 == \"bytes:\") && ( q == 1 ) ) { ";
436
					$rrdupdatesh .= "dsdata = dsdata \":\" \$8 ; ";
437
					$rrdupdatesh .= "q=0; ";
438
					$rrdupdatesh .= "} ";
439
					$rrdupdatesh .= "} END { ";
440
					$rrdupdatesh .= "dsname = substr(dsname,2); ";
441
					$rrdupdatesh .= "dsdata = substr(dsdata,2); ";
442
					$rrdupdatesh .= "printf \"-t \" dsname \" N:\" dsdata }' ";
443
					$rrdupdatesh .= "dsname=\"\" dsdata=\"\"`\n\n";
444
				}
445
		}
446
		$i++;
447
448
		/* System only statistics */
449
		$ifname = "system";
450
451
			/* STATES, create pf states database */
452
			if(! file_exists("$rrddbpath$ifname$states")) {
453
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$states --step $rrdstatesinterval ";
454
				$rrdcreate .= "DS:pfrate:GAUGE:$statesvalid:0:10000000 ";
455
				$rrdcreate .= "DS:pfstates:GAUGE:$statesvalid:0:10000000 ";
456
				$rrdcreate .= "DS:pfnat:GAUGE:$statesvalid:0:10000000 ";
457
				$rrdcreate .= "DS:srcip:GAUGE:$statesvalid:0:10000000 ";
458
				$rrdcreate .= "DS:dstip:GAUGE:$statesvalid:0:10000000 ";
459
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
460
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
461
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
462 e8021eea Seth Mos
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
463 ea4bc46f Seth Mos
464
				create_new_rrd($rrdcreate);
465
			}
466
467
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
468
			if($g['booting']) {
469 e256e9d4 smos
				mwexec("$rrdtool update $rrddbpath$ifname$states N:U:U:U:U:U");
470 ea4bc46f Seth Mos
			}
471
472
 			/* the pf states gathering function. */
473
 			$rrdupdatesh .= "\n";
474
			$rrdupdatesh .= "pfctl_si_out=\"` $pfctl -si > /tmp/pfctl_si_out `\"\n";
475
			$rrdupdatesh .= "pfctl_ss_out=\"` $pfctl -ss > /tmp/pfctl_ss_out`\"\n";
476
			$rrdupdatesh .= "pfrate=\"` cat /tmp/pfctl_si_out | egrep \"inserts|removals\" | awk '{ pfrate = \$3 + pfrate } {print pfrate}'|tail -1 `\"\n";
477
 			$rrdupdatesh .= "pfstates=\"` cat /tmp/pfctl_ss_out | egrep -v \"<\\-.*?<\\-|\\->.*?\\->\" | wc -l|sed 's/ //g'`\"\n";
478
			$rrdupdatesh .= "pfnat=\"` cat /tmp/pfctl_ss_out | egrep '<\\-.*?<\\-|\\->.*?\\->' | wc -l|sed 's/ //g' `\"\n";
479
 			$rrdupdatesh .= "srcip=\"` cat /tmp/pfctl_ss_out | egrep -v '<\\-.*?<\\-|\\->.*?\\->' | grep '\\->' | awk '{print \$3}' | awk -F: '{print \$1}' | sort -u|wc -l|sed 's/ //g' `\"\n";
480
 			$rrdupdatesh .= "dstip=\"` cat /tmp/pfctl_ss_out | egrep -v '<\\-.*?<\\-|\\->.*?\\->' | grep '<\\-' | awk '{print \$3}' | awk -F: '{print \$1}' | sort -u|wc -l|sed 's/ //g' `\"\n";
481
			$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$states N:\$pfrate:\$pfstates:\$pfnat:\$srcip:\$dstip\n\n";
482
483
			/* End pf states statistics */
484
485
			/* CPU, create CPU statistics database */
486
			if(! file_exists("$rrddbpath$ifname$proc")) {
487
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$proc --step $rrdprocinterval ";
488
				$rrdcreate .= "DS:user:GAUGE:$procvalid:0:10000000 ";
489
				$rrdcreate .= "DS:nice:GAUGE:$procvalid:0:10000000 ";
490
				$rrdcreate .= "DS:system:GAUGE:$procvalid:0:10000000 ";
491
				$rrdcreate .= "DS:interrupt:GAUGE:$procvalid:0:10000000 ";
492
				$rrdcreate .= "DS:processes:GAUGE:$procvalid:0:10000000 ";
493
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
494
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
495
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
496 e8021eea Seth Mos
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
497 ea4bc46f Seth Mos
498
				create_new_rrd($rrdcreate);
499
			}
500
501
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
502
			if($g['booting']) {
503 e256e9d4 smos
				mwexec("$rrdtool update $rrddbpath$ifname$proc N:U:U:U:U:U");
504 ea4bc46f Seth Mos
			}
505
506
 			/* the CPU stats gathering function. */
507
 			$rrdupdatesh .= "`$top -d 2 -s 1 0 | $awk '{gsub(/%/, \"\")} BEGIN { \\\n";
508
			$rrdupdatesh .= "printf \"$rrdtool update $rrddbpath$ifname$proc \" } \\\n";
509
			$rrdupdatesh .= "{ if ( \$2 == \"processes:\" ) { processes = \$1; } \\\n";
510
			$rrdupdatesh .= "else if ( \$1 == \"CPU:\" ) { user = \$2; nice = \$4; sys = \$6; interrupt = \$8; } \\\n";
511
			$rrdupdatesh .= "} END { printf \"N:\"user\":\"nice\":\"sys\":\"interrupt\":\"processes }'`\n\n";
512
513
			/* End CPU statistics */
514
515
			/* Memory, create Memory statistics database */
516
			if(! file_exists("$rrddbpath$ifname$mem")) {
517
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$mem --step $rrdmeminterval ";
518
				$rrdcreate .= "DS:active:GAUGE:$memvalid:0:10000000 ";
519
				$rrdcreate .= "DS:inactive:GAUGE:$memvalid:0:10000000 ";
520
				$rrdcreate .= "DS:free:GAUGE:$memvalid:0:10000000 ";
521
				$rrdcreate .= "DS:cache:GAUGE:$memvalid:0:10000000 ";
522
				$rrdcreate .= "DS:wire:GAUGE:$memvalid:0:10000000 ";
523
				$rrdcreate .= "RRA:MIN:0.5:1:1000 ";
524
				$rrdcreate .= "RRA:MIN:0.5:5:1000 ";
525
				$rrdcreate .= "RRA:MIN:0.5:60:1000 ";
526 e8021eea Seth Mos
				$rrdcreate .= "RRA:MIN:0.5:720:3000 ";
527 ea4bc46f Seth Mos
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
528
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
529
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
530 e8021eea Seth Mos
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
531 ea4bc46f Seth Mos
				$rrdcreate .= "RRA:MAX:0.5:1:1000 ";
532
				$rrdcreate .= "RRA:MAX:0.5:5:1000 ";
533
				$rrdcreate .= "RRA:MAX:0.5:60:1000 ";
534 e8021eea Seth Mos
				$rrdcreate .= "RRA:MAX:0.5:720:3000";
535 ea4bc46f Seth Mos
536
				create_new_rrd($rrdcreate);
537
			}
538
539
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
540
			if($g['booting']) {
541 e256e9d4 smos
				mwexec("$rrdtool update $rrddbpath$ifname$mem N:U:U:U:U:U");
542 ea4bc46f Seth Mos
			}
543
544
 			/* the Memory stats gathering function. */
545
 			$rrdupdatesh .= "`$sysctl -n vm.stats.vm.v_page_count vm.stats.vm.v_active_count vm.stats.vm.v_inactive_count vm.stats.vm.v_free_count vm.stats.vm.v_cache_count vm.stats.vm.v_wire_count | ";
546
			$rrdupdatesh .= " $awk '{getline active;getline inactive;getline free;getline cache;getline wire;printf \"$rrdtool update $rrddbpath$ifname$mem N:\"";
547
			$rrdupdatesh .= "((active/$0) * 100)\":\"((inactive/$0) * 100)\":\"((free/$0) * 100)\":\"((cache/$0) * 100)\":\"(wire/$0 * 100)}'`\n\n";
548
			
549
			/* End Memory statistics */
550
551
			/* SPAMD, set up the spamd rrd file */
552
			if (isset($config['installedpackages']['spamdsettings']) &&
553
				 isset ($config['installedpackages']['spamdsettings']['config'][0]['enablerrd'])) {
554
				/* set up the spamd rrd file */
555
				if (!file_exists("$rrddbpath$ifname$spamd")) {
556
					$rrdcreate = "$rrdtool create $rrddbpath$ifname$spamd --step $rrdspamdinterval ";
557
					$rrdcreate .= "DS:conn:GAUGE:$spamdvalid:0:10000 ";
558
					$rrdcreate .= "DS:time:GAUGE:$spamdvalid:0:86400 ";
559
					$rrdcreate .= "RRA:MIN:0.5:1:1000 ";
560
					$rrdcreate .= "RRA:MIN:0.5:5:1000 ";
561
					$rrdcreate .= "RRA:MIN:0.5:60:1000 ";
562 e8021eea Seth Mos
					$rrdcreate .= "RRA:MIN:0.5:720:3000 ";
563 ea4bc46f Seth Mos
					$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
564
					$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
565
					$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
566 e8021eea Seth Mos
					$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
567 ea4bc46f Seth Mos
					$rrdcreate .= "RRA:MAX:0.5:1:1000 ";
568
					$rrdcreate .= "RRA:MAX:0.5:5:1000 ";
569
					$rrdcreate .= "RRA:MAX:0.5:60:1000 ";
570 e8021eea Seth Mos
					$rrdcreate .= "RRA:MAX:0.5:720:3000 ";
571 ea4bc46f Seth Mos
572
					create_new_rrd($rrdcreate);
573
				}
574
575
				$rrdupdatesh .= "\n";
576
				$rrdupdatesh .= "# polling spamd for connections and tarpitness \n";
577
				$rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$spamd \\\n";
578
				$rrdupdatesh .= "`$php -q $spamd_gather`\n";
579
580
			}
581
		/* End System statistics */
582
583 ec51a222 thompsa
		/* 3G WIRELESS, set up the rrd file */
584
		if(isset($config['ppps']['ppp'])) {
585
			$ifname = "ppp";
586
			if (!file_exists("$rrddbpath$ifname$cellular")) {
587
				$rrdcreate = "$rrdtool create $rrddbpath$ifname$cellular --step $rrdcellularinterval ";
588
				$rrdcreate .= "DS:signal1:GAUGE:$cellularvalid:-200:200 ";
589
				$rrdcreate .= "DS:signal2:GAUGE:$cellularvalid:-200:200 ";
590
				$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
591
				$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
592
				$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
593
				$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
594
595
				create_new_rrd($rrdcreate);
596
			}
597
598
			/* enter UNKNOWN values in the RRD so it knows we rebooted. */
599
			if($g['booting']) {
600 e256e9d4 smos
				mwexec("$rrdtool update $rrddbpath$ifname$cellular N:U:U");
601 ec51a222 thompsa
			}
602
603
			$rrdupdatesh .= "\n";
604
			$rrdupdatesh .= "# polling 3G\n";
605 a0bb5a4d thompsa
			$rrdupdatesh .= "dev=`usbconfig show_ifdrv | awk -F. '/ u3g|umodem/ {print \"/dev/\" $1 \".\" $2}'`\n";
606 ec51a222 thompsa
			$rrdupdatesh .= "if [ -n \"\$dev\" ]; then $rrdtool update $rrddbpath$ifname$cellular N:`3gstat -s -d \$dev`\n";
607
			$rrdupdatesh .= "else $rrdtool update $rrddbpath$ifname$cellular N:U:U; fi\n";
608
		}
609
610
611 ea4bc46f Seth Mos
		$rrdupdatesh .= "sleep 60\n";
612
		$rrdupdatesh .= "done\n";
613
		log_error("Creating rrd update script");
614
		/* write the rrd update script */
615
		$updaterrdscript = "{$g['vardb_path']}/rrd/updaterrd.sh";
616
		$fd = fopen("$updaterrdscript", "w");
617
		fwrite($fd, "$rrdupdatesh");
618
		fclose($fd);
619
620
		/* kill off traffic collectors */
621
		kill_traffic_collector();
622
623
		/* start traffic collector */
624
		mwexec_bg("/usr/bin/nice -n20 /bin/sh $updaterrdscript");
625
626
	} else {
627
		/* kill off traffic collectors */
628
		kill_traffic_collector();
629
	}
630
631
	if($g['booting']) 
632
		echo "done.\n";
633
		
634
}
635
636 ab7658da Seth Mos
function kill_traffic_collector() {
637 12980094 Chris Buechler
	mwexec("/bin/pkill -f updaterrd.sh");
638 ab7658da Seth Mos
}
639
640 957d8f75 Seth Mos
/* This xml 2 array function is courtesy of the php.net comment section on xml_parse.
641
 * it is roughly 4 times faster then our existing pfSense parser but due to the large
642
 * size of the RRD xml dumps this is required.
643
 * The reason we do not use it for pfSense is that it does not know about array fields
644
 * which causes it to fail on array fields with single items. Possible Todo?
645
 */
646
function xml2array($contents, $get_attributes = 1, $priority = 'tag')
647
{
648
    if (!function_exists('xml_parser_create'))
649
    {
650
        return array ();
651
    }
652
    $parser = xml_parser_create('');
653
    xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
654
    xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
655
    xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
656
    xml_parse_into_struct($parser, trim($contents), $xml_values);
657
    xml_parser_free($parser);
658
    if (!$xml_values)
659
        return; //Hmm...
660
    $xml_array = array ();
661
    $parents = array ();
662
    $opened_tags = array ();
663
    $arr = array ();
664
    $current = & $xml_array;
665
    $repeated_tag_index = array ();
666
    foreach ($xml_values as $data)
667
    {
668
        unset ($attributes, $value);
669
        extract($data);
670
        $result = array ();
671
        $attributes_data = array ();
672
        if (isset ($value))
673
        {
674
            if ($priority == 'tag')
675
                $result = $value;
676
            else
677
                $result['value'] = $value;
678
        }
679
        if (isset ($attributes) and $get_attributes)
680
        {
681
            foreach ($attributes as $attr => $val)
682
            {
683
                if ($priority == 'tag')
684
                    $attributes_data[$attr] = $val;
685
                else
686
                    $result['attr'][$attr] = $val; //Set all the attributes in a array called 'attr'
687
            }
688
        }
689
        if ($type == "open")
690
        {
691
            $parent[$level -1] = & $current;
692
            if (!is_array($current) or (!in_array($tag, array_keys($current))))
693
            {
694
                $current[$tag] = $result;
695
                if ($attributes_data)
696
                    $current[$tag . '_attr'] = $attributes_data;
697
                $repeated_tag_index[$tag . '_' . $level] = 1;
698
                $current = & $current[$tag];
699
            }
700
            else
701
            {
702
                if (isset ($current[$tag][0]))
703
                {
704
                    $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
705
                    $repeated_tag_index[$tag . '_' . $level]++;
706
                }
707
                else
708
                {
709
                    $current[$tag] = array (
710
                        $current[$tag],
711
                        $result
712
                    );
713
                    $repeated_tag_index[$tag . '_' . $level] = 2;
714
                    if (isset ($current[$tag . '_attr']))
715
                    {
716
                        $current[$tag]['0_attr'] = $current[$tag . '_attr'];
717
                        unset ($current[$tag . '_attr']);
718
                    }
719
                }
720
                $last_item_index = $repeated_tag_index[$tag . '_' . $level] - 1;
721
                $current = & $current[$tag][$last_item_index];
722
            }
723
        }
724
        elseif ($type == "complete")
725
        {
726
            if (!isset ($current[$tag]))
727
            {
728
                $current[$tag] = $result;
729
                $repeated_tag_index[$tag . '_' . $level] = 1;
730
                if ($priority == 'tag' and $attributes_data)
731
                    $current[$tag . '_attr'] = $attributes_data;
732
            }
733
            else
734
            {
735
                if (isset ($current[$tag][0]) and is_array($current[$tag]))
736
                {
737
                    $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
738
                    if ($priority == 'tag' and $get_attributes and $attributes_data)
739
                    {
740
                        $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
741
                    }
742
                    $repeated_tag_index[$tag . '_' . $level]++;
743
                }
744
                else
745
                {
746
                    $current[$tag] = array (
747
                        $current[$tag],
748
                        $result
749
                    );
750
                    $repeated_tag_index[$tag . '_' . $level] = 1;
751
                    if ($priority == 'tag' and $get_attributes)
752
                    {
753
                        if (isset ($current[$tag . '_attr']))
754
                        {
755
                            $current[$tag]['0_attr'] = $current[$tag . '_attr'];
756
                            unset ($current[$tag . '_attr']);
757
                        }
758
                        if ($attributes_data)
759
                        {
760
                            $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
761
                        }
762
                    }
763
                    $repeated_tag_index[$tag . '_' . $level]++; //0 and 1 index is already taken
764
                }
765
            }
766
        }
767
        elseif ($type == 'close')
768
        {
769
            $current = & $parent[$level -1];
770
        }
771
    }
772
    return ($xml_array);
773
}
774
775
?>