diff --git a/models/admin_info_response.go b/models/admin_info_response.go index c221669e5..f116e9479 100644 --- a/models/admin_info_response.go +++ b/models/admin_info_response.go @@ -42,6 +42,9 @@ type AdminInfoResponse struct { // objects Objects int64 `json:"objects,omitempty"` + // prometheus not ready + PrometheusNotReady bool `json:"prometheusNotReady,omitempty"` + // servers Servers []*ServerProperties `json:"servers"` diff --git a/portal-ui/src/common/utils.ts b/portal-ui/src/common/utils.ts index df0dce77c..5bee31d34 100644 --- a/portal-ui/src/common/utils.ts +++ b/portal-ui/src/common/utils.ts @@ -472,7 +472,12 @@ export const getTimeFromTimestamp = ( timestamp: string, fullDate: boolean = false ) => { - const dateObject = new Date(parseInt(timestamp) * 1000); + const timestampToInt = parseInt(timestamp); + + if (isNaN(timestampToInt)) { + return ""; + } + const dateObject = new Date(timestampToInt * 1000); if (fullDate) { return `${dateObject.getFullYear()}-${String( diff --git a/portal-ui/src/screens/Console/Dashboard/BasicDashboard/BasicDashboard.tsx b/portal-ui/src/screens/Console/Dashboard/BasicDashboard/BasicDashboard.tsx index 9c240283c..7e4761f24 100644 --- a/portal-ui/src/screens/Console/Dashboard/BasicDashboard/BasicDashboard.tsx +++ b/portal-ui/src/screens/Console/Dashboard/BasicDashboard/BasicDashboard.tsx @@ -133,6 +133,31 @@ const BasicDashboard = ({ classes, usage }: IDashboardProps) => { return (
+ {usage?.prometheusNotReady && ( + + + } + title={"We can't retrieve advanced metrics at this time"} + help={ + + MinIO Dashboard will display basic metrics as we couldn't + connect to Prometheus successfully. +

+ Please try again in a few minutes. If the problem persists, + you can review your configuration and confirm that Prometheus + server is up and running. +
+ } + /> +
+
+ )} General Status @@ -241,45 +266,47 @@ const BasicDashboard = ({ classes, usage }: IDashboardProps) => { - - - } - title={"Monitoring"} - help={ - - The MinIO Dashboard is displaying basic metrics only due to - missing the{" "} - - necessary settings - {" "} - for displaying extended metrics. -
-
- See{" "} - - Collect MinIO Metrics Using Prometheus - {" "} - for a complete tutorial on scraping and visualizing MinIO - metrics with Prometheus. -
- } - /> + {!usage?.prometheusNotReady && ( + + + } + title={"Monitoring"} + help={ + + The MinIO Dashboard is displaying basic metrics only due to + missing the{" "} + + necessary settings + {" "} + for displaying extended metrics. +
+
+ See{" "} + + Collect MinIO Metrics Using Prometheus + {" "} + for a complete tutorial on scraping and visualizing MinIO + metrics with Prometheus. +
+ } + /> +
-
+ )} ); }; diff --git a/portal-ui/src/screens/Console/Dashboard/Prometheus/Widgets/LinearGraphWidget.tsx b/portal-ui/src/screens/Console/Dashboard/Prometheus/Widgets/LinearGraphWidget.tsx index 9f45f1bb7..d11f652a8 100644 --- a/portal-ui/src/screens/Console/Dashboard/Prometheus/Widgets/LinearGraphWidget.tsx +++ b/portal-ui/src/screens/Console/Dashboard/Prometheus/Widgets/LinearGraphWidget.tsx @@ -154,7 +154,12 @@ const LinearGraphWidget = ({ if (key === "name") { continue; } - const val = parseInt(dp[key]); + let val = parseInt(dp[key]); + + if (isNaN(val)) { + val = 0; + } + if (maxVal < val) { maxVal = val; } diff --git a/portal-ui/src/screens/Console/Dashboard/Prometheus/Widgets/SingleRepWidget.tsx b/portal-ui/src/screens/Console/Dashboard/Prometheus/Widgets/SingleRepWidget.tsx index a41af60b8..81e970f9f 100644 --- a/portal-ui/src/screens/Console/Dashboard/Prometheus/Widgets/SingleRepWidget.tsx +++ b/portal-ui/src/screens/Console/Dashboard/Prometheus/Widgets/SingleRepWidget.tsx @@ -111,6 +111,18 @@ const SingleRepWidget = ({ }, [loading, panelItem, timeEnd, timeStart, displayErrorMessage, apiPrefix]); const gradientID = `colorGradient-${title.split(" ").join("-")}`; + let repNumber = ""; + + if (result) { + const resultRep = parseInt(result.innerLabel || "0"); + + if (!isNaN(resultRep)) { + repNumber = representationNumber(resultRep); + } else { + repNumber = "0"; + } + } + return (
{title}
@@ -150,7 +162,7 @@ const SingleRepWidget = ({ fill={"#07193E"} > {result - ? representationNumber(parseInt(result.innerLabel || "0")) + ? repNumber : ""} diff --git a/portal-ui/src/screens/Console/Dashboard/types.ts b/portal-ui/src/screens/Console/Dashboard/types.ts index cc843fc5f..9184ac500 100644 --- a/portal-ui/src/screens/Console/Dashboard/types.ts +++ b/portal-ui/src/screens/Console/Dashboard/types.ts @@ -20,6 +20,7 @@ export interface Usage { usage: number; buckets: number; objects: number; + prometheusNotReady?: boolean; widgets?: any; servers: ServerInfo[]; } diff --git a/portal-ui/src/screens/Console/NotificationEndpoints/CustomForms/EditConfiguration.tsx b/portal-ui/src/screens/Console/NotificationEndpoints/CustomForms/EditConfiguration.tsx index c9d2b9cc3..1fa11d413 100644 --- a/portal-ui/src/screens/Console/NotificationEndpoints/CustomForms/EditConfiguration.tsx +++ b/portal-ui/src/screens/Console/NotificationEndpoints/CustomForms/EditConfiguration.tsx @@ -89,22 +89,27 @@ const EditConfiguration = ({ useState(false); //Effects useEffect(() => { - const configId = get(selectedConfiguration, "configuration_id", false); + if (loadingConfig) { + const configId = get(selectedConfiguration, "configuration_id", false); - if (configId) { - api - .invoke("GET", `/api/v1/configs/${configId}`) - .then((res) => { - const keyVals = get(res, "key_values", []); - setConfigValues(keyVals); - }) - .catch((err: ErrorResponseHandler) => { - setLoadingConfig(false); - setErrorSnackMessage(err); - }); + if (configId) { + api + .invoke("GET", `/api/v1/configs/${configId}`) + .then((res) => { + const keyVals = get(res, "key_values", []); + setConfigValues(keyVals); + setLoadingConfig(false); + }) + .catch((err: ErrorResponseHandler) => { + setLoadingConfig(false); + setErrorSnackMessage(err); + }); + + return; + } + setLoadingConfig(false); } - setLoadingConfig(false); - }, [selectedConfiguration, setErrorSnackMessage]); + }, [loadingConfig, selectedConfiguration, setErrorSnackMessage]); useEffect(() => { if (saving) { @@ -153,6 +158,9 @@ const EditConfiguration = ({ const continueReset = (restart: boolean) => { setResetConfigurationOpen(false); serverNeedsRestart(restart); + if (restart) { + setLoadingConfig(true); + } }; return ( diff --git a/restapi/admin_info.go b/restapi/admin_info.go index 67e00e3a4..c73ff5fad 100644 --- a/restapi/admin_info.go +++ b/restapi/admin_info.go @@ -58,11 +58,12 @@ func registerAdminInfoHandlers(api *operations.ConsoleAPI) { } type UsageInfo struct { - Buckets int64 - Objects int64 - Usage int64 - DisksUsage int64 - Servers []*models.ServerProperties + Buckets int64 + Objects int64 + Usage int64 + DisksUsage int64 + Servers []*models.ServerProperties + EndpointNotReady bool } // GetAdminInfo invokes admin info and returns a parsed `UsageInfo` structure @@ -845,7 +846,12 @@ func getAdminInfoResponse(session *models.Principal, params admin_api.AdminInfoP } func getUsageWidgetsForDeployment(prometheusURL string, mAdmin *madmin.AdminClient) (*models.AdminInfoResponse, *models.Error) { - if prometheusURL == "" { + prometheusNotReady := false + + if prometheusURL != "" && !testPrometheusURL(prometheusURL) { + prometheusNotReady = true + } + if prometheusURL == "" || prometheusNotReady { // create a minioClient interface implementation // defining the client to be used adminClient := AdminClient{Client: mAdmin} @@ -858,10 +864,11 @@ func getUsageWidgetsForDeployment(prometheusURL string, mAdmin *madmin.AdminClie return nil, prepareError(err) } sessionResp := &models.AdminInfoResponse{ - Buckets: usage.Buckets, - Objects: usage.Objects, - Usage: usage.Usage, - Servers: usage.Servers, + Buckets: usage.Buckets, + Objects: usage.Objects, + Usage: usage.Usage, + Servers: usage.Servers, + PrometheusNotReady: prometheusNotReady, } return sessionResp, nil } diff --git a/restapi/embedded_spec.go b/restapi/embedded_spec.go index 412b00599..011bc36f3 100644 --- a/restapi/embedded_spec.go +++ b/restapi/embedded_spec.go @@ -3655,6 +3655,9 @@ func init() { "objects": { "type": "integer" }, + "prometheusNotReady": { + "type": "boolean" + }, "servers": { "type": "array", "items": { @@ -9503,6 +9506,9 @@ func init() { "objects": { "type": "integer" }, + "prometheusNotReady": { + "type": "boolean" + }, "servers": { "type": "array", "items": { diff --git a/swagger-console.yml b/swagger-console.yml index 15eac23bb..3f12135e0 100644 --- a/swagger-console.yml +++ b/swagger-console.yml @@ -3228,6 +3228,8 @@ definitions: type: integer usage: type: integer + prometheusNotReady: + type: boolean widgets: type: array items: