sentine-dashboard集成grafana

sentine-dashboard集成grafana
利用grafana官方api实现接口:https://grafana.com/docs/grafana/latest/http_api/dashboard/
1 grafana相关配置信息

spring.grafana.url=http://127.0.0.1:3000
spring.grafana.user=user
spring.grafana.password=password

是否开启APIKey 登录验证

spring.grafana.isAPIkey=false
spring.grafana.APIKey.Admin=APIKey
spring.grafana.APIKey.Viewer=APIKey
spring.grafana.APIKey.Editor=APIKey

2 生成APIKey
在这里插入图片描述
在这里插入图片描述
3 编写GrafanaUtil

/**
 * @Auther: shanzhu
 * @Date: 2020/10/23 11:53
 * @Description: Grafana 工具类
 */
@Component("GrafanaUtil")
public class GrafanaUtil {
    /**
     * grafana地址
     **/
    private static String grafanaUrl;

    /**
     * grafana用户名
     **/
    private static String username;

    /**
     * grafana密码
     **/
    private static String password;

    /**
     * 是否开启APIKey 登录验证
     **/
    private static Boolean isAPIkey;

    /**
     * 最高权限
     **/
    private static String APIKey_Admin;

    /**
     * 查看权限
     **/
    private static String APIKey_Viewer;

    /**
     * 编辑权限
     **/
    private static String APIKey_Editor;

    @Value("${spring.grafana.url}")
    public void setGrafanaUrl(String param) {
        grafanaUrl = param;
    }

    @Value("${spring.grafana.user}")
    public void setUsername(String param) {
        username = param;
    }

    @Value("${spring.grafana.password}")
    public void setPassword(String param) {
        password = param;
    }

    @Value("${spring.grafana.isAPIkey}")
    public void setIsAPIkey(Boolean param) {
         isAPIkey = param;
    }

    @Value("${spring.grafana.APIKey.Admin}")
    public void setAPIKey_Admin(String param) {
        APIKey_Admin = param;
    }

    @Value("${spring.grafana.APIKey.Viewer}")
    public void setAPIKey_Viewer(String param) {
        APIKey_Viewer = param;
    }

    @Value("${spring.grafana.APIKey.Editor}")
    public void setAPIKey_Editor(String param) {
        APIKey_Editor = param;
    }

    public static String getGrafanaUrl() {
        return grafanaUrl;
    }

    /**
     * @Author: shanzhu
     * @Date: 2020/10/26 15:35
     * @Description: 身份验证,是否登录
     **/
    public static String getAuth(Integer key_num) throws Exception{
        HttpResponse<JsonNode> response;
        if(isAPIkey){
            response = Unirest.get(grafanaUrl+"/api/login/ping")
                    .header("Accept", "application/json")
                    .header("Content-Type","application/json")
                    .header("Authorization",getAPIkey_authHeader(key_num))
                    .asJson();
        }else {
            response = Unirest.get(grafanaUrl+"/api/login/ping")
                    .basicAuth(username,password)
                    .header("Accept", "application/json")
                    .header("Content-Type","application/json")
                    .asJson();
        }
        return  response.getParsingError().get().getOriginalBody();
    }

