diff --git a/portal-ui/package.json b/portal-ui/package.json index 5d2a38fe4..1502448cd 100644 --- a/portal-ui/package.json +++ b/portal-ui/package.json @@ -29,7 +29,7 @@ "codemirror": "^5.52.2", "history": "^4.10.1", "local-storage-fallback": "^4.1.1", - "lodash": "^4.17.19", + "lodash": "^4.17.21", "moment": "^2.29.1", "react": "17.0.1", "react-app-rewire-hot-loader": "^2.0.1", diff --git a/portal-ui/src/common/utils.ts b/portal-ui/src/common/utils.ts index 9c817d774..2adc10def 100644 --- a/portal-ui/src/common/utils.ts +++ b/portal-ui/src/common/utils.ts @@ -422,9 +422,19 @@ export const generatePoolName = (pools: IPool[]) => { }; // seconds / minutes /hours / Days / Years calculator -export const niceDays = (secondsValue: string) => { +export const niceDays = (secondsValue: string, timeVariant: string = "s") => { let seconds = parseFloat(secondsValue); + switch (timeVariant) { + case "ns": + seconds = Math.floor(seconds * 0.000000001); + break; + case "ms": + seconds = Math.floor(seconds * 0.001); + break; + default: + } + const days = Math.floor(seconds / (3600 * 24)); seconds -= days * 3600 * 24; diff --git a/portal-ui/src/screens/Console/Dashboard/Prometheus/PrDashboard.tsx b/portal-ui/src/screens/Console/Dashboard/Prometheus/PrDashboard.tsx index 7adc2fdd8..74f3efccb 100644 --- a/portal-ui/src/screens/Console/Dashboard/Prometheus/PrDashboard.tsx +++ b/portal-ui/src/screens/Console/Dashboard/Prometheus/PrDashboard.tsx @@ -77,7 +77,7 @@ const PrDashboard = ({ classes, displayErrorMessage }: IPrDashboard) => { const xSpacing = 10; const ySpacing = 10; - const dashboardDistr = getDashboardDistribution(); + const dashboardDistr = getDashboardDistribution(panelInformation.length); const autoSizerStyleProp = { width: "100%", @@ -121,7 +121,7 @@ const PrDashboard = ({ classes, displayErrorMessage }: IPrDashboard) => { hideYAxis={value.disableYAxis} xAxisFormatter={value.xAxisFormatter} yAxisFormatter={value.yAxisFormatter} - panelWidth={singlePanelWidth * dashboardDistr[index].w} + panelWidth={dashboardDistr[index] ? singlePanelWidth * dashboardDistr[index].w : singlePanelWidth} /> ); case widgetType.barChart: @@ -160,12 +160,12 @@ const PrDashboard = ({ classes, displayErrorMessage }: IPrDashboard) => { ); const fetchUsage = useCallback(() => { - let stepCalc = 15; - + let stepCalc = 0; + if (timeStart !== null && timeEnd !== null) { const secondsInPeriod = timeEnd.unix() - timeStart.unix(); - const periods = secondsInPeriod / 60; - + const periods = Math.floor(secondsInPeriod / 60); + stepCalc = periods < 1 ? 15 : periods; } diff --git a/portal-ui/src/screens/Console/Dashboard/Prometheus/utils.ts b/portal-ui/src/screens/Console/Dashboard/Prometheus/utils.ts index 7de5a9f99..d5ff1b455 100644 --- a/portal-ui/src/screens/Console/Dashboard/Prometheus/utils.ts +++ b/portal-ui/src/screens/Console/Dashboard/Prometheus/utils.ts @@ -32,8 +32,8 @@ export const defaultWidgetsLayout: Layout[] = [ h: 2, x: 0, y: 0, - minW: 1, i: "panel-0", + minW: 1, moved: false, static: false, }, @@ -41,9 +41,9 @@ export const defaultWidgetsLayout: Layout[] = [ w: 1, h: 1, x: 1, - y: 0, - minW: 1, + y: 2, i: "panel-1", + minW: 1, moved: false, static: false, }, @@ -51,9 +51,9 @@ export const defaultWidgetsLayout: Layout[] = [ w: 1, h: 1, x: 1, - y: 1, - minW: 1, + y: 3, i: "panel-2", + minW: 1, moved: false, static: false, }, @@ -62,8 +62,8 @@ export const defaultWidgetsLayout: Layout[] = [ h: 2, x: 2, y: 0, - minW: 1, i: "panel-3", + minW: 1, moved: false, static: false, }, @@ -72,18 +72,18 @@ export const defaultWidgetsLayout: Layout[] = [ h: 2, x: 3, y: 0, - minW: 2, i: "panel-4", + minW: 2, moved: false, static: false, }, { - w: 3, + w: 2, h: 2, x: 5, y: 0, - minW: 2, i: "panel-5", + minW: 2, moved: false, static: false, }, @@ -92,8 +92,8 @@ export const defaultWidgetsLayout: Layout[] = [ h: 1, x: 0, y: 2, - minW: 1, i: "panel-6", + minW: 1, moved: false, static: false, }, @@ -102,58 +102,108 @@ export const defaultWidgetsLayout: Layout[] = [ h: 1, x: 0, y: 3, - minW: 1, i: "panel-7", + minW: 1, moved: false, static: false, }, { w: 1, h: 1, - x: 1, + x: 2, y: 2, - minW: 1, i: "panel-8", + minW: 1, moved: false, static: false, }, { w: 1, h: 1, - x: 1, + x: 2, y: 3, - minW: 1, i: "panel-9", - moved: false, - static: false, - }, - { - w: 1, - h: 1, - x: 2, - y: 2, minW: 1, - i: "panel-10", moved: false, static: false, }, { - w: 1, - h: 1, - x: 2, - y: 3, - minW: 1, - i: "panel-11", - moved: false, - static: false, - }, - { - w: 4, + w: 2, h: 2, x: 3, y: 2, + i: "panel-10", minW: 2, + moved: false, + static: false, + }, + { + w: 1, + h: 1, + x: 7, + y: 0, + i: "panel-11", + minW: 1, + moved: false, + static: false, + }, + { + w: 1, + h: 1, + x: 7, + y: 1, i: "panel-12", + minW: 1, + moved: false, + static: false, + }, + { + w: 4, + h: 3, + x: 0, + y: 10, + i: "panel-13", + minW: 2, + moved: false, + static: false, + }, + { + w: 4, + h: 3, + x: 0, + y: 4, + i: "panel-14", + minW: 2, + moved: false, + static: false, + }, + { + w: 2, + h: 2, + x: 5, + y: 2, + i: "panel-15", + minW: 2, + moved: false, + static: false, + }, + { + w: 8, + h: 3, + x: 0, + y: 7, + i: "panel-16", + minW: 2, + moved: false, + static: false, + }, + { + w: 8, + h: 3, + x: 0, + y: 19, + i: "panel-19", + minW: 2, moved: false, static: false, }, @@ -162,8 +212,8 @@ export const defaultWidgetsLayout: Layout[] = [ h: 1, x: 7, y: 2, + i: "panel-20", minW: 1, - i: "panel-13", moved: false, static: false, }, @@ -172,68 +222,88 @@ export const defaultWidgetsLayout: Layout[] = [ h: 1, x: 7, y: 3, + i: "panel-21", minW: 1, - i: "panel-14", moved: false, static: false, }, { - w: 8, - h: 2, - x: 0, + w: 4, + h: 3, + x: 4, y: 4, + i: "panel-22", minW: 2, - i: "panel-15", moved: false, static: false, }, { w: 4, - h: 2, + h: 3, + x: 4, + y: 10, + i: "panel-23", + minW: 2, + moved: false, + static: false, + }, + { + w: 4, + h: 3, x: 0, - y: 5, + y: 13, + i: "panel-24", minW: 2, - i: "panel-16", moved: false, static: false, }, { w: 4, - h: 2, - x: 5, - y: 5, + h: 3, + x: 4, + y: 13, + i: "panel-25", minW: 2, - i: "panel-17", moved: false, static: false, }, { - w: 8, - h: 2, + w: 4, + h: 3, x: 0, - y: 7, + y: 16, + i: "panel-26", minW: 2, - i: "panel-18", moved: false, static: false, }, { w: 4, - h: 2, - x: 0, - y: 9, + h: 3, + x: 4, + y: 16, + i: "panel-27", minW: 2, - i: "panel-19", moved: false, static: false, }, { - w: 4, - h: 2, - x: 5, - y: 9, - minW: 2, - i: "panel-20", + w: 1, + h: 1, + x: 1, + y: 0, + i: "panel-28", + minW: 1, + moved: false, + static: false, + }, + { + w: 1, + h: 1, + x: 1, + y: 1, + i: "panel-29", + minW: 1, moved: false, static: false, }, @@ -251,6 +321,10 @@ const colorsMain = [ "#ADD5E0", ]; +const niceDaysFromNS = (seconds: string) => { + return niceDays(seconds, 'ns'); +} + export const panelsConfiguration: IDashboardPanel[] = [ { title: "Uptime", @@ -260,19 +334,19 @@ export const panelsConfiguration: IDashboardPanel[] = [ labelDisplayFunction: niceDays, }, { - title: "Total Online disks", + title: "Total Online Disks", data: "N/A", type: widgetType.singleValue, layoutIdentifier: "panel-1", }, { - title: "Total Offline disks", + title: "Total Offline Disks", data: "N/A", type: widgetType.singleValue, layoutIdentifier: "panel-2", }, { - title: "Total Data", + title: "Current Usable Capacity", data: [], dataOuter: [{ name: "outer", value: 100 }], widgetConfiguration: { @@ -297,7 +371,7 @@ export const panelsConfiguration: IDashboardPanel[] = [ labelDisplayFunction: niceBytes, }, { - title: "Data Growth", + title: "Data Usage Growth", data: [], widgetConfiguration: [ { @@ -366,26 +440,6 @@ export const panelsConfiguration: IDashboardPanel[] = [ type: widgetType.singleValue, layoutIdentifier: "panel-7", }, - { - title: "Total S3 Traffic Inbound", - data: [], - innerLabel: "N/A", - type: widgetType.singleRep, - layoutIdentifier: "panel-8", - color: "#22B573", - fillColor: "#A6E8C4", - labelDisplayFunction: niceBytes, - }, - { - title: "Total S3 Traffic Outbound", - data: [], - innerLabel: "N/A", - type: widgetType.singleRep, - layoutIdentifier: "panel-9", - color: "#22B573", - fillColor: "#A6E8C4", - labelDisplayFunction: niceBytes, - }, { title: "Number of Buckets", data: [], @@ -393,7 +447,7 @@ export const panelsConfiguration: IDashboardPanel[] = [ type: widgetType.singleRep, color: "#0071BC", fillColor: "#ADD5E0", - layoutIdentifier: "panel-10", + layoutIdentifier: "panel-8", }, { title: "Number of Objects", @@ -402,10 +456,10 @@ export const panelsConfiguration: IDashboardPanel[] = [ type: widgetType.singleRep, color: "#0071BC", fillColor: "#ADD5E0", - layoutIdentifier: "panel-11", + layoutIdentifier: "panel-9", }, { - title: "S3 API Request & Error Rate", + title: "S3 API Data Received Rate", data: [], widgetConfiguration: [ { @@ -416,7 +470,7 @@ export const panelsConfiguration: IDashboardPanel[] = [ }, ], type: widgetType.linearGraph, - layoutIdentifier: "panel-12", + layoutIdentifier: "panel-10", disableYAxis: true, xAxisFormatter: getTimeFromTimestamp, }, @@ -425,21 +479,53 @@ export const panelsConfiguration: IDashboardPanel[] = [ data: [], innerLabel: "N/A", type: widgetType.singleRep, - layoutIdentifier: "panel-13", - color: "#F7655E", - fillColor: "#F4CECE", + layoutIdentifier: "panel-11", + color: "#22B573", + fillColor: "#A6E8C4", }, { title: "Total Goroutines", data: [], innerLabel: "N/A", type: widgetType.singleRep, - layoutIdentifier: "panel-14", + layoutIdentifier: "panel-12", color: "#F7655E", fillColor: "#F4CECE", }, { - title: "S3 API Data Transfer", + title: "Node CPU Usage", + data: [], + widgetConfiguration: [ + { + dataKey: "", + keyLabel: "", + lineColor: "#000", + fillColor: "#000", + }, + ], + type: widgetType.linearGraph, + layoutIdentifier: "panel-13", + disableYAxis: true, + xAxisFormatter: getTimeFromTimestamp, + }, + { + title: "S3 API Request Rate", + data: [], + widgetConfiguration: [ + { + dataKey: "", + keyLabel: "", + lineColor: "#000", + fillColor: "#000", + }, + ], + type: widgetType.linearGraph, + layoutIdentifier: "panel-14", + yAxisFormatter: niceBytes, + xAxisFormatter: getTimeFromTimestamp, + }, + { + title: "S3 API Data Sent Rate", data: [], widgetConfiguration: [ { @@ -451,11 +537,10 @@ export const panelsConfiguration: IDashboardPanel[] = [ ], type: widgetType.linearGraph, layoutIdentifier: "panel-15", - disableYAxis: true, xAxisFormatter: getTimeFromTimestamp, }, { - title: "Total S3 API Data Transfer", + title: "Internode Data Transfer", data: [], widgetConfiguration: [ { @@ -471,38 +556,7 @@ export const panelsConfiguration: IDashboardPanel[] = [ xAxisFormatter: getTimeFromTimestamp, }, { - title: "Active S3 Requests", - data: [], - widgetConfiguration: [ - { - dataKey: "", - keyLabel: "", - lineColor: "#000", - fillColor: "#000", - }, - ], - type: widgetType.linearGraph, - layoutIdentifier: "panel-17", - xAxisFormatter: getTimeFromTimestamp, - }, - { - title: "Internode Data Transfer", - data: [], - widgetConfiguration: [ - { - dataKey: "", - keyLabel: "", - lineColor: "#000", - fillColor: "#000", - }, - ], - type: widgetType.linearGraph, - layoutIdentifier: "panel-18", - yAxisFormatter: niceBytes, - xAxisFormatter: getTimeFromTimestamp, - }, - { - title: "Online Disks", + title: "Node IO", data: [], widgetConfiguration: [ { @@ -514,11 +568,25 @@ export const panelsConfiguration: IDashboardPanel[] = [ ], type: widgetType.linearGraph, layoutIdentifier: "panel-19", - disableYAxis: true, + yAxisFormatter: niceBytes, xAxisFormatter: getTimeFromTimestamp, }, { - title: "Disk Usage", + title: "Time Since Last Heal Activity", + data: "N/A", + type: widgetType.singleValue, + layoutIdentifier: "panel-20", + labelDisplayFunction: niceDaysFromNS, + }, + { + title: "Time Since Last Scan Activity", + data: "N/A", + type: widgetType.singleValue, + layoutIdentifier: "panel-21", + labelDisplayFunction: niceDaysFromNS, + }, + { + title: "S3 API Request Error Rate", data: [], widgetConfiguration: [ { @@ -529,10 +597,106 @@ export const panelsConfiguration: IDashboardPanel[] = [ }, ], type: widgetType.linearGraph, - layoutIdentifier: "panel-20", - yAxisFormatter: niceBytes, + layoutIdentifier: "panel-22", + disableYAxis: true, xAxisFormatter: getTimeFromTimestamp, }, + { + title: "Node Memory Usage", + data: [], + widgetConfiguration: [ + { + dataKey: "", + keyLabel: "", + lineColor: "#000", + fillColor: "#000", + }, + ], + type: widgetType.linearGraph, + layoutIdentifier: "panel-23", + disableYAxis: true, + xAxisFormatter: getTimeFromTimestamp, + yAxisFormatter: niceBytes, + }, + { + title: "Drive Used Capacity", + data: [], + widgetConfiguration: [ + { + dataKey: "", + keyLabel: "", + lineColor: "#000", + fillColor: "#000", + }, + ], + type: widgetType.linearGraph, + layoutIdentifier: "panel-24", + disableYAxis: true, + xAxisFormatter: getTimeFromTimestamp, + yAxisFormatter: niceBytes, + }, + { + title: "Drives Free Inodes", + data: [], + widgetConfiguration: [ + { + dataKey: "", + keyLabel: "", + lineColor: "#000", + fillColor: "#000", + }, + ], + type: widgetType.linearGraph, + layoutIdentifier: "panel-25", + disableYAxis: true, + xAxisFormatter: getTimeFromTimestamp, + }, + { + title: "Node Syscalls", + data: [], + widgetConfiguration: [ + { + dataKey: "", + keyLabel: "", + lineColor: "#000", + fillColor: "#000", + }, + ], + type: widgetType.linearGraph, + layoutIdentifier: "panel-26", + disableYAxis: true, + xAxisFormatter: getTimeFromTimestamp, + }, + { + title: "Node File Descriptors", + data: [], + widgetConfiguration: [ + { + dataKey: "", + keyLabel: "", + lineColor: "#000", + fillColor: "#000", + }, + ], + type: widgetType.linearGraph, + layoutIdentifier: "panel-27", + disableYAxis: true, + xAxisFormatter: getTimeFromTimestamp, + }, + { + title: "Total S3 Traffic Inbound", + data: "N/A", + type: widgetType.singleValue, + layoutIdentifier: "panel-28", + labelDisplayFunction: niceBytes, + }, + { + title: "Total S3 Traffic Outbound", + data: "N/A", + type: widgetType.singleValue, + layoutIdentifier: "panel-29", + labelDisplayFunction: niceBytes, + }, ]; const calculateMainValue = (elements: any[], metricCalc: string) => { @@ -574,7 +738,7 @@ const constructLabelNames = (metrics: any, legendFormat: string) => { export const getWidgetsWithValue = (payload: any[]) => { return panelsConfiguration.map((panelItem) => { const payloadData = payload.find( - (panelT) => panelT.title === panelItem.title + (panelT) => panelT.title.toLowerCase().trim() === panelItem.title.toLowerCase().trim() ); if (!payloadData) { @@ -853,7 +1017,7 @@ export const saveDashboardDistribution = (configuration: Layout[]) => { localStorage.setItem(dLocalStorageV, btoa(JSON.stringify(configuration))); }; -export const getDashboardDistribution = () => { +export const getDashboardDistribution = (currentItems: number) => { const storedConfiguration = localStorage.getItem(dLocalStorageV); if (!storedConfiguration) { @@ -869,5 +1033,10 @@ export const getDashboardDistribution = () => { return defaultWidgetsLayout; } + // Stored Widgets length is not the same as the currentItems, then we return the new configuration + if (currentItems !== 0 && parsedConfig.length !== currentItems) { + return defaultWidgetsLayout; + } + return parsedConfig; }; diff --git a/portal-ui/yarn.lock b/portal-ui/yarn.lock index 7dae76483..87ceb66c8 100644 --- a/portal-ui/yarn.lock +++ b/portal-ui/yarn.lock @@ -7464,6 +7464,11 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + loglevel@^1.6.8: version "1.7.1" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" diff --git a/restapi/admin_info.go b/restapi/admin_info.go index fae473c3a..7dbe9604b 100644 --- a/restapi/admin_info.go +++ b/restapi/admin_info.go @@ -93,11 +93,20 @@ type MetricOptions struct { } type Metric struct { - ID int32 - Title string - Type string - Options MetricOptions - Targets []Target + ID int32 + Title string + Type string + Options MetricOptions + Targets []Target + GridPos GridPos + MaxDataPoints int32 +} + +type GridPos struct { + H int32 + W int32 + X int32 + Y int32 } type WidgetLabel struct { @@ -111,10 +120,16 @@ var labels = []WidgetLabel{ var widgets = []Metric{ { - ID: 1, - Title: "Uptime", - Type: "stat", - + ID: 1, + Title: "Uptime", + Type: "stat", + MaxDataPoints: 100, + GridPos: GridPos{ + H: 6, + W: 3, + X: 0, + Y: 0, + }, Options: MetricOptions{ ReduceOptions: ReduceOptions{ Calcs: []string{ @@ -122,9 +137,7 @@ var widgets = []Metric{ }, }, }, - Targets: []Target{ - { Expr: "time() - max(minio_node_process_starttime_seconds)", LegendFormat: "{{instance}}", @@ -133,10 +146,16 @@ var widgets = []Metric{ }, }, { - ID: 65, - Title: "Total S3 Traffic Inbound", - Type: "stat", - + ID: 65, + Title: "Total S3 Traffic Inbound", + Type: "stat", + MaxDataPoints: 100, + GridPos: GridPos{ + H: 3, + W: 3, + X: 3, + Y: 0, + }, Options: MetricOptions{ ReduceOptions: ReduceOptions{ Calcs: []string{ @@ -144,9 +163,7 @@ var widgets = []Metric{ }, }, }, - Targets: []Target{ - { Expr: "sum by (instance) (minio_s3_traffic_received_bytes{job=\"minio-job\"})", LegendFormat: "{{instance}}", @@ -155,10 +172,16 @@ var widgets = []Metric{ }, }, { - ID: 50, - Title: "Current Usable Capacity", - Type: "gauge", - + ID: 50, + Title: "Current Usable Capacity", + Type: "gauge", + MaxDataPoints: 100, + GridPos: GridPos{ + H: 6, + W: 3, + X: 6, + Y: 0, + }, Options: MetricOptions{ ReduceOptions: ReduceOptions{ Calcs: []string{ @@ -166,9 +189,7 @@ var widgets = []Metric{ }, }, }, - Targets: []Target{ - { Expr: "topk(1, sum(minio_cluster_capacity_usable_free_bytes) by (instance))", LegendFormat: "", @@ -180,9 +201,13 @@ var widgets = []Metric{ ID: 68, Title: "Data Usage Growth", Type: "graph", - + GridPos: GridPos{ + H: 6, + W: 7, + X: 9, + Y: 0, + }, Targets: []Target{ - { Expr: "sum(minio_bucket_usage_total_bytes) by (instance)", LegendFormat: "Used Capacity", @@ -193,7 +218,12 @@ var widgets = []Metric{ ID: 52, Title: "Object size distribution", Type: "bargauge", - + GridPos: GridPos{ + H: 6, + W: 5, + X: 16, + Y: 0, + }, Options: MetricOptions{ ReduceOptions: ReduceOptions{ Calcs: []string{ @@ -201,9 +231,7 @@ var widgets = []Metric{ }, }, }, - Targets: []Target{ - { Expr: "max by (range) (minio_bucket_objects_size_distribution)", LegendFormat: "{{range}}", @@ -212,10 +240,16 @@ var widgets = []Metric{ }, }, { - ID: 61, - Title: "Total Open FDs", - Type: "stat", - + ID: 61, + Title: "Total Open FDs", + Type: "stat", + MaxDataPoints: 100, + GridPos: GridPos{ + H: 3, + W: 3, + X: 21, + Y: 0, + }, Options: MetricOptions{ ReduceOptions: ReduceOptions{ Calcs: []string{ @@ -223,9 +257,7 @@ var widgets = []Metric{ }, }, }, - Targets: []Target{ - { Expr: "sum (minio_node_file_descriptor_open_total)", LegendFormat: "", @@ -234,10 +266,16 @@ var widgets = []Metric{ }, }, { - ID: 64, - Title: "Total S3 Traffic Outbound", - Type: "stat", - + ID: 64, + Title: "Total S3 Traffic Outbound", + Type: "stat", + MaxDataPoints: 100, + GridPos: GridPos{ + H: 3, + W: 3, + X: 3, + Y: 3, + }, Options: MetricOptions{ ReduceOptions: ReduceOptions{ Calcs: []string{ @@ -245,9 +283,7 @@ var widgets = []Metric{ }, }, }, - Targets: []Target{ - { Expr: "sum by (instance) (minio_s3_traffic_sent_bytes{job=\"minio-job\"})", LegendFormat: "", @@ -256,10 +292,16 @@ var widgets = []Metric{ }, }, { - ID: 62, - Title: "Total Goroutines", - Type: "stat", - + ID: 62, + Title: "Total Goroutines", + Type: "stat", + MaxDataPoints: 100, + GridPos: GridPos{ + H: 3, + W: 3, + X: 21, + Y: 3, + }, Options: MetricOptions{ ReduceOptions: ReduceOptions{ Calcs: []string{ @@ -267,9 +309,7 @@ var widgets = []Metric{ }, }, }, - Targets: []Target{ - { Expr: "sum without (server,instance) (minio_node_go_routine_total)", LegendFormat: "", @@ -278,10 +318,16 @@ var widgets = []Metric{ }, }, { - ID: 53, - Title: "Total Online Servers", - Type: "stat", - + ID: 53, + Title: "Total Online Servers", + Type: "stat", + MaxDataPoints: 100, + GridPos: GridPos{ + H: 2, + W: 3, + X: 0, + Y: 6, + }, Options: MetricOptions{ ReduceOptions: ReduceOptions{ Calcs: []string{ @@ -289,9 +335,7 @@ var widgets = []Metric{ }, }, }, - Targets: []Target{ - { Expr: "minio_cluster_nodes_online_total", LegendFormat: "", @@ -300,10 +344,16 @@ var widgets = []Metric{ }, }, { - ID: 9, - Title: "Total Online Disks", - Type: "stat", - + ID: 9, + Title: "Total Online Disks", + Type: "stat", + MaxDataPoints: 100, + GridPos: GridPos{ + H: 2, + W: 3, + X: 3, + Y: 6, + }, Options: MetricOptions{ ReduceOptions: ReduceOptions{ Calcs: []string{ @@ -311,9 +361,7 @@ var widgets = []Metric{ }, }, }, - Targets: []Target{ - { Expr: "minio_cluster_disk_online_total", LegendFormat: "Total online disks in MinIO Cluster", @@ -322,10 +370,16 @@ var widgets = []Metric{ }, }, { - ID: 66, - Title: "Number of Buckets", - Type: "stat", - + ID: 66, + Title: "Number of Buckets", + Type: "stat", + MaxDataPoints: 100, + GridPos: GridPos{ + H: 3, + W: 3, + X: 6, + Y: 6, + }, Options: MetricOptions{ ReduceOptions: ReduceOptions{ Calcs: []string{ @@ -333,9 +387,7 @@ var widgets = []Metric{ }, }, }, - Targets: []Target{ - { Expr: "count(count by (bucket) (minio_bucket_usage_total_bytes))", LegendFormat: "", @@ -346,9 +398,13 @@ var widgets = []Metric{ ID: 63, Title: "S3 API Data Received Rate ", Type: "graph", - + GridPos: GridPos{ + H: 6, + W: 7, + X: 9, + Y: 6, + }, Targets: []Target{ - { Expr: "sum by (server) (rate(minio_s3_traffic_received_bytes[$__interval]))", LegendFormat: "Data Received [{{server}}]", @@ -359,9 +415,13 @@ var widgets = []Metric{ ID: 70, Title: "S3 API Data Sent Rate ", Type: "graph", - + GridPos: GridPos{ + H: 6, + W: 8, + X: 16, + Y: 6, + }, Targets: []Target{ - { Expr: "sum by (server) (rate(minio_s3_traffic_sent_bytes[$__interval]))", LegendFormat: "Data Sent [{{server}}]", @@ -369,10 +429,16 @@ var widgets = []Metric{ }, }, { - ID: 69, - Title: "Total Offline Servers", - Type: "stat", - + ID: 69, + Title: "Total Offline Servers", + Type: "stat", + MaxDataPoints: 100, + GridPos: GridPos{ + H: 2, + W: 3, + X: 0, + Y: 8, + }, Options: MetricOptions{ ReduceOptions: ReduceOptions{ Calcs: []string{ @@ -380,9 +446,7 @@ var widgets = []Metric{ }, }, }, - Targets: []Target{ - { Expr: "minio_cluster_nodes_offline_total", LegendFormat: "", @@ -391,10 +455,16 @@ var widgets = []Metric{ }, }, { - ID: 78, - Title: "Total Offline Disks", - Type: "stat", - + ID: 78, + Title: "Total Offline Disks", + Type: "stat", + MaxDataPoints: 100, + GridPos: GridPos{ + H: 2, + W: 3, + X: 3, + Y: 8, + }, Options: MetricOptions{ ReduceOptions: ReduceOptions{ Calcs: []string{ @@ -402,9 +472,7 @@ var widgets = []Metric{ }, }, }, - Targets: []Target{ - { Expr: "minio_cluster_disk_offline_total", LegendFormat: "", @@ -413,10 +481,16 @@ var widgets = []Metric{ }, }, { - ID: 44, - Title: "Number of Objects", - Type: "stat", - + ID: 44, + Title: "Number of Objects", + Type: "stat", + MaxDataPoints: 100, + GridPos: GridPos{ + H: 3, + W: 3, + X: 6, + Y: 9, + }, Options: MetricOptions{ ReduceOptions: ReduceOptions{ Calcs: []string{ @@ -424,9 +498,7 @@ var widgets = []Metric{ }, }, }, - Targets: []Target{ - { Expr: "topk(1, sum(minio_bucket_usage_object_total) by (instance))", LegendFormat: "", @@ -434,10 +506,16 @@ var widgets = []Metric{ }, }, { - ID: 80, - Title: "Time Since Last Heal Activity", - Type: "stat", - + ID: 80, + Title: "Time Since Last Heal Activity", + Type: "stat", + MaxDataPoints: 100, + GridPos: GridPos{ + H: 2, + W: 3, + X: 0, + Y: 10, + }, Options: MetricOptions{ ReduceOptions: ReduceOptions{ Calcs: []string{ @@ -445,9 +523,7 @@ var widgets = []Metric{ }, }, }, - Targets: []Target{ - { Expr: "minio_heal_time_last_activity_nano_seconds", LegendFormat: "{{server}}", @@ -456,10 +532,16 @@ var widgets = []Metric{ }, }, { - ID: 81, - Title: "Time Since Last Scan Activity", - Type: "stat", - + ID: 81, + Title: "Time Since Last Scan Activity", + Type: "stat", + MaxDataPoints: 100, + GridPos: GridPos{ + H: 2, + W: 3, + X: 3, + Y: 10, + }, Options: MetricOptions{ ReduceOptions: ReduceOptions{ Calcs: []string{ @@ -467,9 +549,7 @@ var widgets = []Metric{ }, }, }, - Targets: []Target{ - { Expr: "minio_usage_last_activity_nano_seconds", LegendFormat: "{{server}}", @@ -481,9 +561,13 @@ var widgets = []Metric{ ID: 60, Title: "S3 API Request Rate", Type: "graph", - + GridPos: GridPos{ + H: 10, + W: 12, + X: 0, + Y: 12, + }, Targets: []Target{ - { Expr: "sum by (server,api) (rate(minio_s3_requests_total[$__interval]))", LegendFormat: "{{server,api}}", @@ -494,9 +578,13 @@ var widgets = []Metric{ ID: 71, Title: "S3 API Request Error Rate", Type: "graph", - + GridPos: GridPos{ + H: 10, + W: 12, + X: 12, + Y: 12, + }, Targets: []Target{ - { Expr: "rate(minio_s3_requests_errors_total[$__interval])", LegendFormat: "{{server,api}}", @@ -507,9 +595,13 @@ var widgets = []Metric{ ID: 17, Title: "Internode Data Transfer", Type: "graph", - + GridPos: GridPos{ + H: 8, + W: 24, + X: 0, + Y: 22, + }, Targets: []Target{ - { Expr: "rate(minio_inter_node_traffic_sent_bytes{job=\"minio-job\"}[$__interval])", LegendFormat: "Internode Bytes Received [{{server}}]", @@ -519,7 +611,6 @@ var widgets = []Metric{ { Expr: "rate(minio_inter_node_traffic_sent_bytes{job=\"minio-job\"}[$__interval])", LegendFormat: "Internode Bytes Received [{{server}}]", - Step: 4, }, }, }, @@ -527,9 +618,13 @@ var widgets = []Metric{ ID: 77, Title: "Node CPU Usage", Type: "graph", - + GridPos: GridPos{ + H: 9, + W: 12, + X: 0, + Y: 30, + }, Targets: []Target{ - { Expr: "rate(minio_node_process_cpu_total_seconds[$__interval])", LegendFormat: "CPU Usage Rate [{{server}}]", @@ -540,9 +635,13 @@ var widgets = []Metric{ ID: 76, Title: "Node Memory Usage", Type: "graph", - + GridPos: GridPos{ + H: 9, + W: 12, + X: 12, + Y: 30, + }, Targets: []Target{ - { Expr: "minio_node_process_resident_memory_bytes", LegendFormat: "Memory Used [{{server}}]", @@ -553,9 +652,13 @@ var widgets = []Metric{ ID: 74, Title: "Drive Used Capacity", Type: "graph", - + GridPos: GridPos{ + H: 8, + W: 12, + X: 0, + Y: 39, + }, Targets: []Target{ - { Expr: "minio_node_disk_used_bytes", LegendFormat: "Used Capacity [{{server}}:{{disk}}]", @@ -566,9 +669,13 @@ var widgets = []Metric{ ID: 82, Title: "Drives Free Inodes", Type: "graph", - + GridPos: GridPos{ + H: 8, + W: 12, + X: 12, + Y: 39, + }, Targets: []Target{ - { Expr: "minio_cluster_disk_free_inodes", LegendFormat: "Free Inodes [{{server}}:{{disk}}]", @@ -579,9 +686,13 @@ var widgets = []Metric{ ID: 11, Title: "Node Syscalls", Type: "graph", - + GridPos: GridPos{ + H: 9, + W: 12, + X: 0, + Y: 47, + }, Targets: []Target{ - { Expr: "rate(minio_node_syscall_read_total[$__interval])", LegendFormat: "Read Syscalls [{{server}}]", @@ -591,7 +702,6 @@ var widgets = []Metric{ { Expr: "rate(minio_node_syscall_read_total[$__interval])", LegendFormat: "Read Syscalls [{{server}}]", - Step: 60, }, }, }, @@ -599,9 +709,13 @@ var widgets = []Metric{ ID: 8, Title: "Node File Descriptors", Type: "graph", - + GridPos: GridPos{ + H: 9, + W: 12, + X: 12, + Y: 47, + }, Targets: []Target{ - { Expr: "minio_node_file_descriptor_open_total", LegendFormat: "Open FDs [{{server}}]", @@ -612,9 +726,13 @@ var widgets = []Metric{ ID: 73, Title: "Node IO", Type: "graph", - + GridPos: GridPos{ + H: 8, + W: 24, + X: 0, + Y: 56, + }, Targets: []Target{ - { Expr: "rate(minio_node_io_rchar_bytes[$__interval])", LegendFormat: "Node RChar [{{server}}]", @@ -656,6 +774,8 @@ type LabelResults struct { Response LabelResponse } +var jobRegex = regexp.MustCompile(`(?m)\{[a-z]+\=\".*?\"\}`) + // getAdminInfoResponse returns the response containing total buckets, objects and usage. func getAdminInfoResponse(session *models.Principal, params admin_api.AdminInfoParams) (*models.AdminInfoResponse, *models.Error) { prometheusURL := getPrometheusURL() @@ -755,10 +875,15 @@ LabelsWaitLoop: extraParamters := fmt.Sprintf("&start=%d&end=%d", now.Add(-15*time.Minute).Unix(), now.Unix()) + var step int32 = 60 if target.Step > 0 { - extraParamters = fmt.Sprintf("%s&step=%d", extraParamters, target.Step) - } else { - extraParamters = fmt.Sprintf("%s&step=%d", extraParamters, *params.Step) + step = target.Step + } + if params.Step != nil && *params.Step > 0 { + step = *params.Step + } + if step > 0 { + extraParamters = fmt.Sprintf("%s&step=%d", extraParamters, step) } if params.Start != nil && params.End != nil { @@ -766,7 +891,7 @@ LabelsWaitLoop: } // replace the `$__interval` global for step with unit (s for seconds) - queryExpr := strings.ReplaceAll(target.Expr, "$__interval", fmt.Sprintf("%ds", *params.Step)) + queryExpr := strings.ReplaceAll(target.Expr, "$__interval", fmt.Sprintf("%ds", 120)) if strings.Contains(queryExpr, "$") { var re = regexp.MustCompile(`\$([a-z]+)`) @@ -777,7 +902,14 @@ LabelsWaitLoop: } } + // replace the weird {job="asd"} in the exp + if strings.Contains(queryExpr, "job=") { + queryExpr = jobRegex.ReplaceAllString(queryExpr, "") + } + endpoint := fmt.Sprintf("%s/api/v1/%s?query=%s%s", getPrometheusURL(), apiType, url.QueryEscape(queryExpr), extraParamters) + + log.Printf("%s \t - %d [%d] - %s\n\n", m.Title, target.Step, params.Step, endpoint) resp, err := http.Get(endpoint) if err != nil { log.Println(err) diff --git a/restapi/embedded_spec.go b/restapi/embedded_spec.go index e1388c254..88bd44578 100644 --- a/restapi/embedded_spec.go +++ b/restapi/embedded_spec.go @@ -128,7 +128,7 @@ func init() { }, { "type": "integer", - "default": 15, + "format": "int32", "name": "step", "in": "query" } @@ -7002,7 +7002,7 @@ func init() { }, { "type": "integer", - "default": 15, + "format": "int32", "name": "step", "in": "query" } diff --git a/restapi/operations/admin_api/admin_info_parameters.go b/restapi/operations/admin_api/admin_info_parameters.go index d5bdb8dca..b072e6bc5 100644 --- a/restapi/operations/admin_api/admin_info_parameters.go +++ b/restapi/operations/admin_api/admin_info_parameters.go @@ -33,18 +33,10 @@ import ( ) // NewAdminInfoParams creates a new AdminInfoParams object -// with the default values initialized. +// no default values defined in spec. func NewAdminInfoParams() AdminInfoParams { - var ( - // initialize parameters with default values - - stepDefault = int64(15) - ) - - return AdminInfoParams{ - Step: &stepDefault, - } + return AdminInfoParams{} } // AdminInfoParams contains all the bound params for the admin info operation @@ -66,9 +58,8 @@ type AdminInfoParams struct { Start *int64 /* In: query - Default: 15 */ - Step *int64 + Step *int32 } // BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface @@ -157,13 +148,12 @@ func (o *AdminInfoParams) bindStep(rawData []string, hasKey bool, formats strfmt // Required: false // AllowEmptyValue: false if raw == "" { // empty values pass all other validations - // Default values have been previously initialized by NewAdminInfoParams() return nil } - value, err := swag.ConvertInt64(raw) + value, err := swag.ConvertInt32(raw) if err != nil { - return errors.InvalidType("step", "query", "int64", raw) + return errors.InvalidType("step", "query", "int32", raw) } o.Step = &value diff --git a/restapi/operations/admin_api/admin_info_urlbuilder.go b/restapi/operations/admin_api/admin_info_urlbuilder.go index 17ea274f2..07806dca9 100644 --- a/restapi/operations/admin_api/admin_info_urlbuilder.go +++ b/restapi/operations/admin_api/admin_info_urlbuilder.go @@ -34,7 +34,7 @@ import ( type AdminInfoURL struct { End *int64 Start *int64 - Step *int64 + Step *int32 _basePath string // avoid unkeyed usage @@ -88,7 +88,7 @@ func (o *AdminInfoURL) Build() (*url.URL, error) { var stepQ string if o.Step != nil { - stepQ = swag.FormatInt64(*o.Step) + stepQ = swag.FormatInt32(*o.Step) } if stepQ != "" { qs.Set("step", stepQ) diff --git a/swagger.yml b/swagger.yml index 5ea890623..05f32a3ff 100644 --- a/swagger.yml +++ b/swagger.yml @@ -1758,9 +1758,9 @@ paths: in: query type: integer - name: step - default: 15 in: query type: integer + format: int32 responses: 200: description: A successful response.