项目背景介绍:zabbix已经在服务器搭建好了,只是需要远程调用zabbix的监控数据。通过php调用访问配置zabbix的服务器,获取监控数据,PHP在于Js交互(jQuery框架),将监控的数据显示在网页之上,网页已经写好,只需要修改部分Js文件以及编写php文件即可。获取要监控的设备是通过配置文件的方式,配置文件中写的是要监控的主机名
有两种方式获取监控数据,第一种是通过直接访问zabbix数据库的方式获取指定数据,第二种就是通过zabbix的自带的api接口直接获取目标数据。前者访问速度快,但是zabbix的表结构较为复杂,直接访问数据库需要对数据库的表结构有较为清楚的认识;后者访问速度慢,但是有现成的接口,不需要除了复杂的表结构关系,省时省力。
hostid:主机的 id
proxy_hostid:代理主机的 id
host:这里代表主机的 ip
status:代表主机的状态:数据库存储有三个值:0 代表被监控,1 代表未监控,3 代表该主机是模板主机 (通过 zabbix 的 api 的 host.get 只能获取到状态为 0 的主机,通过 template.get 能获取到状态为 3 的主机)
name:主机的别名 / 昵称
flags:这个主机是否启用:0 代表启用,1 代表未启用
templateid:模板 id(有点像自关联)
description:对主机的描述
itemid:监控项的 id
type:监控项的类型:常见的有 agent,SNMP,agent (active) 等
hostid:监控项关联的主机 id
name:监控项的名称
key_ : 监控项 item 的 key 值,(数据库中存储的这个 key_的内容大概就是监控表达式比如:system.swap.size [,free] 这种
delay:配置 item 时候配置的 “Update Interval”,开发中没用到,不清楚。
history:监控项数据在历史表中保留的时间天数
trends:监控项数据在 trends 表中保留的天数
status:监控项的状态:0 代表能够使用,1 代表不能够使用
value_type:重点中的重点:有五个值:0,1,2,3,4,代表监控项不同的返回类型,这个值决定了监控项的数据会存储在哪张历史表中
0 - numeric float;
1 - character;
2 - log;
3 - numeric unsigned;
4 - text.
units:监控项数据的单位
itemid:监控项的 id
clock:时间戳,监控项采集数据的触发时间
value:监控项采集数据的值
ns:纳秒
注意:历史表与监控表的关系:使用history.get来获取历史数据,需要传入的参数不止 一个监控项的id,还需传入监控项的value_type,因为如果不传入value_type,history.get方法默认取 history这个表的数据,如果itemid对应不上,就取不到数据。我们要获取的值,内存和磁盘都是numeric unsigned也就说 value_type=3,cpu是numeric float,value_type=0
zabbix的官方文档:
zabbix接口文档
php利用自身的开源框架curl,发送http请求,获取zabbix的认证auth
$url = 'http://xxx/zabbix/api_jsonrpc.php';//xxx是配置zabbix的ip地址
$header = array("Content-type: application/json-rpc");
// get token
function Curl($url, $header, $info)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $info);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response);
}
function get_token($url, $header)
{
$user = 'xxx';//配置的zabbix的用户名
$password = 'xxx';//配置的zabbix的密码
$logininfo = array(
'jsonrpc' => '2.0',
'method' => 'user.login',//调用的zabbix的api,用于远程登录
'params' => array(
'user' => $user,
'password' => $password,
),
'id' => 1,
);
$data = json_encode($logininfo);
$result = Curl($url, $header, $data);
$token = $result->result;
return $token;
}
//目标主机
$goalHost = include ("config/PhysicalMachine_config.php");
function get_hostidFromName($hostname, $token, $header, $url)
{
$gethostid = array(
'jsonrpc' => '2.0',
'method' => 'host.get',
"params" => array(
"output" => ["hostid"],
"filter" => array(
"name" => [$hostname]
)
),
"auth"=>$token,
"id"=>1
);
$data = json_encode($gethostid);
$result = Curl($url,$header,$data);
$hostinfo= $result -> result;
if ( empty($hostinfo) )
{
$hostid ='';
}else
{
$hostid = $hostinfo[0] -> hostid;
}
return $hostid;
}
// get itemid
function get_itemid($hostid, $key, $token, $header, $url)
{
$getitemid = array(
"jsonrpc" => "2.0",
"method" => "item.get",
"params" => array(
"output" => ["itemids"],
"hostids" => $hostid,
"search" => array(
"key_" => $key
),
"sortfield" => "name"
),
"auth" => $token,
"id" => 1
);
$data = json_encode($getitemid);
$result = Curl($url, $header, $data);
$iteminfo = $result->result;
if (empty($iteminfo)) {
$itemid = 'null';
} else {
$itemid = $iteminfo[0]->itemid;
}
return $itemid;
}
// get zabbix value
function get_resource($itemid, $token, $header, $url, $history, $historylimit)
{
$gethistory = array(
"jsonrpc" => "2.0",
"method" => "history.get",
"params" => array(
"output" => "extend",
"history" => $history,
"itemids" => $itemid,
"sortfield" => "clock",
"sortorder" => "DESC",
"limit" => $historylimit
),
"auth" => $token,
"id" => 1
);
$data = json_encode($gethistory);
$result = Curl($url, $header, $data);
$historytotal = $result->result;
$resource = object_array($historytotal);
return $resource;
}
/**
* php数组可以是键值对形式的数据
* 每一个返回的信息都是被封装过的键值对
* foreach把数组的value取出来封装成数组,现在是key(从0开始的整数)-array(id,name)的形式
*/
//获取token
$token = get_token($url, $header);
//获取所有主机信息
$hostlist = get_hostid( $token, $header, $url);
//test from name get id
//$hostids = get_hostidFromName($goalHost[0], $token, $header, $url);
//print_r($hostids);
//获取内存,磁盘,cpu信息
for ($i = 0; $i <count($goalHost) ; $i++) {
//指定要获取的主机信息,cup,内存,磁盘
$source = array('vm.memory.size[available]',
'vm.memory.size[total]',
'system.cpu.util[,idle]',
'vfs.fs.size[/,used]',
'vfs.fs.size[/,total]');
// 存放所有信息的数组
$hostInfo_all = array();
$token = get_token($url, $header);
//get id
$hostid = get_hostidFromName($goalHost[$i], $token, $header, $url);
//get status and ip
$description = get_hostDescription($goalHost[$i], $token, $header, $url);
$status = $description -> status;
$interfaces = $description ->interfaces;
$ip = $interfaces[0] ->ip;
//给数组添加CPU,内存,磁盘属性
foreach ($source as $key) {
if ($key == 'system.cpu.util[,idle]') {
$history = 0;
} else {
$history = 3;
}
//get item
$itemid = get_itemid($hostid, $key, $token, $header, $url);
//get value
$resource = get_resource($itemid, $token, $header, $url, $history, $historylimit);
//把key修改为方便读取的字段
switch ($key) {
case 'vm.memory.size[available]':
$key = 'memory_available';
break;
case 'vm.memory.size[total]':
$key = 'memory_total';
break;
case 'system.cpu.util[,idle]':
$key = 'cpu_idle';
break;
case 'vfs.fs.size[/,used]':
$key = 'fs_used';
break;
case 'vfs.fs.size[/,total]':
$key = 'fs_total';
break;
}
if(!empty($resource)){
//存放单个信息的数组
$zabbix_info = $resource[0]['value'];
//把内存,CPU,磁盘包装成数组
$hostInfo_all[] = array($key => $zabbix_info);
}else{
$hostInfo_all[] = array($key => 'null');
}
}
//给数组添加statue属性和ip属性
$hostInfo_all[] = array("status" => $status);
if(!empty($ip)){
$hostInfo_all[] = array("ip" => $ip);
}else{
$hostInfo_all[] = array("ip" => "null");
}
//把goalHost数组中的name存在空格的替换为-
$host_goal_name = str_replace(' ', '-', $goalHost[$i]);
//把所有属性绑定主机名
$hostinfo = array($host_goal_name => $hostInfo_all);
//返回json数据,每次打印一个主机的所有信息,有多少主机就echo多少次,js是统一接收
echo json_encode($hostinfo, JSON_UNESCAPED_UNICODE);
echo " ";
}
项目下载
使用的时候,需要把代码中的
$url,$user,$password
修改成自己项目的配置。
同时这只是服务器的php部分,这部分代码只是获取到数据并把数据以json串的形式传送到前端,具体还需与前端的js进行交互。