欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

基于java的zabbix4.4 API开发

程序员文章站 2022-07-11 11:53:08
...

为什么要写这篇博客呢,是因为最近做的视频结构化运维系统有集成zabbix做服务器监控,项目需要调用zabbix得api来获取服务器的指标。所以呢边学习便记录。

api开发有两种方式,一种是基于zabbix4j得jar包开发,一种是http直接调用,今天得博客就是通过http来调用,因为zabbix4j有些许毛病。

在学习api之前,建议先去zabbix官方看看文档,学习一下zabbix的api有哪些参数,数据传递格式是怎样的,还有学习一下zabbix的专业术语,否则下面别看了。

官方api文档:https://www.zabbix.com/documentation/current/manual/api

api列表:https://www.zabbix.com/documentation/current/manual/api/reference

1.新建了个zabbix项目,什么jar包都没导,不需要,主要学习调用zabbix的api流程

先配置一下zabbix所需的配置

#zabbix的api请求地址
zabbix.url=http://192.168.57.128
zabbix.interface=/zabbix/api_jsonrpc.php
#zabbix的jsonrpc版本
zabbix.jsonrpc = 2.0
zabbix.username=Admin
zabbix.password=zabbix

2.封装个http工具类用来向zabbix发送请求,不想封装的也可以用hutool,有现成的大量的工具类,hutool安排

package com.xrj.zabbix.tools;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class HttpUtils {
    private static final Logger logger = LoggerFactory.getLogger(HttpUtils.class);
    /**
     * @param url 请求zabbix接口的地址
     * @param param 请求的参数
     * @param method 请求方法
     */
    public static String post(String url , String param , String method){
        HttpURLConnection connection = null;
        DataOutputStream out = null;
        BufferedReader reader = null;
        StringBuffer sb = null;
        try {
            //创建连接
            URL linkUrl = new URL(url);
            connection = (HttpURLConnection) linkUrl.openConnection();
            //默认链接设置
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);
            connection.setRequestMethod(method);
            connection.setRequestProperty("Accept", "application/json"); // 设置接收数据的格式
            connection.setRequestProperty("Content-Type", "application/json"); // 设置发送数据的格式
            //链接连接
            connection.connect();

            //POST请求
            out = new DataOutputStream(connection.getOutputStream());
            //设置发送的编码格式
            out.write(param.getBytes("UTF-8"));
            out.flush();

            //读取响应
            reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String lines;
            sb = new StringBuffer("");
            while ((lines = reader.readLine()) != null) {
                lines = new String(lines.getBytes(), "utf-8");
                sb.append(lines);
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("错误信息:" + e.getMessage());
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    logger.error("错误信息:" + e.getMessage());
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    logger.error("错误信息:" + e.getMessage());
                }
            }
            if (connection != null) {
                connection.disconnect();
            }
        }
        return sb.toString();
    }
}

3.再封装个zabbix的请求体,因为请求zabbix接口时的请求体是这样的:

{ 
    “ jsonrpc” : “ 2.0”,
     “ method” : “ host.get”,
     “ params” : { 
        “ output” : [ 
            “ hostid”,
             “ host” 
        ],
         “ selectInterfaces” : [ 
            “ interfaceid”,
             “ ip” 
        ] 
    },
     “ id” : 2,
     “ auth” : “ 0424bd59b807674191e7d77572075f33” 
}

其中包含了以下属性:

  • jsonrpc-API使用的JSON-RPC协议版本;Zabbix API实现JSON-RPC版本2.0;
  • method- 被调用的API方法;
  • params-将传递给API方法的参数;
  • id -请求的任意标识符;
  • auth-用户认证令牌;由于我们还没有,所以设置为null
所以我将这5个属性封装成实体类:
 
package com.xrj.zabbix.tools;

import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;
@Data
@Accessors(chain = true)
public class ZabbixRequest implements Serializable {
    /**
     *
     */
    private static final long serialVersionUID = 1L;

    private Integer id = 1;
    private String jsonrpc="2.0"; // 状态代码
    private String method; // 代码信息
    private Object params;
    private String auth;

    public ZabbixRequest(String method) {
        this.method = method;
    }

    public ZabbixRequest(String method, Object params) {
        this.method = method;
        this.params = params;
    }

    public ZabbixRequest(String method, Object params, String auth) {
        this.method = method;
        this.params = params;
        this.auth = auth;
    }

}

4.再封装一个zabbixTools,内容如下,主要用于封装post请求方法:

