Subversion Repositories qbpwcf-lib(archive)

Rev

Rev 906 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 liveuser 1
#!/bin/php
2
<?php
3
 
119 liveuser 4
/*
464 liveuser 5
	QBPWCF, Quick Build PHP website Component base on Fedora Linux.
619 liveuser 6
    Copyright (C) 2015~2024 Min-Jhin,Chen
119 liveuser 7
 
464 liveuser 8
    This file is part of QBPWCF.
9
 
10
    QBPWCF is free software: you can redistribute it and/or modify
11
    it under the terms of the GNU General Public License as published by
12
    the Free Software Foundation, either version 3 of the License, or
13
    (at your option) any later version.
14
 
15
    QBPWCF is distributed in the hope that it will be useful,
16
    but WITHOUT ANY WARRANTY; without even the implied warranty of
17
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
    GNU General Public License for more details.
19
 
20
    You should have received a copy of the GNU General Public License
21
    along with QBPWCF.  If not, see <http://www.gnu.org/licenses/>.
22
 
23
*/
24
 
25
/*
26
 
119 liveuser 27
說明:
28
監控系統若負載超過總執行序就警報
29
 
30
參考資料:
31
https://www.php.net/manual/en/function.htmlentities.php
32
 
33
*/
34
 
1 liveuser 35
#使用命名空間qbpwcf
36
namespace qbpwcf;
37
 
466 liveuser 38
#以該檔案的實際位置的 lib path 為 include path 首位
922 liveuser 39
exec("cd ".pathinfo(__FILE__)["dirname"]."/../lib/qbpwcf;pwd;",$output,$status);
466 liveuser 40
set_include_path($output[0].PATH_SEPARATOR.get_include_path());
41
 
464 liveuser 42
#匯入外部套件
466 liveuser 43
include("allInOne.php");
1 liveuser 44
 
70 liveuser 45
#上一封信件寄送的分鐘
46
$lastEmailMinute=gmdate("i");
47
 
1 liveuser 48
#預設執行間隔為1秒鐘
49
$interval=1;
50
 
70 liveuser 51
#預設不開啟所有訊息
52
$verbose=false;
53
 
1 liveuser 54
#預設每天執行的時間範圍為0跟23,亦即每個小時都執行
55
$s=0;
56
$e=23;
57
 
58
#函式說明:
59
#抓取命令列的參數.
60
#回傳結果:
61
#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
62
#$reuslt["error"],執行不正常結束的錯訊息陣列.
63
#$result["function"],當前執行的函式名稱.
64
#$result["argu"],使用的參數陣列.
65
#$result["content"],要回傳的參數陣列.
66
#$result["count"],參數的數量.
67
#必填參數:
68
#無
69
#可省略參數:
70
#$conf["echo"],"true"代表要將抓到的參數一個個印出來,"false"代表用回傳的方式,預設為"false".
71
$conf["echo"]="false";
72
$getArgu=cmd::getArgu($conf);
73
unset($conf);
74
 
75
#如果執行失敗
76
if($getArgu["status"]==="false"){
77
 
78
	#結束執行
79
	return false;
80
 
81
	}#if end
82
 
83
#如果存在一個參數
84
if(isset($getArgu["content"][1])){
85
 
86
	#如果有參數 -h 或 --help 存在
87
	if( $getArgu["content"][1]==="-h" || $getArgu["content"][1]==="--help" ){
88
 
89
		#印出指令說明
70 liveuser 90
		echo "Usage ".basename(__FILE__).":".PHP_EOL; 
91
		echo "\t-i 秒數間隔 -s 開始小時 -e 結束小時".PHP_EOL;
118 liveuser 92
		echo "\t--verbose on 代表提示所有訊息".PHP_EOL;
70 liveuser 93
		echo "\t--eacct 用於寄信的gmail賬戶".PHP_EOL;
94
		echo "\t--epass 用於寄信的gmail密碼".PHP_EOL;
95
		echo "\t--receiver 收件人,一次指定一個收件人".PHP_EOL;
96
		echo "\t--target 監控的主機名稱".PHP_EOL;
1 liveuser 97
 
98
		#結束執行
99
		exit;
100
 
101
		}#if end
102
 
103
	}#if end
104
 
105
#函式說明:
106
#解析參數.
107
#回傳結果:
108
#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
109
#$reuslt["error"],執行不正常結束的錯訊息陣列.
110
#$result["function"],當前執行的函式名稱.
111
#$result["content"],解析好的參數陣列.
112
#$result["content"][$key][$i],參數 $key 的 $i+1 個參數數值內容.
113
#$result["program"],字串,執行的程式名稱.
114
#必填參數:
115
#無
116
#可省略參數:
117
#無
118
#備註:
119
#僅能在命令列底下執行.
120
#建議:
121
#以後可將參數 --a--b 的名稱與後面的數值 $value 存成 $result["a"]["b"][$i]=$value .
104 liveuser 122
$conf=array();
123
$parseArgu=cmd::parseArgu($conf);
124
unset($conf);
1 liveuser 125
 
