概要
Kibanaに対してRubyからVisualizeやDashboardを作ったりしたかったので書いた
コード
class KibanaClient
def self.call method, path, data
endpoint = "http://localhost:5602#{path}"
authorization = 'Basic ' + Base64.encode64("elastic:changeme").chomp
headers = {
authorization: authorization,
"kbn-xsrf": "kibana",
content_type: :json,
accept: :json
}
response = nil
begin
response = RestClient.send(method.to_s, endpoint, data.to_json, headers)
rescue => e
puts e.response
response = e.response
end
response
end
end
Tips
- kbn-xsrfが無いと弾かれる
- Basic認証はKibanaのユーザで行う
- リクエストに必要なJSONはKibanaのSaved ObjectsからInspectすると見れる
- Saved ObjectsのExportで更に詳しく見れる
サンプル
class KibanaClient
def self.call method, path, data
endpoint = "http://localhost:5602#{path}"
authorization = 'Basic ' + Base64.encode64("elastic:changeme").chomp
headers = {
authorization: authorization,
"kbn-xsrf": "kibana",
content_type: :json,
accept: :json
}
response = nil
begin
response = RestClient.send(method.to_s, endpoint, data.to_json, headers)
rescue => e
puts e.response
response = e.response
end
response
end
def self.gen_metric id, index_pattern, title, references = nil, query = nil
references = [
{
"id": index_pattern,
"name": "kibanaSavedObjectMeta.searchSourceJSON.index",
"type": "index-pattern"
}
] if references.blank?
query = {
"query": {
"query": "",
"language": "kuery"
},
"filter": [],
"indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.index"
} if query.blank?
state = {
"title": title,
"type": "metric",
"params": {
"metric": {
"percentageMode": false,
"useRanges": false,
"colorSchema": "Green to Red",
"metricColorMode": "None",
"colorsRange": [
{
"type": "range",
"from": 0,
"to": 10000
}
],
"labels": {
"show": false
},
"invertColors": false,
"style": {
"bgFill": "#000",
"bgColor": false,
"labelColor": false,
"subText": "",
"fontSize": 60
}
},
"dimensions": {
"metrics": [
{
"type": "vis_dimension",
"accessor": 0,
"format": {
"id": "number",
"params": {}
}
}
]
},
"addTooltip": true,
"addLegend": false,
"type": "metric"
},
"aggs": [
{
"id": "1",
"enabled": true,
"type": "count",
"schema": "metric",
"params": {}
}
]
}
json = {
"attributes": {
"description": "",
"kibanaSavedObjectMeta": {
"searchSourceJSON": query.to_json
},
"title": title,
"uiStateJSON": "{}",
"visState": state.to_json
},
"references": references
}
api_path = "/api/saved_objects/visualization/#{id}?overwrite=true"
response = KibanaClient.call(:post, api_path, json)
response
end
def self.gen_pie id, index_pattern, title, field, references = nil, query = nil
references = [
{
"id": index_pattern,
"name": "kibanaSavedObjectMeta.searchSourceJSON.index",
"type": "index-pattern"
}
] if references.blank?
query = {
"query": {
"query": "",
"language": "kuery"
},
"filter": [],
"indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.index"
} if query.blank?
state = {
"title": title,
"type": "pie",
"params": {
"type": "pie",
"addTooltip": true,
"addLegend": true,
"legendPosition": "top",
"isDonut": true,
"labels": {
"show": false,
"values": true,
"last_level": true,
"truncate": 100
},
"dimensions": {
"metric": {
"accessor": 1,
"format": {
"id": "number"
},
"params": {},
"aggType": "count"
},
"buckets": [
{
"accessor": 0,
"format": {
"id": "terms",
"params": {
"id": "string",
"otherBucketLabel": "Other",
"missingBucketLabel": "Missing"
}
},
"params": {},
"aggType": "terms"
}
]
}
},
"aggs": [
{
"id": "1",
"enabled": true,
"type": "count",
"schema": "metric",
"params": {}
},
{
"id": "2",
"enabled": true,
"type": "terms",
"schema": "segment",
"params": {
"field": field,
"orderBy": "1",
"order": "desc",
"size": 5,
"otherBucket": true,
"otherBucketLabel": "Other",
"missingBucket": false,
"missingBucketLabel": "Missing"
}
}
]
}
json = {
"attributes": {
"description": "",
"kibanaSavedObjectMeta": {
"searchSourceJSON": query.to_json
},
"title": title,
"uiStateJSON": "{}",
"visState": state.to_json
},
"references": references
}
api_path = "/api/saved_objects/visualization/#{id}?overwrite=true"
response = KibanaClient.call(:post, api_path, json)
response
end
def self.gen_graph id, index_pattern, title, type, params, aggs, references = nil, query = nil
references = [
{
"id": index_pattern,
"name": "kibanaSavedObjectMeta.searchSourceJSON.index",
"type": "index-pattern"
}
] if references.blank?
query = {
"query": {
"query": "",
"language": "kuery"
},
"filter": [],
"indexRefName": "kibanaSavedObjectMeta.searchSourceJSON.index"
} if query.blank?
state = {
"title": title,
"type": type,
"params": params,
"aggs": aggs
}
json = {
"attributes": {
"description": "",
"kibanaSavedObjectMeta": {
"searchSourceJSON": query.to_json
},
"title": title,
"uiStateJSON": "{}",
"visState": state.to_json
},
"references": references
}
api_path = "/api/saved_objects/visualization/#{id}?overwrite=true"
response = KibanaClient.call(:post, api_path, json)
response
end
def self.gen_dashboard id, title, panels, references, options = {}, query = nil
query = {
"query": {
"query": "",
"language": "kuery"
},
"filter": []
} if query.blank?
puts id
puts title
puts panels
puts references
puts options
puts query
json = {
"attributes": {
"description": "",
"hits": 0,
"kibanaSavedObjectMeta": {
"searchSourceJSON": query.to_json
},
"optionsJSON": options.to_json,
"panelsJSON": panels.to_json,
"timeRestore": false,
"title": title
},
"references": references
}
puts json
api_path = "/api/saved_objects/dashboard/#{id}?overwrite=true"
response = KibanaClient.call(:post, api_path, json)
response
end
end
Generatorから
response = KibanaClient.gen_graph("test_graph", "index_name", "タイトル", "area", params, aggs, references, query)
各変数はKibanaでグラフを作って、Inspectからテンプレ化すると楽