kibana的dashboard内嵌到web中的定制化问题

kibana内嵌到web中的定制化问题

2个通用的需求:
1.去掉AddFilter按钮
2.自定义传参过滤或者搜索

1.去掉AddFilter。
调研下来发现因为跨域访问的问题, 导致外层无法访问iframe内部的contentwindow等元素, 也就失去了控制子元素显示或隐藏的机会。
最终通过修改kibana前端源码完成, 具体到XXX:\Bitnami\elk-6.2.3-0\kibana\optimize\bundles\commons.style.css, 找到".filter-bar", 添加display:none即可。

2.自定义传参。
这个需要仔细分析kibana的dashboard的share的两者方式的不同处。
“share saved dashboard”方式的link类似:
http://localhost:81/elk/app/kibana#/dashboard/de8df1e0-58a6-11e8-aa0c-7db6a9fbe317?_embed=true&g=()
上面的link是我们建立的dashboard并没有做任何过滤或者搜索查询。


而“share snapshot”方式的link类似:
http://localhost:81/elk/app/kibana#/dashboard/de8df1e0-58a6-11e8-aa0c-7db6a9fbe317?embed=true&_g=()&_a=(description:'',filters:!(),fullScreenMode:!f,options:(darkTheme:!f,hidePanelTitles:!f,useMargins:!t),panels:!((gridData:(h:3,i:'1',w:6,x:0,y:0),id:'5c4fa8e0-58a6-11e8-aa0c-7db6a9fbe317',panelIndex:'1',type:visualization,version:'6.2.3'),(gridData:(h:3,i:'2',w:6,x:6,y:0),id:'766a8d30-58a6-11e8-aa0c-7db6a9fbe317',panelIndex:'2',type:visualization,version:'6.2.3'),(gridData:(h:3,i:'3',w:6,x:0,y:3),id:d6c12e00-58a6-11e8-aa0c-7db6a9fbe317,panelIndex:'3',type:visualization,version:'6.2.3')),query:(language:lucene,query:''),timeRestore:!f,title:CT,viewMode:view)

snapshot和saved的区别在于,
snapshot是个快照,snapshot不会随着服务器的配置而更新, 因此snapshot把当前dashboard的配置都加到url的query参数里了。
saved 只有dashboard的访问url, 具体配置参数不传递, 根据kibana服务器的即时配置来返回结果呈现给用户。

通过snapshot和saved的对比, 我们可以推测kibana的过滤和搜索传递的参数方式。 下面我仔细介绍下url中的几个参数的含义。
“de8df1e0-58a6-11e8-aa0c-7db6a9fbe317”
是dashboard的_id, 这个id是share后生成的url包含的。如果程序中需要动态变化这个值, 比如根据dashboard的名字来构建查询url的话, 可以先用restful api根据title来查询id。
GET /.kibana/_search
{
 "query": {
   "match": {
     "type": "dashboard"
   }
   }
 }
}