    /**
     * @Author: shanzhu
     * @Date: 2020/10/28 9:46
     * @Description: 新增 或者 更新 bashboard
     * JSON Body schema:
     *     dashboard – The complete dashboard model, id = null to create a new dashboard.
     *     dashboard.id – id = null to create a new dashboard.
     *     dashboard.uid – Optional unique identifier when creating a dashboard. uid = null will generate a new uid.
     *     folderId – The id of the folder to save the dashboard in.
     *     overwrite – Set to true if you want to overwrite existing dashboard with newer version, same dashboard title in folder or same dashboard uid.
     *     message - Set a commit message for the version history.
     *     refresh - Set the dashboard refresh interval. If this is lower than the minimum refresh interval, then Grafana will ignore it and will enforce the minimum refresh interval.
     *     ps:String str = "{\n" +
     *                 "  \"dashboard\": {\n" +
     *                 "    \"id\": null,\n" +
     *                 "    \"uid\": null,\n" +
     *                 "    \"title\": \"Production Overview\",\n" +
     *                 "    \"tags\": [ \"templated\" ],\n" +
     *                 "    \"timezone\": \"browser\",\n" +
     *                 "    \"schemaVersion\": 16,\n" +
     *                 "    \"version\": 0,\n" +
     *                 "    \"refresh\": \"25s\"\n" +
     *                 "  },\n" +
     *                 "  \"folderId\": 0,\n" +
     *                 "  \"overwrite\": false\n" +
     *                 "}";
     * @param
     *
     **/
    public static String insertOrUpdateBashboard(String jsonString,Integer key_num) throws Exception{
        HttpResponse<JsonNode> response;
        if(isAPIkey){
            response = Unirest.post(grafanaUrl+"/api/dashboards/db")
                    .header("Accept", "application/json")
                    .header("Content-Type","application/json")
                    .header("Authorization",getAPIkey_authHeader(key_num))
                    .body(jsonString)
                    .asJson();
        }else {
            response = Unirest.post(grafanaUrl+"/api/dashboards/db")
                    .basicAuth(username,password)
                    .header("Accept", "application/json")
                    .header("Content-Type","application/json; charset=UTF-8")
                    .body(jsonString)
                    .asJson();
        }
        return response.getBody().toString();
    }

    /**
     * 导入仪表板
     * @param jsonString
     * @param key_num
     * @return
     * @throws Exception
     */
    public static String importBashboard(JSONObject jsonString,Integer key_num) throws Exception{
        HttpResponse<JsonNode> response;
        if(isAPIkey){
            response = Unirest.post(grafanaUrl+"api/dashboards/import")
                    .header("Accept", "application/json")
                    .header("Content-Type","application/json")
                    .header("Authorization",getAPIkey_authHeader(key_num))
                    .body(jsonString)
                    .asJson();
        }else {
            response = Unirest.post(grafanaUrl+"api/dashboards/import")
                    .basicAuth(username,password)
                    .header("Accept", "application/json")
                    .header("Content-Type","application/json; charset=UTF-8")
                    .body(jsonString)
                    .asJson();
        }
        return response.getBody().toString();
    }

    /**
     * @Author: shanzhu
     * @Date: 2020/10/23 14:54
     * @Description: 根据uid获取dashboard
     * 测试uid:HYS-BSpGz
     **/
    public static String getDashboardByUid(String uid,Integer key_num) throws Exception{
        HttpResponse<JsonNode> response;
        if(isAPIkey){
            response = Unirest.get(grafanaUrl+"/api/dashboards/uid/"+uid)
                    .header("Accept", "application/json")
                    .header("Content-Type","application/json")
                    .header("Authorization",getAPIkey_authHeader(key_num))
                    .asJson();
        } else {
            response = Unirest.get(grafanaUrl+"/api/dashboards/uid/"+uid)
                    .basicAuth(username,password)
                    .header("Accept", "application/json")
                    .header("Content-Type","application/json")
                    .asJson();
        }
        return  response.getBody().toString();
    }

    /**
     * @Author: shanzhu
     * @Date: 2020/10/27 17:18
     * @Description: 搜索Folder/Dashboard
     * Query parameters:
     *     query – Search Query
     *     tag – List of tags to search for
     *     type – Type to search for, dash-folder or dash-db
     *     dashboardIds – List of dashboard id’s to search for
     *     folderIds – List of folder id’s to search in for dashboards
     *     starred – Flag indicating if only starred Dashboards should be returned
     *     limit – Limit the number of returned results (max 5000)
     *     page – Use this parameter to access hits beyond limit. Numbering starts at 1. limit param acts as page size. Only available in Grafana v6.2+.
     * @param paramUrl 查询条件 以?开始 ps:/api/search?folderIds=0&query=&starred=false or /api/search?query=seninel-influxdb-shan-grafana
     * @param key_num 权限区分
     * @Return 返回查询结果 json格式
     **/
    public static String searchDashboard(String paramUrl,Integer key_num) throws Exception{
        HttpResponse<JsonNode> response;
        if(isAPIkey){
            response = Unirest.get(grafanaUrl+"/api/search/"+paramUrl)
                    .header("Accept", "application/json")
                    .header("Content-Type","application/json")
                    .header("Authorization",getAPIkey_authHeader(key_num))
                    .asJson();
        } else {
            response = Unirest.get(grafanaUrl+"/api/search/"+paramUrl)
                    .basicAuth(username,password)
                    .header("Accept", "application/json")
                    .header("Content-Type","application/json")
                    .asJson();
        }
        return  response.getBody().toString();
    }
    