126
#如果執行失敗
127
if($parseArgu["status"]==="false"){
128
 
129
	#結束執行
130
	return false;
131
 
132
	}#if end
133
 
134
#如果有參數
135
if(isset($parseArgu["content"])){
136
 
137
	#如果有參數 i
138
	if(isset($parseArgu["content"]["i"])){
139
 
140
		#如果有一個參數 i
141
		if(isset($parseArgu["content"]["i"][0])){
142
 
143
			#如果是正常的數值
144
			if((int)$parseArgu["content"]["i"][0]>0){
145
 
146
				#設置新的 interval
147
				$interval=(int)$parseArgu["content"]["i"][0];
148
 
149
				}#if end
150
 
151
			}#if end
152
 
153
		}#if end
154
 
155
	#如果有參數 s
156
	if(isset($parseArgu["content"]["s"])){
157
 
158
		#如果有一個參數 s
159
		if(isset($parseArgu["content"]["s"][0])){
160
 
161
			#如果是正常的數值
162
			if( (int)$parseArgu["content"]["s"][0]>0 && (int)$parseArgu["content"]["s"][0]<23 ){
163
 
164
				#設置新的開始小時
165
				$s=(int)$parseArgu["content"]["s"][0];
166
 
167
				}#if end
168
 
169
			}#if end
170
 
171
		}#if end
172
 
173
	#如果有參數 e
174
	if(isset($parseArgu["content"]["e"])){
175
 
176
		#如果有一個參數 e
177
		if(isset($parseArgu["content"]["e"][0])){
178
 
179
			#如果是正常的數值
180
			if( (int)$parseArgu["content"]["e"][0]>0 && (int)$parseArgu["content"]["e"][0]<23 ){
181
 
182
				#設置新的結束小時
183
				$e=(int)$parseArgu["content"]["e"][0];
184
 
185
				}#if end
186
 
187
			}#if end
188
 
189
		}#if end
190
 
70 liveuser 191
	#如果有參數 verbose
192
	if(isset($parseArgu["content"]["verbose"])){
193
 
194
		#如果有一個參數verbose
195
		if(isset($parseArgu["content"]["verbose"][0])){
196
 
197
			#設置要 verbose
198
			$verbose=true;
199
 
200
			}#if end
201
 
202
		}#if end
203
 
204
	#如果有參數 eacct
205
	if(isset($parseArgu["content"]["eacct"])){
206
 
207
		#如果有一個參數eacct
208
		if(isset($parseArgu["content"]["eacct"][0])){
209
 
210
			#設置eacct
211
			$eacct=$parseArgu["content"]["eacct"][0];
212
 
213
			}#if end
214
 
215
		}#if end
216
 
217
	#如果有參數 epass
218
	if(isset($parseArgu["content"]["epass"])){
219
 
220
		#如果有一個參數epass
221
		if(isset($parseArgu["content"]["epass"][0])){
222
 
223
			#設置epass
224
			$epass=$parseArgu["content"]["epass"][0];
225
 
226
			}#if end
227
 
228
		}#if end
229
 
230
	#如果有參數 receiver
231
	if(isset($parseArgu["content"]["receiver"])){
232
 
233
		#設置receiver
234
		$receiver=$parseArgu["content"]["receiver"];
235
 
236
		}#if end
237
 
238
	#如果有參數 target
239
	if(isset($parseArgu["content"]["target"])){
240
 
241
		#如果有一個參數target
242
		if(isset($parseArgu["content"]["target"][0])){
243
 
244
			#設置target
245
			$target=$parseArgu["content"]["target"][0];
246
 
247
			}#if end
248
 
249
		}#if end
250
 
1 liveuser 251
	}#if end	
252
 
70 liveuser 253
#如果參數有缺
254
if( !isset($eacct) || !isset($epass) || !isset($receiver) || !isset($target) )
255
{
256
	echo "參數 --eacct 跟 --epass 跟 --receiver 跟 --target 必填".PHP_EOL;
257
	exit;
258
}
259
 
260
#預設上次不需要警示
261
$lastAlert=false;
262
 
263
#預設上次的警示數值為0
264
$lastAlertValue=0;
265
 