package com.xrj.zabbix.tools;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class ZabbixTools {

    private static String ZABBIX_URL;
    private static String ZABBIX_INTERFACE;
    @Value("${zabbix.url}")
    public void setZabbixUrl(String zabbixUrl) {
        ZabbixTools.ZABBIX_URL = zabbixUrl;
    }
    @Value("${zabbix.interface}")
    public void setZabbixInterface(String zabbixInterface) {
        ZabbixTools.ZABBIX_INTERFACE = zabbixInterface;
    }

    /**
     * 向zabbix发送post请求
     * @param request
     * @return
     */
    public static String sendPost(ZabbixRequest request) {
        return HttpUtils.post(ZABBIX_URL + ZABBIX_INTERFACE, JSON.toJSONString(request), "POST");
    }

    public static String sendPost(String url, ZabbixRequest request) {
        return HttpUtils.post(url + ZABBIX_INTERFACE, JSON.toJSONString(request), "POST");
    }

    public static String sendPost(String url, String port, ZabbixRequest request) {
        return HttpUtils.post(url + ":" + port + ZABBIX_INTERFACE, JSON.toJSONString(request), "POST");
    }
}

5.测试一下接口,在调用接口时,要先模拟登录拿到令牌,像token那样,拿到令牌后才能正常获取数据(下面测试获取服务器总内存,实际972M,有点少哈哈)。

package com.xrj.zabbix;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xrj.zabbix.tools.ZabbixRequest;
import com.xrj.zabbix.tools.ZabbixTools;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.HashMap;
import java.util.Map;

@SpringBootTest
class ZabbixApplicationTests {
    @Value("${zabbix.username}")
    private String USERNAME;

    @Value("${zabbix.password}")
    private String PASSWORD;


    @Test
    void zabbixTools(){
        //全局zabbixRequest
        ZabbixRequest zabbixRequest=null;


        //获取zabbix权限begin
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("user", USERNAME);

        params.put("password", PASSWORD);

        zabbixRequest=new ZabbixRequest("user.login",params,null);
        String response= ZabbixTools.sendPost(zabbixRequest);

        //拿到auth
        JSONObject json = JSON.parseObject(response);
        String auth=json.getString("result");
        System.out.println(auth);

        //获取服务器内存信息
        //1.通过ip获取服务器的唯一标识
        Map<String, Object> filter = new HashMap<String, Object>();
        filter.put("ip", "192.168.57.128");
        params.clear();
        params.put("output", "extend");
        params.put("filter", filter);
        zabbixRequest=new ZabbixRequest("host.get",params,auth);
        String response1= ZabbixTools.sendPost(zabbixRequest);

        JSONArray result = JSON.parseObject(response1).getJSONArray("result");
        String hostid=null;
        if (result.size() > 0) {
            JSONObject json1 = result.getJSONObject(0);
            hostid = json1.getString("hostid");
            System.out.println(hostid);
        }else{
            System.out.println("未获取到hostid");
        }

        //2.获取监控项唯一标识
        String key="system.swap.size[,total]";
        Map<String, Object> search = new HashMap<String, Object>();
        search.put("key_", key);
        params.clear();
        params.put("output", "extend");
        params.put("hostids", hostid);
        params.put("search", search);
        zabbixRequest=new ZabbixRequest("item.get",params,auth);
        String response2= ZabbixTools.sendPost(zabbixRequest);
        JSONArray result1=JSON.parseObject(response2).getJSONArray("result");
        String itemid=null;
        if (result1.size() > 0) {
            JSONObject json2 = result1.getJSONObject(0);
            if (json2 != null) {
                itemid=json2.getString("itemid");
                System.out.println(itemid);
            }
        }

        //3.获取当前数据
        params.clear();
        params.put("output", "extend");
        params.put("itemids", itemid);
        zabbixRequest=new ZabbixRequest("item.get",params,auth);
        String response3= ZabbixTools.sendPost(zabbixRequest);
        JSONArray result2 = JSON.parseObject(response3).getJSONArray("result");
        System.out.println(result2.getJSONObject(0).getIntValue("lastvalue"));
    }

}

打印结果如下(返回的数据是以bety为单位):

1019580416

1019580416字节换算成M为972.347M,我们来看看监控页面的值:

基于java的zabbix4.4 API开发

数据一样,没有毛病。

6.到这里zabbix的api调用流程就写完了,接下来送一份zabbix接口开发的工具类:

package com.xrj.zabbix.tools;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
public class ZabbixUtil {

    private static String URL = "http://192.168.57.128/zabbix/api_jsonrpc.php";

    private static String AUTH = null;

    private static final String USERNAME = "Admin";