    /**
     * @Author: shanzhu
     * @Date: 2020/10/26 14:16
     * @Description: 根据权限返回指定的APIKey值
     * @param key_num 判断是什么权限:Admin 1 Viewer 2 Editor 3
     *                默认为查看权限(Viewer 2)
     * @return String APIkey
     **/
    private static String getAPIkey_authHeader(Integer key_num){
        String Bearer = "Bearer ";
        if(key_num.intValue() == 1){
            return Bearer + APIKey_Admin;
        }else if(key_num.intValue() == 2){
            return Bearer + APIKey_Viewer;
        }else if(key_num.intValue() == 3){
            return Bearer + APIKey_Editor;
        } else {
            // 默认查看权限
            return Bearer + APIKey_Viewer;
        }
    }

}

4 编辑sentinel前端请求接口 app.js中添加接口

  this.querySentinelUrlByApp = function(e) {
        return l({
            url: "/metric/querySentinelUrlByApp.json",
            params: e,
            method: "GET"
        })
    }

5 前端实现
$sce’ 需要存在

app.controller('MetricCtl', ['$scope', '$stateParams', 'MetricService', '$interval', '$timeout',**'$sce'**,

接口请求后台获取url,动态改变地址

function () {
      var params = {
        app: $scope.app
      };
      MetricService.querySentinelUrlByApp(params).success(function (data) {
      
        $scope.grafanaUrl = $sce.trustAsResourceUrl(data.data);
      
      })
    }

html中grafanaUrl则改变地址

<iframe class="report-iframe table-bordered"
                    target="_blank"
                    width="1600px"
                    height="1000px"
                    seamless
                    frameBorder="0"
                    allowfullscreen
                    ng-src="{{grafanaUrl}}"></iframe>

6 后台实现

/**
     * @param app 应用名
     * @return Result
     * @Author shanzhu
     * @Description 根据sentinel应用名查询在grafana中的信息
     **/
    @ResponseBody
    @RequestMapping("/querySentinelUrlByApp.json")
    public Result<?> querySentinelUrlByApp(String app){
        if (StringUtil.isEmpty(app)) {
            return Result.ofFail(-1, "app can't be null or empty");
        }
        String result = "";
        try {
            ArrayList<Map<String,String>> grafana  =
                    JSON.parseObject(GrafanaUtil.searchDashboard("?query="+app,null), new TypeReference<ArrayList<Map<String,String>>>(){});
            //  未查到grafanaDashboard
            if (grafana.size() == 0){
                // 创建grafana 仪表盘
                // file/grafanaDashboard.json 设计好的json数据
                ClassPathResource resource = new ClassPathResource("file/grafanaDashboard.json");
                InputStream stream = resource.getInputStream();
                byte[] byteArr = new byte[stream.available()];
                stream.read(byteArr);
                String str = new String(byteArr);
              
                String  dashboard = GrafanaUtil.insertOrUpdateBashboard(str,1);
                JSONObject jsonObject = JSON.parseObject(dashboard);
                result = jsonObject.get("url").toString();
            } else {
                result = grafana.get(0).get("url");
            }

            result = GrafanaUtil.getGrafanaUrl()+result;
        }catch (Exception e){
            logger.error("querySentinelUrlByApp:"+e.getMessage());
            return Result.ofFail(-1, e.getMessage());
        }
        return Result.ofSuccess(result);
    }

grafanaDashboard.json

{
  "dashboard": {
    "id": null,
    "uid": null,
    "title": "Production Overview",
    "tags": [ "templated" ],
    "timezone": "browser",
    "schemaVersion": 16,
    "version": 0,
    "refresh": "25s"
  },
  "folderId": 0,
  "overwrite": false
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值