1 liveuser 266
#無窮迴圈
267
while(true){
268
 
269
	#取得現在時間
270
	#涵式說明:
271
	#呼叫shell執行系統命令,並取得回傳的內容.
272
	#回傳的結果:
273
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
274
	#$result["error"],錯誤訊息陣列.
275
	#$result["function"],當前執行的函數名稱.
276
	#$result["argu"],使用的參數.
277
	#$result["cmd"],執行的指令內容.
278
	#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
279
	#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
280
	#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
281
	#$result["running"],是否還在執行.
282
	#$result["pid"],pid.
283
	#$result["statusCode"],執行結束後的代碼.
284
	#必填的參數
285
	#$conf["command"],字串,要執行的指令與.
286
	$conf["command"]="date";
287
	#$conf["fileArgu"],字串,變數__FILE__的內容.
288
	$conf["fileArgu"]=__FILE__;		
289
	#可省略參數:
290
	#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
291
	$conf["argu"]=array("-d","now","+%H");
292
	#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
293
	#$conf["arguIsAddr"]=array();	
294
	#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
295
	#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
296
	#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
297
	#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
298
	#$conf["enablePrintDescription"]="true";
299
	#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
300
	#$conf["printDescription"]="";
301
	#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
453 liveuser 302
	$conf["escapeshellarg"]="true";
1 liveuser 303
	#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
304
	#$conf["username"]="";
305
	#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
306
	#$conf["password"]="";
307
	#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
308
	#$conf["useScript"]="";
309
	#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
310
	#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
311
	#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
312
	#$conf["inBackGround"]="";
313
	#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
314
	#$conf["getErr"]="false";
315
	#備註:
316
	#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
317
	#參考資料:
318
	#exec=>http://php.net/manual/en/function.exec.php
319
	#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
320
	#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
321
	$callShell=external::callShell($conf);
322
	unset($conf);
323
 
324
	#如果執行出錯
325
	if($callShell["status"]===false){
326
 
327
		#結束執行
328
		return false;
329
 
330
		}#if end
331
 
332
	#如果沒有回小時
333
	if(!isset($callShell["output"][0])){
334
 
335
		#結束執行
336
		return false;
337
 
338
		}#if end
339
 
340
	#取得輸出
341
	$hour=$callShell["output"][0];
342
 
343
	#如果小於開始小時
344
	if($hour<(int)$s){
345
 
346
		#休息一小時
347
		sleep(3600);
348
 
349
		#再跑一次
350
		continue;
351
 
352
		}#if end
353
 
354
	#如果大於結束小時
355
	if($hour>(int)$e){
356
 
357
		#休息一小時
358
		sleep(3600);
359
 
360
		#再跑一次
361
		continue;
362
 
363
		}#if end
364
 
365
	#取得現在時間
366
	#涵式說明:
367
	#呼叫shell執行系統命令,並取得回傳的內容.
368
	#回傳的結果:
369
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
370
	#$result["error"],錯誤訊息陣列.
371
	#$result["function"],當前執行的函數名稱.
372
	#$result["argu"],使用的參數.
373
	#$result["cmd"],執行的指令內容.
374
	#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
375
	#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
376
	#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
377
	#$result["running"],是否還在執行.
378
	#$result["pid"],pid.
379
	#$result["statusCode"],執行結束後的代碼.
380
	#必填的參數
381
	#$conf["command"],字串,要執行的指令與.
382
	$conf["command"]="date";
383
	#$conf["fileArgu"],字串,變數__FILE__的內容.
384
	$conf["fileArgu"]=__FILE__;		
385
	#可省略參數:
386
	#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
387
	#$conf["argu"]=array("");
388
	#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
389
	#$conf["arguIsAddr"]=array();	
390
	#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
391
	#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
392
	#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
393
	#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
394
	#$conf["enablePrintDescription"]="true";
395
	#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
396
	#$conf["printDescription"]="";
397
	#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
453 liveuser 398
	$conf["escapeshellarg"]="true";
1 liveuser 399
	#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
400
	#$conf["username"]="";
401
	#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
402
	#$conf["password"]="";
403
	#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
404
	#$conf["useScript"]="";
405
	#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
406
	#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
407
	#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
408
	#$conf["inBackGround"]="";
409
	#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
410
	#$conf["getErr"]="false";
411
	#備註:
412
	#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
413
	#參考資料:
414
	#exec=>http://php.net/manual/en/function.exec.php
415
	#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
416
	#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
417
	$callShell=external::callShell($conf);
418
	unset($conf);
419
 
420
	#如果執行出錯
70 liveuser 421
	if($callShell["status"]==="false"){
1 liveuser 422
 
423
		#結束執行
424
		return false;
425
 
426
		}#if end
427
 
428
	#取得輸出
429
	$time=$callShell["output"];
430
 
431
	#涵式說明:
432
	#呼叫shell執行系統命令,並取得回傳的內容.
433
	#回傳的結果:
434
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
435
	#$result["error"],錯誤訊息陣列.
436
	#$result["function"],當前執行的函數名稱.
437
	#$result["argu"],使用的參數.
438
	#$result["cmd"],執行的指令內容.
439
	#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
440
	#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
441
	#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
442
	#$result["running"],是否還在執行.
443
	#$result["pid"],pid.
444
	#$result["statusCode"],執行結束後的代碼.
445
	#必填的參數
446
	#$conf["command"],字串,要執行的指令與.
447
	$conf["command"]="uptime";
448
	#$conf["fileArgu"],字串,變數__FILE__的內容.
449
	$conf["fileArgu"]=__FILE__;		
450
	#可省略參數:
451
	#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
452
	#$conf["argu"]=array("");
453
	#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
454
	#$conf["arguIsAddr"]=array();	
455
	#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
456
	#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
457
	#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
458
	#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
459
	#$conf["enablePrintDescription"]="true";
460
	#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
461
	#$conf["printDescription"]="";
462
	#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
453 liveuser 463
	$conf["escapeshellarg"]="true";
1 liveuser 464
	#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
465
	#$conf["username"]="";
466
	#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
467
	#$conf["password"]="";
468
	#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
469
	#$conf["useScript"]="";
470
	#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
471
	#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
472
	#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
473
	#$conf["inBackGround"]="";
474
	#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
475
	#$conf["getErr"]="false";
476
	#備註:
477
	#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
478
	#參考資料:
479
	#exec=>http://php.net/manual/en/function.exec.php
480
	#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
481
	#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
482
	$callShell=external::callShell($conf);
483
	unset($conf);
484
 
485
	#如果執行出錯
486
	if($callShell["status"]===false){
487
 
488
		#結束執行
489
		return false;
490
 
491
		}#if end
492
 
493
	#取得輸出
494
	$uptime=$callShell["output"];
495
 
70 liveuser 496
	#用來分割的關鍵字
497
	$splitWord="load average: ";
498
 
499
	#函式說明:
500
	#將固定格式的字串分開,並回傳分開的結果。
501
	#回傳結果:
502
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
503
	#$result["error"],錯誤訊息陣列
504
	#$result["function"],當前執行的函數名稱.
505
	#$result["argu"],使用的參數.
506
	#$result["oriStr"],要分割的原始字串內容
507
	#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
508
	#$result["dataCounts"],爲總共分成幾段
509
	#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
510
	#必填參數:
511
	#$conf["stringIn"],字串,要處理的字串.
512
	$conf["stringIn"]=$uptime[0];
513
	#$conf["spiltSymbol"],字串,爲以哪個符號作爲分割.
514
	$conf["spiltSymbol"]=$splitWord;
515
	#可省略參數:
516
	#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
517
	$conf["allowEmptyStr"]="false";
518
	#備註:
519
	#無.
520
	$spiltString=stringProcess::spiltString($conf);
521
	unset($conf);
522
 
523
	#如果執行失敗
524
	if($spiltString["status"]==="false")
525
	{
526
		#結束執行
527
		return false;
528
	}
529
 
530
	#如果沒有指令的關鍵字存在
531
	if($spiltString["found"]==="false")
532
	{
533
		#結束執行
534
		return false;
535
	}
536
 
537
	#用來分割的關鍵字
538
	$splitWord=", ";
539
 
540
	#函式說明:
541
	#將固定格式的字串分開,並回傳分開的結果。
542
	#回傳結果:
543
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
544
	#$result["error"],錯誤訊息陣列
545
	#$result["function"],當前執行的函數名稱.
546
	#$result["argu"],使用的參數.
547
	#$result["oriStr"],要分割的原始字串內容
548
	#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
549
	#$result["dataCounts"],爲總共分成幾段
550
	#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
551
	#必填參數:
552
	#$conf["stringIn"],字串,要處理的字串.
553
	$conf["stringIn"]=$spiltString["dataArray"][1];
554
	#$conf["spiltSymbol"],字串,爲以哪個符號作爲分割.
555
	$conf["spiltSymbol"]=$splitWord;
556
	#可省略參數:
557
	#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
558
	$conf["allowEmptyStr"]="false";
559
	#備註:
560
	#無.
561
	$spiltString=stringProcess::spiltString($conf);
562
	unset($conf);
563
 
564
	#如果執行失敗
565
	if($spiltString["status"]==="false")
566
	{
567
		#結束執行
568
		return false;
569
	}
570
 
571
	#如果沒有指令的關鍵字存在
572
	if($spiltString["found"]==="false")
573
	{
574
		#結束執行
575
		return false;
576
	}
577
 
578
	#取得uptime的當下數值
579
	$uptimeVal=$spiltString["dataArray"][0];
580
 
581
	#取得CPU有多少執行序
1 liveuser 582
	#涵式說明:
583
	#呼叫shell執行系統命令,並取得回傳的內容.
584
	#回傳的結果:
585
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
586
	#$result["error"],錯誤訊息陣列.
587
	#$result["function"],當前執行的函數名稱.
588
	#$result["argu"],使用的參數.
589
	#$result["cmd"],執行的指令內容.
590
	#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
591
	#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
592
	#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
593
	#$result["running"],是否還在執行.
594
	#$result["pid"],pid.
595
	#$result["statusCode"],執行結束後的代碼.
596
	#必填的參數
597
	#$conf["command"],字串,要執行的指令與.
453 liveuser 598
	$conf["command"]="lscpu";
70 liveuser 599
	#$conf["fileArgu"],字串,變數__FILE__的內容.
600
	$conf["fileArgu"]=__FILE__;		
601
	#可省略參數:
602
	#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
453 liveuser 603
	$conf["argu"]=array("|","grep","CPU(s)","|","grep","-v","NUMA");
70 liveuser 604
	#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
605
	#$conf["arguIsAddr"]=array();	
606
	#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
607
	#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
608
	#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
609
	#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
610
	#$conf["enablePrintDescription"]="true";
611
	#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
612
	#$conf["printDescription"]="";
613
	#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
453 liveuser 614
	$conf["escapeshellarg"]="true";
70 liveuser 615
	#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
616
	#$conf["username"]="";
617
	#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
618
	#$conf["password"]="";
619
	#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
620
	#$conf["useScript"]="";
621
	#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
622
	#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
623
	#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
624
	#$conf["inBackGround"]="";
625
	#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
626
	#$conf["getErr"]="false";
627
	#備註:
628
	#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
629
	#參考資料:
630
	#exec=>http://php.net/manual/en/function.exec.php
631
	#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
632
	#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
633
	$callShell=external::callShell($conf);
634
	unset($conf);
635
 
636
	#如果執行出錯
637
	if($callShell["status"]==="false"){
638
 
639
		#結束執行
640
		return false;
641
 
642
		}#if end
643
 
644
	#取得輸出
645
	$lscpu=$callShell["output"];
646
 
647
	#用來分割的關鍵字
648
	$splitWord="CPU(s): ";
649
 
650
	#函式說明:
651
	#將固定格式的字串分開,並回傳分開的結果。
652
	#回傳結果:
653
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
654
	#$result["error"],錯誤訊息陣列
655
	#$result["function"],當前執行的函數名稱.
656
	#$result["argu"],使用的參數.
657
	#$result["oriStr"],要分割的原始字串內容
658
	#$result["dataArray"],爲分割好字串的陣列內容,$result["dataArray"][$i]爲第($i+1)段的內容。
659
	#$result["dataCounts"],爲總共分成幾段
660
	#$result["found"],是否有在$conf["stringIn"]找到$conf["spiltSymbol"],"true"代表有找到,"false"代表沒有找到.
661
	#必填參數:
662
	#$conf["stringIn"],字串,要處理的字串.
663
	$conf["stringIn"]=$lscpu[0];
664
	#$conf["spiltSymbol"],字串,爲以哪個符號作爲分割.
665
	$conf["spiltSymbol"]=$splitWord;
666
	#可省略參數:
667
	#$conf["allowEmptyStr"],是否允許分割出來空字串,預設為"false"不允許;"true"代表允許.
668
	$conf["allowEmptyStr"]="false";
669
	#備註:
670
	#無.
671
	$spiltString=stringProcess::spiltString($conf);
672
	unset($conf);
673
 
674
	#如果執行失敗
675
	if($spiltString["status"]==="false")
676
	{
677
		#結束執行
678
		return false;
679
	}
680
 
681
	#如果沒有指令的關鍵字存在
682
	if($spiltString["found"]==="false")
683
	{
684
		#結束執行
685
		return false;
686
	}
687
 
688
	#取得uptime的當下數值
689
	$lscpuVal=(int)$spiltString["dataArray"][0];
690
 
691
	#如果有程序必須等待cpu給予資源
692
	if($uptimeVal>=$lscpuVal)
693
	{
694
		#設置需要警示
695
		$alert=true;
696
	}
697
	#反之解除
698
	else
699
	{
700
		#設置需要警示
701
		$alert=false;
702
	}
703
 
704
	#設置警示數值
705
	$alertValue=$uptimeVal;
706
 
98 liveuser 707
	#取得當前程序樹
70 liveuser 708
	#涵式說明:
709
	#呼叫shell執行系統命令,並取得回傳的內容.
710
	#回傳的結果:
711
	#$result["status"],執行是否正常,"true"代表正常,"false"代表不正常.
712
	#$result["error"],錯誤訊息陣列.
713
	#$result["function"],當前執行的函數名稱.
714
	#$result["argu"],使用的參數.
715
	#$result["cmd"],執行的指令內容.
716
	#$result["fullCmd"],如果參數 $conf["inBackGround"] 為 "true" 則會回傳該值.
717
	#$result["output"],爲執行完二元碼後的輸出陣列,若 $conf["inBackGround"] 為 "true",則為當下的輸出.
718
	#$result["tmpFileOutput"],儲存輸出的暫存檔案名稱,若 $conf["inBackGround"] 為 "true" 則會回傳該值.
719
	#$result["running"],是否還在執行.
720
	#$result["pid"],pid.
721
	#$result["statusCode"],執行結束後的代碼.
722
	#必填的參數
723
	#$conf["command"],字串,要執行的指令與.
453 liveuser 724
	$conf["command"]="ps";
1 liveuser 725
	#$conf["fileArgu"],字串,變數__FILE__的內容.
726
	$conf["fileArgu"]=__FILE__;		
727
	#可省略參數:
728
	#$conf["argu"],陣列字串,指令搭配的參數,預設為空陣列.
453 liveuser 729
	$conf["argu"]=array("axuwf","|","cat");
1 liveuser 730
	#$conf["arguIsAddr"],陣列字串,指令搭配的哪些參數為路徑,為路徑的參數會進行轉換以便符合呼叫當前函數的位置,預設不指定,若有3個參數,其中第3個參數為路徑,則表示為array("false","false","true").
731
	#$conf["arguIsAddr"]=array();	
732
	#$conf["pre"],陣列,要在本指令前執行的每個指令與參數.
733
	#$conf["pre"][$i]["cmd"],字串,要在本指令前執行的第$i+1個指令.
734
	#$conf["pre"][$i]["param"],陣列字串,要在本指令前執行的第$i+1個指令的參數.
735
	#$conf["enablePrintDescription"],字串,是否要印出$conf["printDescription"]的內容,"true"代表要,"false"代表不要,預設為"false".
736
	#$conf["enablePrintDescription"]="true";
737
	#$conf["printDescription"],字串,執行該外部程式前要印出來的的文字,預設為$conf["command"]的內容加上使用的$conf["argu"]參數.
738
	#$conf["printDescription"]="";
739
	#$conf["escapeshellarg"],字串,是否要啟用過濾參數,用了比較安全,但可能會出錯,"true"為啟用,"false"為不啟用,預設為"false".
453 liveuser 740
	$conf["escapeshellarg"]="true";
1 liveuser 741
	#$conf["username"],字串,要用什麼使用者來執行,預設為執行php的使用者,該參數不適用於apache環境.
742
	#$conf["username"]="";
743
	#$conf["password"],字串,root的使用者密碼,預設不使用密碼,該參數不適用於apache環境.
744
	#$conf["password"]="";
745
	#$conf["useScript"],字串,是否要啟用Linux的script指令來記錄輸出,"true"代表要,Fedora的selinux會擋住該操作;"false"代表不要,預設為"false".
746
	#$conf["useScript"]="";
747
	#$conf["logFilePath"],字串,當 $conf["useScript"] 為 "true" 時,輸出的內容要暫存到哪裡,預設為 "/tmp/.qbpwcf_tmp/external/callShell/".
748
	#$conf["logFilePath"]=".qbpwcf_tmp/external/callShell/";
749
	#$conf["inBackGround"],字串,是否要在背景執行,且不會等待程式執行結束再執行下一個指令,"true"代表是,"false"代表不要,預設為"false",如果$conf["command"]有用「;」區隔的多個指令將會出錯.
750
	#$conf["inBackGround"]="";
751
	#$conf["getErr"],字串,"true"代表將錯誤輸出變成標準輸出,反之"false"為不變動.
752
	#$conf["getErr"]="false";
753
	#備註:
754
	#不是所有指令都能用apache的身份執行,目前已知java,javac指令無法執行,使用root身份可能會被selinux阻擋.
755
	#參考資料:
756
	#exec=>http://php.net/manual/en/function.exec.php
757
	#escapeshellcmd=>http://php.net/manual/en/function.escapeshellcmd.php
758
	#escapeshellarg=>http://php.net/manual/en/function.escapeshellarg.php
759
	$callShell=external::callShell($conf);
760
	unset($conf);
761
 
762
	#如果執行出錯
70 liveuser 763
	if($callShell["status"]==="false"){
1 liveuser 764
 
765
		#結束執行
766
		return false;
767
 
768
		}#if end
769
 
770
	#取得輸出
771
	$output=$callShell["output"];
772
 
773
	#$time,現在時間
774
	#$uptime,load average.
775
	#$output,完整工作程序樹
776
 
70 liveuser 777
	#設置郵件參數
778
	$conf["acct"]=$eacct;
779
	$conf["pass"]=$epass;
780
	$conf["receiver"]=$receiver;
1 liveuser 781
 
70 liveuser 782
	#設置時間
783
	$date=date("Y-m-d H:i:s");
1 liveuser 784
 
70 liveuser 785
	#如果從正常狀態進入需要警示的狀態
786
	if($lastAlert===false && $alert===true)
787
	{	
788
		#警示超過負荷
789
		$conf["subject"]=$conf["plainBody"]=$conf["htmlBody"]=$target." 於 ".$date." 超過負荷(".$alertValue.">".$lscpuVal.")了".PHP_EOL;
72 liveuser 790
 
98 liveuser 791
		#串接完整的工作樹
792
		foreach($output as $line)
72 liveuser 793
		{
794
			$conf["plainBody"]=$conf["plainBody"].PHP_EOL.$line;
118 liveuser 795
			$conf["htmlBody"]=$conf["htmlBody"]."<br>".htmlentities($line);
72 liveuser 796
		}
98 liveuser 797
 
70 liveuser 798
		#寄送通知信件
799
		sendMail($conf);			
800
 
801
		#更新寄送的分鐘
802
		$lastEmailMinute=gmdate("i");
803
 
804
	}#if end
805
 
806
	#反之如果負載更嚴重了
807
	else if($lastAlert===true && $alert===true && $alertValue>$lastAlertValue)
808
	{
809
		#警示超過負荷
810
		$conf["subject"]=$conf["plainBody"]=$conf["htmlBody"]=$target." 於 ".$date." 負荷更重了(".$alertValue.">".$lscpuVal.")了".PHP_EOL;
1 liveuser 811
 
98 liveuser 812
		#如果不同分鐘,且超過5分鐘了
813
		if($lastEmailMinute!==gmdate("i") && (gmdate("i")-$lastEmailMinute)>5 )
70 liveuser 814
		{
98 liveuser 815
			#串接完整的工作樹
816
			foreach($output as $line)
72 liveuser 817
			{
818
				$conf["plainBody"]=$conf["plainBody"].PHP_EOL.$line;
118 liveuser 819
				$conf["htmlBody"]=$conf["htmlBody"]."<br>".htmlentities($line);
72 liveuser 820
			}
821
 
822
			#加上pre tag
823
			$conf["htmlBody"]="<pre>".$conf["htmlBody"]."<pre/>";
824
 
70 liveuser 825
			#寄送通知信件
826
			sendMail($conf);
827
 
828
			#更新寄送的分鐘
829
			$lastEmailMinute=gmdate("i");
830
 
1 liveuser 831
		}#if end
832
 
70 liveuser 833
	}#if end
1 liveuser 834
 
70 liveuser 835
	#反之如果可以負荷了
836
	else if($lastAlert===true && $alert===false)
837
	{
838
		#提示恢復正常了
839
		$conf["subject"]=$conf["plainBody"]=$conf["htmlBody"]=$target." 於 ".$date." 恢復正常了".PHP_EOL;
840
 
98 liveuser 841
		#串接完整的工作樹
842
		foreach($output as $line)
72 liveuser 843
		{
844
			$conf["plainBody"]=$conf["plainBody"].PHP_EOL.$line;
118 liveuser 845
			$conf["htmlBody"]=$conf["htmlBody"]."<br>".htmlentities($line);
72 liveuser 846
		}
847
 
848
		#加上pre tag
849
		$conf["htmlBody"]="<pre>".$conf["htmlBody"]."<pre/>";
850
 
70 liveuser 851
		#寄送通知信件
852
		sendMail($conf);
1 liveuser 853
 
70 liveuser 854
	}#if end
1 liveuser 855
 
70 liveuser 856
	#其他不需要警示與提示的狀況,如果有開啟 $verbose
857
	else if($verbose===true)
858
	{
859
		#verbose訊息
860
		$conf["subject"]=$conf["plainBody"]=$conf["htmlBody"]=$target." 於 ".$date." 正常(".$alertValue."<".$lscpuVal.")".PHP_EOL;
861
 
98 liveuser 862
		#如果不同分鐘,且超過5分鐘了
863
		if($lastEmailMinute!==gmdate("i") && (gmdate("i")-$lastEmailMinute)>5 )
70 liveuser 864
		{
98 liveuser 865
			#串接完整的工作樹
866
			foreach($output as $line)
72 liveuser 867
			{
868
				$conf["plainBody"]=$conf["plainBody"].PHP_EOL.$line;
118 liveuser 869
				$conf["htmlBody"]=$conf["htmlBody"]."<br>".htmlentities($line);
72 liveuser 870
			}
871
 
872
			#加上pre tag
873
			$conf["htmlBody"]="<pre>".$conf["htmlBody"]."<pre/>";
874
 
70 liveuser 875
			#寄送通知信件
876
			sendMail($conf);
877
 
878
			#更新寄送的分鐘
879
			$lastEmailMinute=gmdate("i");
880
 
1 liveuser 881
		}#if end
882
 
70 liveuser 883
	}#else end
123 liveuser 884
 
70 liveuser 885
	#移除mail參數
886
	unset($conf);
123 liveuser 887
 
70 liveuser 888
	#更新上次的是否需要警示識別
889
	$lastAlert=$alert;
890
 
891
	#更新上次的警示數值為
892
	$lastAlertValue=$alertValue;
123 liveuser 893
 
1 liveuser 894
	#休息 $interval 秒
895
	sleep($interval);
896
 
897
	}#while end