"hits": [
     {
       "_index": ".kibana",
       "_type": "doc",
       "_id": "dashboard:de8df1e0-58a6-11e8-aa0c-7db6a9fbe317",
       "_score": 1.9924302,
       "_source": {
         "type": "dashboard",
         "updated_at": "2018-05-16T01:17:49.488Z",
         "dashboard": {
           "title": "CT",
           "hits": 0,
           "description": "",
           "panelsJSON": """[{"panelIndex":"1","gridData":{"x":0,"y":0,"w":6,"h":3,"i":"1"},"version":"6.2.3","type":"visualization","id":"5c4fa8e0-58a6-11e8-aa0c-7db6a9fbe317"},{"panelIndex":"2","gridData":{"x":6,"y":0,"w":6,"h":3,"i":"2"},"version":"6.2.3","type":"visualization","id":"766a8d30-58a6-11e8-aa0c-7db6a9fbe317"},{"panelIndex":"3","gridData":{"x":0,"y":3,"w":6,"h":3,"i":"3"},"version":"6.2.3","type":"visualization","id":"d6c12e00-58a6-11e8-aa0c-7db6a9fbe317"}]""",
           "optionsJSON": """{"darkTheme":false,"useMargins":true,"hidePanelTitles":false}""",
           "version": 1,
           "timeRestore": false,
           "kibanaSavedObjectMeta": {
             "searchSourceJSON": """{"query":{"query":"CT","language":"lucene"},"filter":[],"highlightAll":true,"version":true}"""
           }
         }
       }

embed=true 代表内嵌到web中, 即只有dashboard,没有kibana的左边导航栏等。

_a 传递了具体的配置的参数, 内部有filter和query等。
filters:!()内就是具体过滤的配置, 效果就是AddFilter按钮上变成了具体的过滤值。 比如我们添加systemid为123456789012的过滤,拼成的过滤url字符串为
filters:!(
('$state':(store:appState),meta:(alias:!n,disabled:!f,index:d44e6850-573d-11e8-b53a-edf9125f1874,key:systemID.keyword,negate:!f,params:(query:'123456789012',type:phrase),type:phrase,value:'123456789012'),query:(match:(systemID.keyword:(query:'123456789012',type:phrase))))
)
上面简化掉不需要的参数,最后为:
filters:!((meta:(),query:(match:(systemID.keyword:(query:'123456789012',type:phrase)))))
最终形成的url为:
http://localhost:81/elk/app/kibana#/dashboard/de8df1e0-58a6-11e8-aa0c-7db6a9fbe317?_g=()&_a=(filters:!((meta:(),query:(match:(systemID.keyword:(query:'123456789012',type:phrase))))))

解释下最终的url字符串,
1._g()之前是原始的dashboard的url, 后面_a是我们添加的过滤url。
2._a内每次大括号类似json对象的花括号,因此层次不能省略;
3.query:(match:(systemID.keyword:(query:'123456789012',type:phrase))) 是filter里最关键的字符串,  类似json

 "query": {
   "match": {
     "systemID.keyword": {
       "type": "phrase",
       "query": "123456789012"
     }
   }
 }

类似es的queryDSL语句。我们修改sytemId.keyword 和12345679012为我们真正动态改变的字段和值即可。

filter是查询完成后再过滤,query是直接查询。


通过query实现特定数据的方法如下:
http://localhost:81/elk/app/kibana#/dashboard/de8df1e0-58a6-11e8-aa0c-7db6a9fbe317?embed=true&_g=()&_a=(query:(language:lucene,query:'systemID.keyword:123456789012'))
同样的是把query放到_a()里。
query的语句为:
query:(language:lucene,query:'systemID.keyword:123456789012')
类似
       "query": {
              "language": "lucene",
              "query":"systemID.keyword:123456789012"
       }

同样的我们动态修改"systemID.keyword:123456789012"为我们具体的field和value即可


接下来解释一下_g=()参数
先看个url的例子:
http://localhost:81/elk/app/kibana#/dashboard/de8df1e0-58a6-11e8-aa0c-7db6a9fbe317?&_g=(refreshInterval:('$$hashKey':'object:328',display:'15 minutes',pause:!f,section:2,value:900000),time:(from:now-1h,interval:'1m',mode:quick,timezone:Asia/Shanghai,to:now))

上面的url其实是我用url解码后得到的原始字符串。
_g也有2个关键的字段, refreshInterval和time。
refreshInterval控制是否自动刷新以及刷新频率
time设置dashboard的时间范围from和to,时间间隔interval, 以及时区设置timezone,保证时间轴的时间显示正确。

最终效果:
<p>
kibana-demo works!
</p>
<div id="content" >
<iframe id="dashboard" src="http://localhost:81/elk/app/kibana#/dashboard/de8df1e0-58a6-11e8-aa0c-7db6a9fbe317?embed=true&_g=()&_a=(query:(language:lucene,query:'systemID.keyword:123456789012'))"
sandbox="allow-same-origin allow-scripts">
</iframe>
</div>
kibana的dashboard内嵌到web中的定制化问题