項目需要,監控mysql佔用磁盤量,並在cacti上顯示出來。
由於不是mysql裏每個database都要監控,並且數量和名稱也不是固定的,所以就不能像snmp或者使用script/command的方式獲取固定的內容了。的使用到index,並讓用戶來選擇。
ps:前面寫了幾篇,比較凌亂,而且也有錯誤的地方,畢竟寫了那麼多字也懶的刪了。
再寫一篇吧
本次詳細寫了一個cacti能使用的script query的製作方法,語言採用php。cacti的web頁面必須使用mysql,so使用php不存在還要安裝依賴或者庫什麼的問題。
方法1:在數據庫所在機,寫個腳本或者程序,查看mysql的存儲目錄,並上傳到cacti上
分析1:由於cacti是採用輪訓的機制,與cacti接口比較麻煩,放棄。
方法2:在mysql機器上定製一個mib文件來擴展snmp的內容,使mysql的信息能夠在cacti上使用snmp查詢的方式來獲取到。
分析2:定製mib,就必須寫一個守護程序來定時更新snmp裏的數據,如果寫不好安全性和穩定性有問題。再一個做運維嘛小東西寫寫,服務還是由開發來寫吧 :)【這種方法最靠譜,但難度大】
方法3:使用script在cacti上直接獲取mysql的信息
分析3:效率低,可能有網絡異常。需要開放監控賬戶的權限,由於本次項目mysql全部是監聽內網網口,安全性沒問題,在同一個局域網,網絡問題不大,再一個開發快。【採用此方式】
一、數據採集方法
使用mysql的內部語句來統計數據庫的大小,可能與磁盤佔用量有差別,但也基本顯示出了磁盤佔用情況。
使用的查詢語句:
select sum(DATA_LENGTH)+sum(INDEX_LENGTH) from information_schema.tables where table_schema='數據庫名';
另外賬戶還必須有show databases;的權限
二、採集過程
1、首先查詢出mysql需要統計的數據庫,並列出相關信息(就是數據庫的描述了)
2、選擇需要統計的數據庫,使用模板創建圖形,和輪訓獲取數據並保存
3、在需要的時候來看過往的數據庫大小的變化了
三、實現過程
完成這個任務,需要2個文件:
描述功能和方法的xml文件;
實現具體功能php文件;
先創建一個xml來讓cacti知道如何獲取mysql裏的數據庫名(由於數據庫沒有索引值,這裏索引和描述都爲數據庫名)
文件名:flashapp_mysql_space.xml
<interface> <name>get mysql databases</name> <script_path>|path_php_binary| -q |path_cacti|/scripts/flashapp_mysql_space.php</script_path> <arg_prepend>|host_hostname|</arg_prepend> <arg_index>index</arg_index> <arg_query>query</arg_query> <arg_get>get</arg_get> <arg_num_indexes>num_index</arg_num_indexes> <output_delimeter>:</output_delimeter> <index_order>hrDataBasesIndex</index_order> <index_order_type>numeric</index_order_type> <fields> <hrDataBasesIndex> <name>DataBasesIndex</name> <direction>input</direction> <query_name>index</query_name> </hrDataBasesIndex> <hrDataBasesDescr> <name>Description</name> <direction>input</direction> <query_name>desc</query_name> </hrDataBasesDescr> <hrDataBasesSize> <name>Total Size</name> <direction>output</direction> <query_name>space</query_name> </hrDataBasesSize> </fields> </interface>
xml中詳細描述了,如何獲取索引、如何查詢索引對應的相關信息、以及如何獲取具體的數據
<fields> ..... </fields> 這部分,描述了使用給cacti輸入和保存的數據的內容,有個類型input和output,input是在device添加Data Query後創建圖表時出現【選擇列表】時出現的信息,outpu爲創建圖表後rrd文件保存的數據。
其他部分:
<name> | 不解釋 |
<script_path> | 也不解釋了吧,其中|path_php_binary| 等爲cacti的變量,大家可以看手冊 |
<arg_prepend> | 爲flashapp_mysql_space.php 後面跟的參數多個用空格空開,我們這裏主要主機的ip就可以了 |
<arg_index> | 獲取索引的關鍵字,這裏也就是指使用 flashapp_mysql_space.php |host_hostname| index 來獲取索引,如果你不是index,是list或者什麼的自己改吧(別和系統的衝突就好) |
<arg_query> | 何獲取其他信息使用的關鍵字,比如每個表格的描述信息,其實也就是下面fields中input信息的獲取方法實際命令爲: flashapp_mysql_space.php |host_hostname| query <類型是input的query_name> |
<arg_get> | 獲取output使用的關鍵字,實際命令 flashapp_mysql_space.php |host_hostname| get <query_name> <index> 注意輸出不能有換行符 |
<arg_num_indexes> | 索引數量,也可以沒有,cacti會自己統計 |
<output_delimeter> | 在使用query時,索引和數據之間的分隔符 |
<index_order> | 索引排序依據,可使用fields裏面的input類型的名字,也可以是多個,用冒號【:】分隔. |
<index_order_type> | 排序方法 numeric:1,2,3,10,20,31 alphabetic:1,10,2,20,3,31 |
fields->name | |
fields->direction | input output |
fields->query_name | script 查詢此項時使用的關鍵字 如本例的hrDataBasesIndex,是個input,query_name爲desc,所以命令爲: flashapp_mysql_space.php |host_hostname| query desc 如果是hrDataBasesSize 那就是: flashapp_mysql_space.php |host_hostname| get space <索引> |
ok,到這步應該都知道怎麼寫你自己的xml文件了吧,對了<interface>,這個名字隨便起,一般用<query></query>
接下來該寫php文件來獲取數據了
先用命令行方式來看下執行結果,程序見最後
獲取索引
[root@localhost ~]# php flashapp_mysql_space.php 192.168.1.84 index cacti cacti1 cacti2 test1 [root@localhost ~]#
獲取索引數
[root@localhost ~]# php flashapp_mysql_space.php 192.168.1.84 num_index 4 [root@localhost ~]#
獲取選擇列表的內容(由於數據庫木有索引,所以索引和描述相同)
[root@localhost ~]# php flashapp_mysql_space.php 192.168.1.84 query index cacti:cacti cacti1:cacti1 cacti2:cacti1 test1:test1 [root@localhost ~]# php flashapp_mysql_space.php 192.168.1.84 query desc cacti:cacti cacti1:cacti1 cacti2:cacti1 test1:test1 [root@localhost ~]#
獲取數據庫大小
[root@localhost ~]# php flashapp_mysql_space.php 192.168.1.84 get space cacti 664589[root@localhost ~]# [root@localhost ~]# php flashapp_mysql_space.php 192.168.1.84 get space cacti1 804581[root@localhost ~]#
今天太晚,睡覺明天繼續寫如何配置到cacti裏
文件:flashapp_mysql_space.php
<?php /* * flashapp_mysql_space.php * ------------------------------------------------- * enable cacti to read mysql database size * Originally by tongyuan at flashapp dot cn - 2013/12/25 * * * usage: * flashapp_mysql_space.php db_host <index|num_nidex> * flashapp_mysql_spqce.php db_host query index|desc * flashapp_mysql_spqce.php db_host get space database_name * * mysql user must have permissions to do this. * give mysqluser /show databases/ and /select/ permissions . * * examle: * grant select,show databases on *.* \ * to monitor@'192.168.1.0/255.255.255.0' identified by 'monitor'; * */ # all of host use the same account and password # you can change it by youself. $username = "monitor"; $password = "monitor"; # enable or disable debug mode # use debug mode in cli # 0 - disable # 1 - enable $debug=0; # this is cacti's header ,not use for this script. # i am not sure for that. # deactivate http headers $no_http_headers = true; # include some cacti files for ease of use include(dirname(__FILE__) . "/../include/global.php"); include(dirname(__FILE__) . "/../lib/snmp.php"); $host = $_SERVER["argv"][1]; //get all dabase name and count,expect system database. if ($_SERVER["argc"] >= 3 ) { $cmd=$_SERVER["argv"][2]; if (@mysql_connect($host,$username,$password)) { $alldataBase = @mysql_query("show databases"); $dataBaseNum = 0; $dataBase=array(); while ($row=@mysql_fetch_array($alldataBase)) { if ( $row[0] != "information_schema" && $row[0] != "mysql" && $row[0] != "performance_schema" && $row[0] != "test" ) { $dataBase[]=$row[0]; $dataBaseNum+=1; } } /*DEBUG*/if ($debug) {echo "all dataBase Number is :";print_r($dataBaseNum);echo "\n";} /*DEBUG*/if ($debug) {echo "all dataBase is :";print_r($dataBase);echo "\n";} // output index if ($cmd == 'index') { foreach ($dataBase as $d){echo $d."\n";} exit(0); } // output index_number if ($cmd == "num_index" ) { echo $dataBaseNum . "\n"; exit(0); } if ($cmd == "query" || $cmd =="get" ) { $arg=$_SERVER["argv"][3]; if ($dataBaseNum == 0) {exit(0);} // output database space if ($cmd == "query" && ($arg == "index" || $arg == "desc")) { foreach ($dataBase as $key => $value) { echo $value . ":" .$value . "\n"; } exit(0); } if ($cmd == "get" && $arg == "space") { $dataBaseSpace=array(); foreach ($dataBase as $row){ $resault=@mysql_query("select sum(DATA_LENGTH)+sum(INDEX_LENGTH) from information_schema.tables where table_schema='".$row."'"); $space=@mysql_fetch_row($resault)[0]; $dataBaseSpace[] = $space?$space:"0"; //return NULL if database is empty,so change to zero. } /*DEBUG*/if ($debug) {echo "All dataBase space is :";print_r($dataBaseSpace);echo "\n";} $get_database=$_SERVER["argv"][4]; foreach ($dataBase as $key => $value) { if ($value == $get_database){ echo $dataBaseSpace[$key]; } } } } } else { die("Can't connected to Server!\n"); } } ?>