898
 
70 liveuser 899
#寄送email
900
function sendMail($conf)
901
{
902
	#接收參數
903
	$acct=$conf["acct"];
904
	$pass=$conf["pass"];
905
	$receiver=$conf["receiver"];
906
	$subject=$conf["subject"];
907
	$plainBody=$conf["plainBody"];
908
	$htmlBody=$conf["htmlBody"];
909
	unset($conf);
910
 
911
	#函式說明:
912
	#使用 curl 來透過SMTP伺服器寄信
913
	#回傳結果:
914
	#$result["status"],寄信的情況,若爲"true",則十之八九沒有問題.
915
	#$result["error"],錯誤訊息陣列
916
	#$result["function"],當前執行的函數
917
	#$result["warning"],警示訊息,一些不會導致失敗但不能說是完美的問題.
918
	#$result["cmd"],寄信的指令.
919
	#$result["detailCmd"],較詳細的寄信指令.
920
	#必填參數:
921
	#$conf["username"],字串,用來登入郵件伺服器的帳號
922
	$conf["username"]=$acct;
923
	#$conf["password"],字串,用來登入郵件伺服器的密碼
924
	$conf["password"]=$pass;
925
	#$conf["receiverMail"],陣列,收件人的信箱
926
	$conf["receiverMail"]=$receiver;
927
	#$conf["subject"],字串,郵件的主題
928
	$conf["subject"]=$subject;
929
	#$conf["plainBody"],字串,郵件本文的純文字內容.
930
	$conf["plainBody"]=$plainBody;
931
	#$conf["htmlBody"]="";,字串,郵件本文的html內容,多媒體盡量不要用base64的方式來嵌入,因為大部分的郵件服務(Gmail)都不支援,如果是在單機上的郵件軟體就可能有支援,例如:Evolution.
932
	$conf["htmlBody"]=$htmlBody;
933
	#$conf["fileArgu"],字串,php內建變數「__FILE__」的內容.
934
	$conf["fileArgu"]=__FILE__;
935
	#可省略參數:
936
	#$conf["mailServer"],字串,要使用的SMTP郵件伺服器網址與連接口,預設爲 smtps://smtp.gmail.com:465
937
	#$conf["mailServer"]="";
938
	#$conf["mailerMailDisplay"],字串,要顯示的寄件人信箱,預設爲 $conf["username"]
939
	#$conf["mailerMailDisplay"]="";
940
	#$conf["mailerNameDisplay"],字串,要顯示的寄件人姓名,預設爲 $conf["username"]
941
	#$conf["mailerNameDisplay"]="";
942
	#$conf["receiverMailDisplay"],陣列,要顯示的收件人信箱,預設爲 $conf["receiverMail"] 對應的元素.
943
	#$conf["receiverMailDisplay"]="";#
944
	#$conf["receiverNameDisplay"],陣列,要顯示的收件人姓名,預設爲 $conf["receiverMail"] 對應的元素.
945
	#$conf["receiverNameDisplay"]="";
946
	#$conf["attachment"],陣列,每個要寄送的附件路徑與檔案名稱
947
	#$conf["attachment"]=array();
948
	#$conf["attachmentName"],陣列,每個要寄送的附件顯示名稱,預設為$conf["attachment"]中的實際檔案名稱.
949
	#$conf["attachmentName"]=array();
950
	#$conf["attachmentMimeType"],陣列,每個附件的 mimeType,預設為"application/*".
951
	#$conf["attachmentMimeType"]array();
952
	#範例語句:
953
	#curl --url smtps://smtp.gmail.com:465 -u username@gmail.com:userPassword --mail-from username@gmail.com --mail-rcpt receiver@mail.com --upload-file mail.txt -v
954
	#範例信件內容:
955
	#From: "userName" <username@gmail.com>
956
	#To: "receiverName" <userPassword@yahoo.com.tw>
957
	#Subject: This is a test
958
	#本文~
959
	#參考資料來源:
960
	#用curl來寄信=>http://stackoverflow.com/questions/14722556/using-curl-to-send-email
961
	#降低安全性標準讓curl可以使用=>https://www.google.com/settings/security/lesssecureapps
962
	#信件內容header的設定=>http://jjdai.zhupiter.com/2010/10/php-%E5%A6%82%E4%BD%95%E5%82%B3%E9%80%81%E4%B8%80%E5%B0%81-mime-html-%E6%A0%BC%E5%BC%8F%E7%9A%84-email-%E4%BF%A1%E4%BB%B6/
963
	#檔案每列不得超超過70個字元=>http://php.net/manual/en/function.mail.php
964
	#寄信給多人=>https://github.com/curl/curl/issues/784
965
	#備註:
966
	#信件的內容格式有錯,導致本文無法顯示.
967
	$curlSmtp=mail::curlSmtp($conf);
968
	unset($conf);
969
 
970
	#如果執行失敗
971
	if($curlSmtp["status"]==="false")
972
	{
973
		#印出內容
974
		var_dump($curlSmtp);
975
 
976
		#結束執行
977
		exit;		
978
 
979
	}#if end
980
 
123 liveuser 981
}#function sendMail end