最近項目需要獲取linux主機的一些信息,如CPU使用率,內存使用情況等。由於我們本身就裝了zabbix系統,所以我只用知道如何獲取信息即可,總結有兩種方法可以獲取。
一、通過ZABBIX API獲取主機信息
這種方式獲取的主機信息相對是比較新的(每分鍾更新一次)。但因為每次都需要請求接口,所以相對比較慢,如果並發查詢的主機數量比較多,就會非常慢。
開源監控系統ZABBIX的官方文檔提供了豐富的API。我這里http請求是用的Guzzle 6。當然你也可以用php內置的curl函數自己寫一個http請求,非常簡單。
1、用戶認證以獲取token。
$responst = $this->httpClient->request('POST', 'http://zabbix.xxxxx.com/zabbix/api_jsonrpc.php', [
'headers' => [
'Content-Type' => 'application/json-rpc',
],
'json' => [
'jsonrpc' => '2.0',
'method' => 'user.login',
'params' => [
"user"=> 'your username',
"password"=> 'your password'
],
'id' => 1,
'auth' => null
],
]);
由於這里是用戶認證,所有 auth 可以直接寫 null 。返回結果為:
{ "jsonrpc": "2.0", "result": "0424bd59b807674191e7d77572075f33", "id": 1 }
result 里就是 token ,在后面的請求中都是需要的。
2、根據主機的IP獲取hostid。
$responst = $this->httpClient->request('POST', 'http://zabbix.xxxxx.com/zabbix/api_jsonrpc.php', [ 'headers' => [ 'Content-Type' => 'application/json-rpc', ], 'json' => [ 'jsonrpc' => '2.0', 'method' => 'host.get', 'params' => [
"output" => ["hostid"],
"filter" => [
"host" => '192.168.1.1'
]
],
'id' => 1,
'auth' =>"0424bd59b807674191e7d77572075f33"
], ]);
上面的 output 是限制返回項,如果想要返回所有的主機信息,可以去掉 output 。上面請求的返回結果為:
{ "jsonrpc": "2.0", "result": [ { "hostid": "10160", } ], "id": 1 }
3、獲取主機的監控項itemid。
zabbix提供了很多監控項,那么問題來了,哪些才是我們需要的呢?下面是博主給大家介紹幾個常用的監控項:
$items = array( 'vm.memory.size[available]', // 內存可用值 (KB) 'vm.memory.size[total]', // 內存總數 (KB) 'system.cpu.util[,idle]', // 當前CPU IDLE值 (%) 'vfs.fs.size[/,used]', // 當前 / 盤使用值 (KB) 'vfs.fs.size[/,total]', // 當前 / 盤總數 (KB) );
$item_ids = array();
foreach ($items as $item) {
$responst = $this->httpClient->request('POST', $this->url, [
'headers' => [
'Content-Type' => 'application/json-rpc',
],
'json' => [
'jsonrpc' => $this->jsonrpc,
'method' => $this->METHOD_ITEM_GET,
'params' => [
"output" => 'extend',
"hostids" => $this->hostid,
"search" => [
"key_" => $item
],
'sortfield' => 'name'
],
'id' => 1,
'auth' => $this->token
],
]);
$body = json_decode($responst->getBody()->getContents());
$item_ids[] = $body->result[0]->itemid;
}
返回的結果為:
{ "jsonrpc": "2.0", "result": [ { "itemid": "23298", "type": "0", "snmp_community": "", "snmp_oid": "", "hostid": "10084", "name": "Context switches per second", "key_": "vm.memory.size[available]", "delay": "60", "history": "7", "trends": "365", "lastvalue": "2552", "lastclock": "1351090998", "prevvalue": "2641", "state": "0", "status": "0", "value_type": "3", "trapper_hosts": "", "units": "sps", "multiplier": "0", "delta": "1", "snmpv3_securityname": "", "snmpv3_securitylevel": "0", "snmpv3_authpassphrase": "", "snmpv3_privpassphrase": "", "snmpv3_authprotocol": "0", "snmpv3_privprotocol": "0", "snmpv3_contextname": "", "formula": "1", "error": "", "lastlogsize": "0", "logtimefmt": "", "templateid": "22680", "valuemapid": "0", "delay_flex": "", "params": "", "ipmi_sensor": "", "data_type": "0", "authtype": "0", "username": "", "password": "", "publickey": "", "privatekey": "", "mtime": "0", "lastns": "564054253", "flags": "0", "interfaceid": "1", "port": "", "description": "", "inventory_link": "0", "lifetime": "0", "evaltype": "0" } ], "id": 1 }
4、獲取對應監控項的歷史信息
上一步中我們獲取到了所有對應監控項的itemid。現在獲取這些監控項的歷史信息。這個接口中的信息是每分鍾更新一次的,所以具體要去多久的信息看各自的需求。
$items_result = array(); foreach ($this->itemids as $k=>$itemid) { if($this->items[$k] == 'system.cpu.util[,idle]') { $history = 0; }else { $history = 3; } $responst = $this->httpClient->request('POST', 'http://zabbix.xxxxx.com/zabbix/api_jsonrpc.php', [ 'headers' => [ 'Content-Type' => 'application/json-rpc', ], 'json' => [ 'jsonrpc' => '2.0', 'method' => 'history.get', 'params' => [ "output" => 'extend', "history" => $history, "itemids" => $itemid, "sortfield" => 'clock', 'sortorder' => 'DESC', 'limit' => '1', ], 'id' => 1, 'auth' => $this->token ], ]); $body = json_decode($responst->getBody()->getContents()); if(property_exists($body, 'result')) { $items_result[$this->items[$k]] = $body->result[0]->value; }else { Log::error(json_encode($body)); return false; } }
返回結果為:
{ "jsonrpc": "2.0", "result": [ { "itemid": "23296", "clock": "1351090996", "value": "0.0850", "ns": "563157632" }, { ], "id": 1 }
最終的結果應該為:
array:5 [▼ "system.cpu.util[,idle]" => 98.9622 "vfs.fs.size[/,total]" => "42141548544" "vfs.fs.size[/,used]" => "6917797137" "vm.memory.size[available]" => "57394996906" "vm.memory.size[total]" => "67439050752" ]
二、直接從數據庫獲取信息
這種方式獲取的數據並不是最新的(每小時更新一次)。但查詢速度大大的提升了。
因為我是用laravel框架寫的代碼,所有就偷懶一下,不寫原生的sql語句了,大家湊合看。
1、通過ip從hosts表獲取hostid
$host_id = Host::where('host', '10.50.150.80')->value('hostid');
返回結果為: 11101
2、通過hostid從items表獲取items監控項的itemid
$items = array( 'vm.memory.size[available]', // 內存可用值 (KB) 'vm.memory.size[total]', // 內存總數 (KB) 'system.cpu.util[,idle]', // 當前CPU IDLE值 (%) 'vfs.fs.size[/,used]', // 當前 / 盤使用值 (KB) 'vfs.fs.size[/,total]', // 當前 / 盤總數 (KB) ); $item_ids = Item::where('hostid', 11106)->whereIn('key_', $items)->pluck('itemid', 'key_');
返回結果為:
Collection {#183 ▼ #items: array:5 [▼ "system.cpu.util[,idle]" => 152511 "vfs.fs.size[/,total]" => 155584 "vfs.fs.size[/,used]" => 155587 "vm.memory.size[available]" => 152533 "vm.memory.size[total]" => 152534 ] }
3、通過itemid從trends表或trends_uint表獲取歷史信息
$result = array(); foreach ($item_ids as $key=>$item_id) { if($key == 'system.cpu.util[,idle]') { $value = Trend::where('itemid', $item_id)->orderBy('clock', 'DESC')->value('value_avg'); }else { $value = TrendsUint::where('itemid', $item_id)->orderBy('clock', 'DESC')->value('value_avg'); } $result[$key] = $value; }
返回結果為:
array:5 [▼ "system.cpu.util[,idle]" => 98.9622 "vfs.fs.size[/,total]" => "42141548544" "vfs.fs.size[/,used]" => "6917797137" "vm.memory.size[available]" => "57394996906" "vm.memory.size[total]" => "67439050752" ]