    private static final String PASSWORD = "zabbix";


    /**
     * 向Zabbix发送Post请求,并返回json格式字符串
     *
     * @param map 请求参数
     * @return
     * @throws Exception
     */
    public static String sendPost(Map map) {
        String param = JSON.toJSONString(map);
        HttpURLConnection connection = null;
        DataOutputStream out = null;
        BufferedReader reader = null;
        StringBuffer sb = null;
        try {
            //创建连接
            URL url = new URL(URL);
            connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Accept", "application/json"); // 设置接收数据的格式
            connection.setRequestProperty("Content-Type", "application/json"); // 设置发送数据的格式

            connection.connect();

            //POST请求
            out = new DataOutputStream(connection.getOutputStream());
            out.writeBytes(param);
            out.flush();

            //读取响应
            connection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String lines;
            sb = new StringBuffer("");
            while ((lines = reader.readLine()) != null) {
                lines = new String(lines.getBytes(), "utf-8");
                sb.append(lines);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                connection.disconnect();
            }
        }
        return sb.toString();

    }


    /**
     * 通过用户名和密码设置AUTH,获得权限 @
     */
    public static void setAuth() {

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("user", USERNAME);

        params.put("password", PASSWORD);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("jsonrpc", "2.0");
        map.put("method", "user.login");
        map.put("params", params);
        map.put("auth", null);
        map.put("id", 0);

        String response = sendPost(map);
        JSONObject json = JSON.parseObject(response);
        AUTH = json.getString("result");
    }


    private static String getAuth() {
        if (AUTH == null) {
            setAuth();
        }
        return AUTH;
    }


    /**
     * 获得主机hostid
     *
     * @param host Zabbix中配置的主机hosts
     * @return 返回hostid @
     */
    public static String getHostIdByHostName(String host) {
        Map<String, Object> filter = new HashMap<String, Object>();
        filter.put("host", host);
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("output", "hostid");
        params.put("filter", filter);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("jsonrpc", "2.0");
        map.put("method", "host.get");
        map.put("params", params);
        map.put("auth", getAuth());
        map.put("id", 0);

        String response = sendPost(map);
        JSONArray result = JSON.parseObject(response).getJSONArray("result");
        if (result.size() > 0) {
            JSONObject json = result.getJSONObject(0);
            String hostid = json.getString("hostid");
            return hostid;
        } else {
            return null;
        }

    }


    /**
     * 获得主机hostid
     *
     * @param ip Zabbix中配置的主机ip
     * @return 返回hostid @
     */
    public static String getHostIdByIp(String ip) {
        Map<String, Object> filter = new HashMap<String, Object>();
        filter.put("ip", ip);
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("output", "extend");
        params.put("filter", filter);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("jsonrpc", "2.0");
        map.put("method", "host.get");
        map.put("params", params);
        map.put("auth", getAuth());
        map.put("id", 0);

        String response = sendPost(map);
        JSONArray result = JSON.parseObject(response).getJSONArray("result");
        if (result.size() > 0) {
            JSONObject json = result.getJSONObject(0);
            String hostId = json.getString("hostid");
            return hostId;
        } else {
            return null;
        }

    }


    /**
     * 获得某主机的某个监控项id
     *
     * @param hostId 主机
     * @param key 监控项
     * @return 监控项itemid
     * @throws Exception
     */
    public static String getItemId(String hostId, String key) throws Exception {
        JSONArray result = getItemByHostAndKey(hostId, key);
        if (result.size() > 0) {
            JSONObject json = result.getJSONObject(0);
            if (json != null) {
                return json.getString("itemid");
            }
        }
        return null;

    }


    /**
     * 获取某主机某监控项的value_type
     *
     * @param hostId
     * @param key
     * @return
     * @throws Exception
     * @author aaa@qq.com
     * @since 创建时间:2016年8月12日 上午10:38:10
     */
    public static int getValueType(String hostId, String key) throws Exception {
        JSONArray result = getItemByHostAndKey(hostId, key);
        if (result.size() > 0) {
            JSONObject json = result.getJSONObject(0);
            if (json != null) {
                return json.getIntValue("value_type");
            }
        }
        return 3;

    }


    /**
     * 获取某主机某监控项在一段时间内的数据
     *
     * @param itemId
     * @param valueType
     * @param from
     * @param to
     * @return
     * @author aaa@qq.com
     * @since 创建时间:2016年8月18日 上午11:42:48
     */
    public static JSONArray getHistoryDataByItemId(String itemId, int valueType, long from, long to) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("output", "extend");
        params.put("history", valueType);
        params.put("itemids", itemId);
        params.put("sortfield", "clock");
        params.put("sortorder", "DESC");//时间降序
        params.put("time_from", from / 1000);
        params.put("time_till", to / 1000);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("jsonrpc", "2.0");
        map.put("method", "history.get");
        map.put("params", params);
        map.put("auth", getAuth());
        map.put("id", 0);

