Skip to content

Commit 027d545

Browse files
committed
add kibana dashboard transfer
1 parent c06f3e3 commit 027d545

File tree

15 files changed

+290
-0
lines changed

15 files changed

+290
-0
lines changed

.vitepress/siderbars/getOscompatibleDemo.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ function getSidebar() {
1919
{
2020
text: 'ES兼容',
2121
items: [
22+
{ text: 'Kibana Dashboard迁移', link: '/oscompatibledemo/kibana_dashboard_transfer' },
2223
{ text: '最佳实践', link: '/oscompatibledemo/es_best_practice' },
2324
],
2425
},
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# 概要
2+
3+
本文介绍在数据迁移到SLS后,如何将原来Kibana中的dashboard迁移到SLS对接的Kibana中
4+
5+
# 操作思路
6+
7+
![](/img/oscompatibledemo/dashboard10.png)
8+
9+
10+
* 从旧的Kibana导出dashboard的export.ndjson文件
11+
* 新的Kibana中准备好index pattern
12+
* 把export.ndjson中的旧的index pattern id替换成新的Kibana index patter Id
13+
* 完成替换后,把export.ndjson导入到新的kibana
14+
15+
16+
# Dashboard迁移演示
17+
18+
## 在ES中准备数据和Dashboard, 并导出Dashboard配置
19+
向es1 写入数据
20+
21+
```
22+
POST people/_bulk
23+
{ "index": {} }
24+
{ "name": "Alice", "age": 30 }
25+
{ "index": {} }
26+
{ "name": "Bob", "age": 25 }
27+
{ "index": {} }
28+
{ "name": "Charlie", "age": 35 }
29+
```
30+
31+
在kibana1上基于people创建两个dashboard
32+
33+
![](/img/oscompatibledemo/dashboard0.png)
34+
35+
其中一个dashboard示例
36+
37+
![](/img/oscompatibledemo/dashboard1.png)
38+
39+
保存好Dashboard后,进入Kibana `Stack Management->Saved objects` 来导出
40+
41+
![](/img/oscompatibledemo/dashboard2.png)
42+
43+
勾选想要导出的dashboard,注意 不要勾选 `Include related objects`
44+
45+
导出后dashboard的内容存在 `export.ndjson`
46+
47+
48+
## 在SLS对接的Kibana中复用Dashboard
49+
50+
在sls中准备好一份相同的数据,确保字段一致
51+
52+
![](/img/oscompatibledemo/dashboard3.png)
53+
54+
新部署一套Kibana并对接SLS,参考操作链接 -> [SLS对接Kibana](https://help.aliyun.com/zh/sls/user-guide/use-kibana-to-access-the-elasticsearch-compatible-api-of-log-service)
55+
56+
注意,这里用的es/kbiana版本和之前的es/kibana版本保持一致
57+
58+
使用 `Docker Compose``Helm Chart` 方案对接SLS后,会自动在Kibana中创建好相应的Index Pattern
59+
60+
![](/img/oscompatibledemo/dashboard4.png)
61+
62+
63+
### 执行迁移
64+
65+
* 查看老的es中的Index Pattern的ID
66+
67+
准备好 kibana_config_1.json,然后使用 [ptn_list.py 点击下载](ptn_list.py) 来list Index Pattern
68+
```
69+
{
70+
"url" : "http://xxx:5601",
71+
"user" : "elastic",
72+
"password" : "",
73+
"space" : "default"
74+
}
75+
```
76+
执行
77+
```
78+
➜ /tmp python ptn_list.py kibana_config_1.json
79+
f06fc2b0-b82d-11ef-88c6-15adf26175c7 people
80+
```
81+
82+
f06fc2b0-b82d-11ef-88c6-15adf26175c7 这个就是旧的people这个index pattern的id
83+
84+
在Kibana导出的dashboard配置文件 export.ndjson中可以看到对这个Index Pattern Id的引用
85+
![](/img/oscompatibledemo/dashboard5.png)
86+
87+
88+
* 在SLS对接的Kibana中找到新的Index Pattern的Id
89+
90+
同样使用 [ptn_list.py 点击下载](ptn_list.py) 来list 新的Kibana中Index Pattern的ID
91+
92+
```
93+
# 准备好kibana_config_2.json
94+
95+
➜ /tmp python ptn_list.py kibana_config_2.json
96+
ef710470-b83a-11ef-bb2b-ad198b7b763d etl.people
97+
```
98+
99+
100+
通过sed命令批量修改 `export.ndjson` 中的ID替换
101+
102+
```
103+
sed -i 's/f06fc2b0-b82d-11ef-88c6-15adf26175c7/ef710470-b83a-11ef-bb2b-ad198b7b763d/' export.ndjson
104+
```
105+
106+
* 进入新的Kibana `Stack Management->Saved objects` 来将export.ndjson导入
107+
108+
![](/img/oscompatibledemo/dashboard6.png)
109+
110+
点击Import
111+
112+
![](/img/oscompatibledemo/dashboard7.png)
113+
114+
出现下面界面表示导入成功,如有报错的情况需要看报错信息,再看如何处理
115+
116+
![](/img/oscompatibledemo/dashboard8.png)
117+
118+
打开新的dashboard是否符合预期
119+
![](/img/oscompatibledemo/dashboard9.png)

src/oscompatibledemo/ptn_delete.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import sys
2+
import json
3+
import requests
4+
from requests.auth import HTTPBasicAuth
5+
from datetime import datetime
6+
7+
kibanaEndpoint= ''
8+
kibanaUser = ''
9+
kibanaPassword = ''
10+
kibanaSpace = ''
11+
12+
def print_with_time(message):
13+
current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
14+
print(f"[{current_time}] {message}")
15+
16+
def deleteKibanaIndexPattern(space, indexPatternId):
17+
uri = f"{kibanaEndpoint}/api/saved_objects/index-pattern/{indexPatternId}"
18+
19+
if space != "default":
20+
uri = f"{kibanaEndpoint}/s/{space}/api/saved_objects/index-pattern/{indexPatternId}"
21+
headers = {
22+
"kbn-xsrf": "true",
23+
}
24+
ret = requests.delete(uri,
25+
auth=kibanaAuth,
26+
headers=headers)
27+
if ret.status_code != 200:
28+
print_with_time(f"Failed to delete index patterns. " +
29+
f"Status code: {ret.status_code}, body: {ret.content}")
30+
else:
31+
print_with_time(f"delete indexPattern {indexPatternId} @ {space} success")
32+
33+
def print_help():
34+
print('''
35+
Usage: python %s kibana_config.json index_pattern_ids.txt
36+
37+
kibana_config.json exmplae:
38+
{
39+
"url" : "http://192.168.1.1:5601",
40+
"user" : "elastic",
41+
"password" : "thePassword",
42+
"space" : "default"
43+
}
44+
45+
index_pattern_ids.txt example content:
46+
aa77bf10-9c17-11ef-8665-41f4399ec183 etl-dev.mytest
47+
5a264770-a0a9-11ef-8279-7f5e6cac2855 etl-spe.es_test3
48+
d07fc4c0-a0d4-11ef-8279-7f5e6cac2855 etl-spe.es_test5
49+
50+
you can use kibana_index_pattern_list.py to get index_pattern_ids.txt file
51+
''' % sys.argv[0])
52+
indexPatternIds = []
53+
try:
54+
configFile = sys.argv[1]
55+
indexPatternIdFile = sys.argv[2]
56+
kbnConfig = json.loads(open(configFile, 'r').read())
57+
58+
kibanaEndpoint=kbnConfig['url']
59+
kibanaUser = kbnConfig['user']
60+
kibanaPassword = kbnConfig['password']
61+
kibanaSpace = kbnConfig['space']
62+
63+
for i in open(indexPatternIdFile,'r').read().split('\n'):
64+
if i.strip()!="":
65+
id = i.split('\t')[0].split(' ')[0]
66+
indexPatternIds.append(id)
67+
except Exception as ex:
68+
print_help()
69+
print(str(ex))
70+
sys.exit(1)
71+
72+
73+
kibanaAuth = HTTPBasicAuth(kibanaUser, kibanaPassword)
74+
75+
for indexPatternId in indexPatternIds:
76+
#print_with_time("start to delete index pattern %s" % indexPatternId)
77+
deleteKibanaIndexPattern(kibanaSpace, indexPatternId)

src/oscompatibledemo/ptn_list.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import sys
2+
import json
3+
import requests
4+
from requests.auth import HTTPBasicAuth
5+
from datetime import datetime
6+
7+
kibanaEndpoint= ''
8+
kibanaUser = ''
9+
kibanaPassword = ''
10+
kibanaSpace = ''
11+
12+
def print_with_time(message):
13+
current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
14+
print(f"[{current_time}] {message}")
15+
16+
def getKibanaExsitIndexPatterns(space):
17+
page = 1
18+
per_page = 100 # 每页获取100条记录
19+
existing_patterns = {}
20+
headers = {
21+
"kbn-xsrf": "true",
22+
"Content-Type": "application/json"
23+
}
24+
while True:
25+
uri = f"{kibanaEndpoint}/api/saved_objects/_find"
26+
if space != "default":
27+
uri = f"{kibanaEndpoint}/s/{space}/api/saved_objects/_find"
28+
response = requests.get(
29+
uri,
30+
auth=kibanaAuth,
31+
headers=headers,
32+
params={
33+
"type": "index-pattern",
34+
"page": page,
35+
"per_page": per_page
36+
}
37+
)
38+
39+
if response.status_code == 200:
40+
response_data = response.json()
41+
saved_objects = response_data.get("saved_objects", [])
42+
43+
if not saved_objects:
44+
break # 如果当前页没有获取到新的记录,停止翻页
45+
46+
for pattern in saved_objects:
47+
existing_patterns[pattern["attributes"]["title"]] = pattern["id"]
48+
# existing_patterns.extend([pattern["attributes"]["title"]
49+
# for pattern in saved_objects])
50+
51+
# 检查是否还有更多的记录
52+
total = response_data.get("total", 0)
53+
if len(existing_patterns) >= total:
54+
break
55+
56+
page += 1 # 下一页
57+
else:
58+
print_with_time(f"Failed to get existing index patterns. Status code: {response.status_code}")
59+
return []
60+
61+
return existing_patterns
62+
63+
def print_help():
64+
print('''
65+
Usage: python %s kibana_config.json
66+
67+
kibana_config.json exmplae:
68+
{
69+
"url" : "http://192.168.1.1:5601",
70+
"user" : "elastic",
71+
"password" : "thePassword",
72+
"space" : "default"
73+
}
74+
75+
''' % sys.argv[0])
76+
try:
77+
configFile = sys.argv[1]
78+
kbnConfig = json.loads(open(configFile, 'r').read())
79+
80+
kibanaEndpoint=kbnConfig['url']
81+
kibanaUser = kbnConfig['user']
82+
kibanaPassword = kbnConfig['password']
83+
kibanaSpace = kbnConfig['space']
84+
except Exception as ex:
85+
print_help()
86+
print(str(ex))
87+
sys.exit(1)
88+
89+
kibanaAuth = HTTPBasicAuth(kibanaUser, kibanaPassword)
90+
existsPatterns = getKibanaExsitIndexPatterns(kibanaSpace)
91+
92+
for name, id in existsPatterns.items():
93+
print("%s\t%s" %(id, name))
335 KB
Loading
591 KB
Loading
Loading
748 KB
Loading
1.33 MB
Loading
658 KB
Loading
916 KB
Loading
628 KB
Loading
765 KB
Loading
718 KB
Loading
503 KB
Loading

0 commit comments

Comments
 (0)