项目(一)设备监控:通过PHP调用zabbix的api接口获取主机信息(内存、磁盘、cpu、ip地址、状态)以及报警信息

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33945246/article/details/89332198

项目背景介绍:zabbix已经在服务器搭建好了,只是需要远程调用zabbix的监控数据。通过php调用访问配置zabbix的服务器,获取监控数据,PHP在于Js交互(jQuery框架),将监控的数据显示在网页之上,网页已经写好,只需要修改部分Js文件以及编写php文件即可。获取要监控的设备是通过配置文件的方式,配置文件中写的是要监控的主机名

有两种方式获取监控数据,第一种是通过直接访问zabbix数据库的方式获取指定数据,第二种就是通过zabbix的自带的api接口直接获取目标数据。前者访问速度快,但是zabbix的表结构较为复杂,直接访问数据库需要对数据库的表结构有较为清楚的认识;后者访问速度慢,但是有现成的接口,不需要除了复杂的表结构关系,省时省力。

一、zabbix表结构

host表

  • 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:对主机的描述

item表

  • 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:监控项数据的单位

history表

  • itemid:监控项的 id

  • clock:时间戳,监控项采集数据的触发时间

  • value:监控项采集数据的值

  • ns:纳秒

  • 注意:历史表与监控表的关系:使用history.get来获取历史数据,需要传入的参数不止 一个监控项的id,还需传入监控项的value_type,因为如果不传入value_type,history.get方法默认取 history这个表的数据,如果itemid对应不上,就取不到数据。我们要获取的值,内存和磁盘都是numeric unsigned也就说 value_type=3cpu是numeric float,value_type=0

alter表

  • alertid:报警的id
  • alerttype:报警的类型
  • clock:报警触发的时间
  • message:报警的信息

二、php调用zabbix的api

zabbix的官方文档:
zabbix接口文档

(一)php获取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;
}

(二)读取配置文件的主机名,并获取主机id

//目标主机
$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;
}

(三)获取item项目以及主机信息

// 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进行交互。

猜你喜欢

转载自blog.csdn.net/qq_33945246/article/details/89332198