專案

一般

配置概況

動作

工作單 #60

已結束

工作單 #62: 報表重整

既有報表整理與遷移

是由 marlboro chu 於 約 1 年 前加入. 於 約 1 年 前更新.

狀態:
Close
優先權:
LOW
被分派者:
-
開始日期:
2025-01-13
完成日期:
2025-02-28
完成百分比:

0%


概述

既有報表整理,並遷移至新建 grafana 系統


檔案

GrafanaETL.java (16.1 KB) GrafanaETL.java marlboro chu, 2025-02-13 02:23

是由 marlboro chu 於 約 1 年 前更新

  • 父議題 設定為 #62

是由 marlboro chu 於 約 1 年 前更新

  • 備份報表資訊
  1. 備份 folder
public static void backupAllFolders() throws Exception {

 List<Map<String, Object>> folders = getAllFoldersFromGrafanaA();
 ObjectMapper objectMapper = new ObjectMapper();
 String json = objectMapper.writeValueAsString(folders);
 writeToFile(BACKUP_FOLDER + "//folders.json", json);

}

public static List getAllFoldersFromGrafanaA() throws Exception {

	String url = GRAFANA_A_URL + "/api/folders";
	HttpHeaders headers = new HttpHeaders();
	headers.set("Authorization", API_KEY_A);
	headers.setContentType(MediaType.APPLICATION_JSON);
	HttpEntity<String> entity = new HttpEntity<>(headers);

	ResponseEntity<List> response = restTemplate.exchange(url, HttpMethod.GET, entity, List.class);
	if (response.getStatusCode() == HttpStatus.OK) {
		return (response.getBody());
		// writeToFile(BACKUP_FOLDER + "//folders.json", new
		// JSONArray(response.getBody()).toString());
	}
	return Collections.emptyList();
}

  1. 備份 dashboard 及 library
public static void backupAllDashboardAndLibs() {
	try {

		RestTemplate restTemplate = new RestTemplate();
		HttpHeaders headers = new HttpHeaders();
		headers.set("Authorization", API_KEY_A);
		headers.setContentType(MediaType.APPLICATION_JSON);

		String searchUrl = GRAFANA_A_URL + "/api/search?type=dash-db";
		HttpEntity<String> request = new HttpEntity<>(headers);
		ResponseEntity<String> searchResponse = restTemplate.exchange(searchUrl, HttpMethod.GET, request,
				String.class);

		ObjectMapper objectMapper = new ObjectMapper();
		JsonNode searchResult = objectMapper.readTree(searchResponse.getBody());

		for (JsonNode dashboard : searchResult) {

			String dashboardUid = dashboard.get("uid").asText();

			String dashboardTitle = dashboard.get("title").asText();

			String dashboardUrl = GRAFANA_A_URL + "/api/dashboards/uid/" + dashboardUid;
			ResponseEntity<String> dashboardResponse = restTemplate.exchange(dashboardUrl, HttpMethod.GET, request,
					String.class);
			JsonNode dashboardJson = objectMapper.readTree(dashboardResponse.getBody());

			writeToFile(BACKUP_FOLDER + "dashboard\\" + dashboardTitle + ".json", dashboardJson);

			JsonNode panels = dashboardJson.path("dashboard").path("panels");
			for (JsonNode panel : panels) {

				if (panel.has("libraryPanel")) {

					String libraryPanelUid = panel.get("libraryPanel").get("uid").asText();
					System.out.println("Found library panel with UID: " + libraryPanelUid);

					String libraryElementsUrl = GRAFANA_A_URL + "/api/library-elements/" + libraryPanelUid;

					HttpEntity<String> libraryRequest = new HttpEntity<>(headers);
					ResponseEntity<String> libraryResponse = restTemplate.exchange(libraryElementsUrl,
							HttpMethod.GET, libraryRequest, String.class);

					String resBody = libraryResponse.getBody();

					JsonNode libraryElementsJson = objectMapper.readTree(resBody);

					writeToFile(BACKUP_FOLDER + "library\\"
							+ libraryElementsJson.path("result").get("name").asText() + ".json",
							libraryElementsJson);

				}
			}

		}

	} catch (Exception e) {
		e.printStackTrace();
	}
}
  1. 備份 Datasource
private static void backupDataSource() throws Exception {

	String urlA = GRAFANA_A_URL + "/api/datasources";
	HttpHeaders headers = new HttpHeaders();
	headers.set("Authorization", API_KEY_A);
	headers.setContentType(MediaType.APPLICATION_JSON);
	HttpEntity<String> entity = new HttpEntity<>(headers);

	ResponseEntity<String> response = restTemplate.exchange(urlA, HttpMethod.GET, entity, String.class);
	if (response.getStatusCode() == HttpStatus.OK) {
		System.out.println(response.getBody());
		writeToFile(BACKUP_FOLDER + "//datasource.json", new JSONArray(response.getBody()).toString());
	}

}

是由 marlboro chu 於 約 1 年 前更新

  • 匯入報表依序為
  1. 匯入 folder
  2. 匯入 dataSource
  3. 匯入 Library
    因 Grafana 目前尚未提供相對的 API ,故匯入會直接 insert 至資料庫
  4. 匯入 Dashboard

是由 marlboro chu 於 約 1 年 前更新

匯入相關資訊後,若因 DataSource 未正常運作,開啟報表時會出現以下錯誤訊息或類似的錯誤訊息,須先解決使 DataSource 可以正常運作。

  • cannot create property '$$config' on string
  • cannot create property 'name' on string ''

是由 marlboro chu 於 約 1 年 前更新

  • 狀態New 變更為 Close
動作

匯出至 Atom PDF