        String response = sendPost(map);
        JSONArray result = JSON.parseObject(response).getJSONArray("result");

        return result;

    }


    /**
     * 获取某主机某监控项最近的数据
     *
     * @param hostId
     * @param key
     * @return @
     * @author aaa@qq.com
     * @since 创建时间:2016年8月12日 上午10:31:49
     */
    public static JSONArray getItemByHostAndKey(String hostId, String key) {
        if (hostId == null) {
            return null;
        }
        Date start = new Date();

        Map<String, Object> search = new HashMap<String, Object>();
        search.put("key_", key);

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("output", "extend");
        params.put("hostids", hostId);
        params.put("search", search);

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("jsonrpc", "2.0");
        map.put("method", "item.get");
        map.put("params", params);
        map.put("auth", getAuth());
        map.put("id", 0);

        String response = sendPost(map);
        JSONArray result = JSON.parseObject(response).getJSONArray("result");

        return result;
    }


    /**
     * 多个监控项的当前数据
     *
     * @param itemIds
     * @return
     * @author aaa@qq.com
     * @since 创建时间:2016年8月18日 下午4:33:14
     */
    public static JSONArray getDataByItems(List<String> itemIds) {

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("output", "extend");
        params.put("itemids", itemIds);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("jsonrpc", "2.0");
        map.put("method", "item.get");
        map.put("params", params);
        map.put("auth", getAuth());
        map.put("id", 0);
        String response = sendPost(map);
        JSONArray result = JSON.parseObject(response).getJSONArray("result");

        return result;

    }


    /**
     * 多个监控项的历史数据
     *
     * @param itemIds
     * @param valueType
     * @param from
     * @param to
     * @return
     * @author aaa@qq.com
     * @since 创建时间:2016年8月18日 下午5:12:53
     */
    public static JSONArray getHistoryDataByItems(List<String> itemIds, int valueType, long from,
                                                  long to) {

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("output", "extend");
        params.put("history", valueType);
        params.put("itemids", itemIds);
        params.put("sortfield", "clock");
        params.put("sortorder", "DESC");//时间降序
        params.put("time_from", from / 1000);
        params.put("time_till", to / 1000);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("jsonrpc", "2.0");
        map.put("method", "history.get");
        map.put("params", params);
        map.put("auth", getAuth());
        map.put("id", 0);
        String response = sendPost(map);
        JSONArray result = JSON.parseObject(response).getJSONArray("result");
        return result;

    }

    /**
     * 获得api版本
     *
     * @return 返回hostid @
     */
    public static String getApiInfoVersion() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("jsonrpc", "2.0");
        map.put("method", "apiinfo.version");
        map.put("params", new ArrayList());
        map.put("auth", null);
        map.put("id", 0);

        String response = sendPost(map);
        JSONObject result = JSON.parseObject(response);
        String version = result.getString("result");
        return version;
    }

}

测试:

public static void main(String[] args) throws Exception {
        ZabbixUtil.setAuth();
        long time_till = new Date().getTime();
        long time_from = time_till - 5 * 60000;
        String ip = "192.168.57.128";
        String key = "system.swap.size[,total]";
        String hostId = ZabbixUtil.getHostIdByIp(ip);
        String itemId = ZabbixUtil.getItemId(hostId, key);
        int valueType = ZabbixUtil.getValueType(hostId, key);
        JSONArray jsonArray=ZabbixUtil.getHistoryDataByItemId(itemId, valueType, time_from, time_till);
        System.out.println(jsonArray);


        //System.out.println(ZabbixUtil.getApiInfoVersion());
    }

打印结果(总交换空间2g,记得bety转G):

[{"itemid":"29180","ns":"333387757","clock":"1595921480","value":"2147479552"},{"itemid":"29180","ns":"289230373","clock":"1595921420","value":"2147479552"},{"itemid":"29180","ns":"245825811","clock":"1595921360","value":"2147479552"},{"itemid":"29180","ns":"202178913","clock":"1595921300","value":"2147479552"},{"itemid":"29180","ns":"159210316","clock":"1595921240","value":"2147479552"}]

使用ZabbixUtil.getApiInfoVersion()查看目前使用的api版本:

4.4.10