From 2e456a6cb2fad616688cc26239d08e7ae8ef4cf7 Mon Sep 17 00:00:00 2001 From: Nurlan Moldomurov Date: Tue, 10 Sep 2024 11:54:49 +0300 Subject: [PATCH 01/10] PMM-13348 Fix status presentation. --- .../grafana-ui/src/components/Badge/Badge.tsx | 2 +- public/app/percona/inventory/Inventory.types.ts | 1 + public/app/percona/inventory/Tabs/Agents.tsx | 4 ++++ .../percona/inventory/Tabs/Services.utils.ts | 2 +- .../components/StatusBadge/StatusBadge.test.tsx | 17 +++++++++++++++++ .../components/StatusBadge/StatusBadge.tsx | 6 ++++-- 6 files changed, 28 insertions(+), 4 deletions(-) diff --git a/packages/grafana-ui/src/components/Badge/Badge.tsx b/packages/grafana-ui/src/components/Badge/Badge.tsx index e8e1e4ac1ee53..c9fec5ce5cfe8 100644 --- a/packages/grafana-ui/src/components/Badge/Badge.tsx +++ b/packages/grafana-ui/src/components/Badge/Badge.tsx @@ -10,7 +10,7 @@ import { Icon } from '../Icon/Icon'; import { HorizontalGroup } from '../Layout/Layout'; import { Tooltip } from '../Tooltip'; -export type BadgeColor = 'blue' | 'red' | 'green' | 'orange' | 'purple'; +export type BadgeColor = 'blue' | 'red' | 'green' | 'orange' | 'purple' | 'gray'; export interface BadgeProps extends HTMLAttributes { text: React.ReactNode; diff --git a/public/app/percona/inventory/Inventory.types.ts b/public/app/percona/inventory/Inventory.types.ts index a3acfb9408eb8..2a1a90bd4d24f 100644 --- a/public/app/percona/inventory/Inventory.types.ts +++ b/public/app/percona/inventory/Inventory.types.ts @@ -54,6 +54,7 @@ export enum ServiceAgentStatus { STARTING = 'STARTING', RUNNING = 'RUNNING', WAITING = 'WAITING', + INITIALIZATION_ERROR = 'INITIALIZATION_ERROR', STOPPING = 'STOPPING', DONE = 'DONE', UNKNOWN = 'UNKNOWN', diff --git a/public/app/percona/inventory/Tabs/Agents.tsx b/public/app/percona/inventory/Tabs/Agents.tsx index bb9ca8dda81cb..062a8b6532c42 100644 --- a/public/app/percona/inventory/Tabs/Agents.tsx +++ b/public/app/percona/inventory/Tabs/Agents.tsx @@ -92,6 +92,10 @@ export const Agents: FC { export const getAgentsMonitoringStatus = (agents: DbAgent[]) => { const allAgentsOk = agents?.every( (agent) => - agent.status === ServiceAgentStatus.RUNNING || agent.status === ServiceAgentStatus.STARTING || !!agent.isConnected + agent.status === ServiceAgentStatus.RUNNING || agent.status === ServiceAgentStatus.STARTING || !!agent.isConnected || agent.status === ServiceAgentStatus.UNKNOWN ); return allAgentsOk ? MonitoringStatus.OK : MonitoringStatus.FAILED; }; diff --git a/public/app/percona/inventory/components/StatusBadge/StatusBadge.test.tsx b/public/app/percona/inventory/components/StatusBadge/StatusBadge.test.tsx index 85109c54448cf..e5260e6b12b89 100644 --- a/public/app/percona/inventory/components/StatusBadge/StatusBadge.test.tsx +++ b/public/app/percona/inventory/components/StatusBadge/StatusBadge.test.tsx @@ -64,4 +64,21 @@ describe('StatusBadge', () => { expect(screen.queryByTestId('status-badge-red')).toBeInTheDocument(); expect(screen.queryByText('3/3 not running')).toBeInTheDocument(); }); + it('should render grey if any agent has unknown status', () => { + render( + + + + ); + expect(screen.queryByTestId('status-badge-gray')).toBeInTheDocument(); + expect(screen.queryByText('2/3 running')).toBeInTheDocument(); + }); }); diff --git a/public/app/percona/inventory/components/StatusBadge/StatusBadge.tsx b/public/app/percona/inventory/components/StatusBadge/StatusBadge.tsx index 959588328852c..bdd3dc4cbfb61 100644 --- a/public/app/percona/inventory/components/StatusBadge/StatusBadge.tsx +++ b/public/app/percona/inventory/components/StatusBadge/StatusBadge.tsx @@ -16,7 +16,7 @@ export const StatusBadge: FC = ({ agents, type, strippedId }) const link = `/inventory/${type}/${strippedId}/agents`; const totalAgents = agents.length; - const [good, bad] = agents.reduce( + const [good, bad, unknown] = agents.reduce( (acc, agent) => { if ( agent.status === ServiceAgentStatus.RUNNING || @@ -24,6 +24,8 @@ export const StatusBadge: FC = ({ agents, type, strippedId }) !!agent.isConnected ) { acc[0]++; + } else if (agent.status === ServiceAgentStatus.UNKNOWN) { + acc[2]++; } else { acc[1]++; } @@ -32,7 +34,7 @@ export const StatusBadge: FC = ({ agents, type, strippedId }) [0, 0] ); const percentageNotRunning = bad / totalAgents; - const badgeColor: BadgeColor = percentageNotRunning === 1 ? 'red' : percentageNotRunning === 0 ? 'green' : 'orange'; + const badgeColor: BadgeColor = percentageNotRunning === 1 ? 'red' : percentageNotRunning === 0 ? 'green' : unknown === 0 ? 'orange' : 'gray'; const textToShow = `${percentageNotRunning === 1 ? bad : good}/${totalAgents}`; const textToAppend = `${percentageNotRunning === 1 ? ' not running' : ' running'}`; From c3f81c3b1e0c1125926d3066e0ed7ad7a20f2c76 Mon Sep 17 00:00:00 2001 From: Nurlan Moldomurov Date: Wed, 11 Sep 2024 01:22:30 +0300 Subject: [PATCH 02/10] PMM-13348 Fix status presentation. --- public/app/percona/inventory/Tabs/Agents.tsx | 4 ++-- public/app/percona/inventory/Tabs/Agents.utils.ts | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/public/app/percona/inventory/Tabs/Agents.tsx b/public/app/percona/inventory/Tabs/Agents.tsx index 062a8b6532c42..e3d27f83b0386 100644 --- a/public/app/percona/inventory/Tabs/Agents.tsx +++ b/public/app/percona/inventory/Tabs/Agents.tsx @@ -33,7 +33,7 @@ import { GET_AGENTS_CANCEL_TOKEN, GET_NODES_CANCEL_TOKEN, GET_SERVICES_CANCEL_TO import { Messages } from '../Inventory.messages'; import { InventoryService } from '../Inventory.service'; -import { beautifyAgentType, getAgentStatusColor, toAgentModel } from './Agents.utils'; +import { beautifyAgentType, getAgentStatusColor, getBadgeTextForAgentStatus, toAgentModel } from './Agents.utils'; import { formatNodeId } from './Nodes.utils'; import { getStyles } from './Tabs.styles'; @@ -64,7 +64,7 @@ export const Agents: FC ( - + ), type: FilterFieldTypes.DROPDOWN, options: [ diff --git a/public/app/percona/inventory/Tabs/Agents.utils.ts b/public/app/percona/inventory/Tabs/Agents.utils.ts index b6fecead62b1c..935fe0f4bcd38 100644 --- a/public/app/percona/inventory/Tabs/Agents.utils.ts +++ b/public/app/percona/inventory/Tabs/Agents.utils.ts @@ -1,4 +1,5 @@ import { BadgeColor } from '@grafana/ui'; +import { capitalizeText } from "app/percona/shared/helpers/capitalizeText"; import { payloadToCamelCase } from 'app/percona/shared/helpers/payloadToCamelCase'; import { Agent, AgentType, ServiceAgentPayload, ServiceAgentStatus } from '../Inventory.types'; @@ -53,4 +54,8 @@ export const beautifyAgentType = (type: AgentType): string => type.replace(/^\w/, (c) => c.toUpperCase()).replace(/[_-]/g, ' '); export const getAgentStatusColor = (status: ServiceAgentStatus): BadgeColor => - status === ServiceAgentStatus.STARTING || status === ServiceAgentStatus.RUNNING ? 'green' : 'red'; + status === ServiceAgentStatus.STARTING || status === ServiceAgentStatus.RUNNING ? 'green' : status === ServiceAgentStatus.UNKNOWN ? 'gray' : 'red'; + +export const getBadgeTextForAgentStatus = (status: ServiceAgentStatus): string => { + return capitalizeText(status.replace('_', ' ')); +}; From 16bcde9fa80c6e2723c8402806b9f601dd4575dd Mon Sep 17 00:00:00 2001 From: Nurlan Moldomurov Date: Fri, 13 Sep 2024 10:21:18 +0300 Subject: [PATCH 03/10] PMM-13348 Fix status presentation. --- public/app/percona/inventory/Inventory.types.ts | 2 ++ public/app/percona/inventory/Tabs/Agents.tsx | 1 - public/app/percona/inventory/Tabs/Nodes.tsx | 4 ++++ public/app/percona/inventory/Tabs/Services.utils.ts | 12 ++++++++++-- .../inventory/Tabs/Services/ServicesTable.tsx | 4 ++++ .../inventory/components/StatusBadge/StatusBadge.tsx | 4 ++-- .../components/StatusLink/StatusLink.styles.ts | 5 +++-- .../inventory/components/StatusLink/StatusLink.tsx | 4 +--- 8 files changed, 26 insertions(+), 10 deletions(-) diff --git a/public/app/percona/inventory/Inventory.types.ts b/public/app/percona/inventory/Inventory.types.ts index 2a1a90bd4d24f..ed12786de9ab4 100644 --- a/public/app/percona/inventory/Inventory.types.ts +++ b/public/app/percona/inventory/Inventory.types.ts @@ -58,11 +58,13 @@ export enum ServiceAgentStatus { STOPPING = 'STOPPING', DONE = 'DONE', UNKNOWN = 'UNKNOWN', + INVALID = '', } export enum MonitoringStatus { OK = 'OK', FAILED = 'Failed', + UNKNOWN = 'Unknown', } export interface ServiceAgentPayload { diff --git a/public/app/percona/inventory/Tabs/Agents.tsx b/public/app/percona/inventory/Tabs/Agents.tsx index e3d27f83b0386..bd72dbb847f9c 100644 --- a/public/app/percona/inventory/Tabs/Agents.tsx +++ b/public/app/percona/inventory/Tabs/Agents.tsx @@ -21,7 +21,6 @@ import { fetchNodesAction } from 'app/percona/shared/core/reducers/nodes/nodes'; import { fetchServicesAction } from 'app/percona/shared/core/reducers/services'; import { getNodes, getServices } from 'app/percona/shared/core/selectors'; import { isApiCancelError } from 'app/percona/shared/helpers/api'; -import { capitalizeText } from 'app/percona/shared/helpers/capitalizeText'; import { getExpandAndActionsCol } from 'app/percona/shared/helpers/getExpandAndActionsCol'; import { logger } from 'app/percona/shared/helpers/logger'; import { filterFulfilled, processPromiseResults } from 'app/percona/shared/helpers/promises'; diff --git a/public/app/percona/inventory/Tabs/Nodes.tsx b/public/app/percona/inventory/Tabs/Nodes.tsx index 7d738f55d8cc1..c7042c7280605 100644 --- a/public/app/percona/inventory/Tabs/Nodes.tsx +++ b/public/app/percona/inventory/Tabs/Nodes.tsx @@ -143,6 +143,10 @@ export const NodesTab = () => { label: MonitoringStatus.FAILED, value: MonitoringStatus.FAILED, }, + { + label: MonitoringStatus.UNKNOWN, + value: MonitoringStatus.UNKNOWN, + }, ], }, { diff --git a/public/app/percona/inventory/Tabs/Services.utils.ts b/public/app/percona/inventory/Tabs/Services.utils.ts index f1226edf19d53..c9086b107fa28 100644 --- a/public/app/percona/inventory/Tabs/Services.utils.ts +++ b/public/app/percona/inventory/Tabs/Services.utils.ts @@ -45,9 +45,17 @@ export const getBadgeTextForServiceStatus = (status: ServiceStatus): string => { export const getAgentsMonitoringStatus = (agents: DbAgent[]) => { const allAgentsOk = agents?.every( (agent) => - agent.status === ServiceAgentStatus.RUNNING || agent.status === ServiceAgentStatus.STARTING || !!agent.isConnected || agent.status === ServiceAgentStatus.UNKNOWN + agent.status === ServiceAgentStatus.RUNNING || agent.status === ServiceAgentStatus.STARTING || !!agent.isConnected ); - return allAgentsOk ? MonitoringStatus.OK : MonitoringStatus.FAILED; + console.log('allAgentsOk', allAgentsOk); + const hasUnknownAgents = agents?.some( + (agent) => + agent.agentType !== "pmm-agent" && (agent.status === ServiceAgentStatus.UNKNOWN || agent.status === ServiceAgentStatus.INVALID || agent.status === undefined) + ); + + console.log('hasUnknownAgents', hasUnknownAgents); + console.log('agents', agents); + return allAgentsOk ? MonitoringStatus.OK : hasUnknownAgents ? MonitoringStatus.UNKNOWN : MonitoringStatus.FAILED; }; export const stripServiceId = (serviceId: string) => { diff --git a/public/app/percona/inventory/Tabs/Services/ServicesTable.tsx b/public/app/percona/inventory/Tabs/Services/ServicesTable.tsx index 55d14ab928267..0d687249d0164 100644 --- a/public/app/percona/inventory/Tabs/Services/ServicesTable.tsx +++ b/public/app/percona/inventory/Tabs/Services/ServicesTable.tsx @@ -160,6 +160,10 @@ const ServicesTable: FC = ({ label: MonitoringStatus.FAILED, value: MonitoringStatus.FAILED, }, + { + label: MonitoringStatus.UNKNOWN, + value: MonitoringStatus.UNKNOWN, + }, ], }, { diff --git a/public/app/percona/inventory/components/StatusBadge/StatusBadge.tsx b/public/app/percona/inventory/components/StatusBadge/StatusBadge.tsx index bdd3dc4cbfb61..199d397f66e2e 100644 --- a/public/app/percona/inventory/components/StatusBadge/StatusBadge.tsx +++ b/public/app/percona/inventory/components/StatusBadge/StatusBadge.tsx @@ -24,14 +24,14 @@ export const StatusBadge: FC = ({ agents, type, strippedId }) !!agent.isConnected ) { acc[0]++; - } else if (agent.status === ServiceAgentStatus.UNKNOWN) { + } else if (agent.status === ServiceAgentStatus.UNKNOWN || agent.status === ServiceAgentStatus.INVALID) { acc[2]++; } else { acc[1]++; } return acc; }, - [0, 0] + [0, 0, 0] ); const percentageNotRunning = bad / totalAgents; const badgeColor: BadgeColor = percentageNotRunning === 1 ? 'red' : percentageNotRunning === 0 ? 'green' : unknown === 0 ? 'orange' : 'gray'; diff --git a/public/app/percona/inventory/components/StatusLink/StatusLink.styles.ts b/public/app/percona/inventory/components/StatusLink/StatusLink.styles.ts index ff4040da7eb5f..7941c3eb67708 100644 --- a/public/app/percona/inventory/components/StatusLink/StatusLink.styles.ts +++ b/public/app/percona/inventory/components/StatusLink/StatusLink.styles.ts @@ -1,10 +1,11 @@ import { css } from '@emotion/css'; import { GrafanaTheme2 } from '@grafana/data'; +import { MonitoringStatus } from "app/percona/inventory/Inventory.types"; -export const getStyles = ({ visualization }: GrafanaTheme2, allAgentsOk: boolean) => ({ +export const getStyles = ({ visualization }: GrafanaTheme2, status: string | undefined) => ({ link: css` text-decoration: underline; - color: ${allAgentsOk ? visualization.getColorByName('green') : visualization.getColorByName('red')}; + color: ${status === MonitoringStatus.OK ? visualization.getColorByName('green') : status === MonitoringStatus.FAILED ? visualization.getColorByName('red') : visualization.getColorByName('gray')}; `, }); diff --git a/public/app/percona/inventory/components/StatusLink/StatusLink.tsx b/public/app/percona/inventory/components/StatusLink/StatusLink.tsx index d2e37e960124e..a58297789a7f5 100644 --- a/public/app/percona/inventory/components/StatusLink/StatusLink.tsx +++ b/public/app/percona/inventory/components/StatusLink/StatusLink.tsx @@ -2,14 +2,12 @@ import React, { FC } from 'react'; import { Link, useStyles2 } from '@grafana/ui'; -import { MonitoringStatus } from '../../Inventory.types'; - import { getStyles } from './StatusLink.styles'; import { StatusLinkProps } from './StatusLink.types'; export const StatusLink: FC = ({ agentsStatus, type, strippedId }) => { const link = `/inventory/${type}/${strippedId}/agents`; - const styles = useStyles2((theme) => getStyles(theme, agentsStatus === MonitoringStatus.OK)); + const styles = useStyles2((theme) => getStyles(theme, agentsStatus)); return ( From 24b14e13572fbee97a0410dff263d36a9ca2d286 Mon Sep 17 00:00:00 2001 From: Nurlan Moldomurov Date: Fri, 13 Sep 2024 12:33:02 +0300 Subject: [PATCH 04/10] PMM-13348 Fix status presentation, revert StatusBadge changes. --- public/app/percona/inventory/Inventory.types.ts | 2 +- public/app/percona/inventory/Tabs/Nodes.tsx | 4 ++-- .../percona/inventory/Tabs/Services.utils.ts | 2 +- .../inventory/Tabs/Services/ServicesTable.tsx | 4 ++-- .../components/StatusBadge/StatusBadge.test.tsx | 17 ----------------- .../components/StatusBadge/StatusBadge.tsx | 8 +++----- 6 files changed, 9 insertions(+), 28 deletions(-) diff --git a/public/app/percona/inventory/Inventory.types.ts b/public/app/percona/inventory/Inventory.types.ts index ed12786de9ab4..fbc9463b24796 100644 --- a/public/app/percona/inventory/Inventory.types.ts +++ b/public/app/percona/inventory/Inventory.types.ts @@ -64,7 +64,7 @@ export enum ServiceAgentStatus { export enum MonitoringStatus { OK = 'OK', FAILED = 'Failed', - UNKNOWN = 'Unknown', + NA = 'N/A', } export interface ServiceAgentPayload { diff --git a/public/app/percona/inventory/Tabs/Nodes.tsx b/public/app/percona/inventory/Tabs/Nodes.tsx index c7042c7280605..d09efd2edc156 100644 --- a/public/app/percona/inventory/Tabs/Nodes.tsx +++ b/public/app/percona/inventory/Tabs/Nodes.tsx @@ -144,8 +144,8 @@ export const NodesTab = () => { value: MonitoringStatus.FAILED, }, { - label: MonitoringStatus.UNKNOWN, - value: MonitoringStatus.UNKNOWN, + label: MonitoringStatus.NA, + value: MonitoringStatus.NA, }, ], }, diff --git a/public/app/percona/inventory/Tabs/Services.utils.ts b/public/app/percona/inventory/Tabs/Services.utils.ts index c9086b107fa28..6c74278a78d93 100644 --- a/public/app/percona/inventory/Tabs/Services.utils.ts +++ b/public/app/percona/inventory/Tabs/Services.utils.ts @@ -55,7 +55,7 @@ export const getAgentsMonitoringStatus = (agents: DbAgent[]) => { console.log('hasUnknownAgents', hasUnknownAgents); console.log('agents', agents); - return allAgentsOk ? MonitoringStatus.OK : hasUnknownAgents ? MonitoringStatus.UNKNOWN : MonitoringStatus.FAILED; + return allAgentsOk ? MonitoringStatus.OK : hasUnknownAgents ? MonitoringStatus.NA : MonitoringStatus.FAILED; }; export const stripServiceId = (serviceId: string) => { diff --git a/public/app/percona/inventory/Tabs/Services/ServicesTable.tsx b/public/app/percona/inventory/Tabs/Services/ServicesTable.tsx index 0d687249d0164..2ea443c2e175e 100644 --- a/public/app/percona/inventory/Tabs/Services/ServicesTable.tsx +++ b/public/app/percona/inventory/Tabs/Services/ServicesTable.tsx @@ -161,8 +161,8 @@ const ServicesTable: FC = ({ value: MonitoringStatus.FAILED, }, { - label: MonitoringStatus.UNKNOWN, - value: MonitoringStatus.UNKNOWN, + label: MonitoringStatus.NA, + value: MonitoringStatus.NA, }, ], }, diff --git a/public/app/percona/inventory/components/StatusBadge/StatusBadge.test.tsx b/public/app/percona/inventory/components/StatusBadge/StatusBadge.test.tsx index e5260e6b12b89..85109c54448cf 100644 --- a/public/app/percona/inventory/components/StatusBadge/StatusBadge.test.tsx +++ b/public/app/percona/inventory/components/StatusBadge/StatusBadge.test.tsx @@ -64,21 +64,4 @@ describe('StatusBadge', () => { expect(screen.queryByTestId('status-badge-red')).toBeInTheDocument(); expect(screen.queryByText('3/3 not running')).toBeInTheDocument(); }); - it('should render grey if any agent has unknown status', () => { - render( - - - - ); - expect(screen.queryByTestId('status-badge-gray')).toBeInTheDocument(); - expect(screen.queryByText('2/3 running')).toBeInTheDocument(); - }); }); diff --git a/public/app/percona/inventory/components/StatusBadge/StatusBadge.tsx b/public/app/percona/inventory/components/StatusBadge/StatusBadge.tsx index 199d397f66e2e..959588328852c 100644 --- a/public/app/percona/inventory/components/StatusBadge/StatusBadge.tsx +++ b/public/app/percona/inventory/components/StatusBadge/StatusBadge.tsx @@ -16,7 +16,7 @@ export const StatusBadge: FC = ({ agents, type, strippedId }) const link = `/inventory/${type}/${strippedId}/agents`; const totalAgents = agents.length; - const [good, bad, unknown] = agents.reduce( + const [good, bad] = agents.reduce( (acc, agent) => { if ( agent.status === ServiceAgentStatus.RUNNING || @@ -24,17 +24,15 @@ export const StatusBadge: FC = ({ agents, type, strippedId }) !!agent.isConnected ) { acc[0]++; - } else if (agent.status === ServiceAgentStatus.UNKNOWN || agent.status === ServiceAgentStatus.INVALID) { - acc[2]++; } else { acc[1]++; } return acc; }, - [0, 0, 0] + [0, 0] ); const percentageNotRunning = bad / totalAgents; - const badgeColor: BadgeColor = percentageNotRunning === 1 ? 'red' : percentageNotRunning === 0 ? 'green' : unknown === 0 ? 'orange' : 'gray'; + const badgeColor: BadgeColor = percentageNotRunning === 1 ? 'red' : percentageNotRunning === 0 ? 'green' : 'orange'; const textToShow = `${percentageNotRunning === 1 ? bad : good}/${totalAgents}`; const textToAppend = `${percentageNotRunning === 1 ? ' not running' : ' running'}`; From d732387b9b9fe01a4fdc0048e98231660cb77d46 Mon Sep 17 00:00:00 2001 From: Nurlan Moldomurov Date: Fri, 13 Sep 2024 13:18:17 +0300 Subject: [PATCH 05/10] PMM-13348 prettier. --- public/app/percona/inventory/Tabs/Agents.tsx | 4 ++-- public/app/percona/inventory/Tabs/Agents.utils.ts | 8 ++++++-- public/app/percona/inventory/Tabs/Services.utils.ts | 5 ++++- .../inventory/components/StatusLink/StatusLink.styles.ts | 8 ++++++-- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/public/app/percona/inventory/Tabs/Agents.tsx b/public/app/percona/inventory/Tabs/Agents.tsx index bd72dbb847f9c..d51b4502a9b6c 100644 --- a/public/app/percona/inventory/Tabs/Agents.tsx +++ b/public/app/percona/inventory/Tabs/Agents.tsx @@ -92,9 +92,9 @@ export const Agents: FC type.replace(/^\w/, (c) => c.toUpperCase()).replace(/[_-]/g, ' '); export const getAgentStatusColor = (status: ServiceAgentStatus): BadgeColor => - status === ServiceAgentStatus.STARTING || status === ServiceAgentStatus.RUNNING ? 'green' : status === ServiceAgentStatus.UNKNOWN ? 'gray' : 'red'; + status === ServiceAgentStatus.STARTING || status === ServiceAgentStatus.RUNNING + ? 'green' + : status === ServiceAgentStatus.UNKNOWN + ? 'gray' + : 'red'; export const getBadgeTextForAgentStatus = (status: ServiceAgentStatus): string => { return capitalizeText(status.replace('_', ' ')); diff --git a/public/app/percona/inventory/Tabs/Services.utils.ts b/public/app/percona/inventory/Tabs/Services.utils.ts index 6c74278a78d93..158e9aa7cc294 100644 --- a/public/app/percona/inventory/Tabs/Services.utils.ts +++ b/public/app/percona/inventory/Tabs/Services.utils.ts @@ -50,7 +50,10 @@ export const getAgentsMonitoringStatus = (agents: DbAgent[]) => { console.log('allAgentsOk', allAgentsOk); const hasUnknownAgents = agents?.some( (agent) => - agent.agentType !== "pmm-agent" && (agent.status === ServiceAgentStatus.UNKNOWN || agent.status === ServiceAgentStatus.INVALID || agent.status === undefined) + agent.agentType !== 'pmm-agent' && + (agent.status === ServiceAgentStatus.UNKNOWN || + agent.status === ServiceAgentStatus.INVALID || + agent.status === undefined) ); console.log('hasUnknownAgents', hasUnknownAgents); diff --git a/public/app/percona/inventory/components/StatusLink/StatusLink.styles.ts b/public/app/percona/inventory/components/StatusLink/StatusLink.styles.ts index 7941c3eb67708..3f1fb28c62d0f 100644 --- a/public/app/percona/inventory/components/StatusLink/StatusLink.styles.ts +++ b/public/app/percona/inventory/components/StatusLink/StatusLink.styles.ts @@ -1,11 +1,15 @@ import { css } from '@emotion/css'; import { GrafanaTheme2 } from '@grafana/data'; -import { MonitoringStatus } from "app/percona/inventory/Inventory.types"; +import { MonitoringStatus } from 'app/percona/inventory/Inventory.types'; export const getStyles = ({ visualization }: GrafanaTheme2, status: string | undefined) => ({ link: css` text-decoration: underline; - color: ${status === MonitoringStatus.OK ? visualization.getColorByName('green') : status === MonitoringStatus.FAILED ? visualization.getColorByName('red') : visualization.getColorByName('gray')}; + color: ${status === MonitoringStatus.OK + ? visualization.getColorByName('green') + : status === MonitoringStatus.FAILED + ? visualization.getColorByName('red') + : visualization.getColorByName('gray')}; `, }); From ebddfbfab081f9eb335acd73a59bad5e2683ada5 Mon Sep 17 00:00:00 2001 From: Matej Kubinec Date: Fri, 13 Sep 2024 13:12:23 +0200 Subject: [PATCH 06/10] PMM-13348 Refactoring --- .../app/percona/inventory/Inventory.types.ts | 2 +- .../percona/inventory/Tabs/Services.utils.ts | 27 ++++++++----------- .../StatusLink/StatusLink.styles.ts | 2 +- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/public/app/percona/inventory/Inventory.types.ts b/public/app/percona/inventory/Inventory.types.ts index fbc9463b24796..08ef2a611b2aa 100644 --- a/public/app/percona/inventory/Inventory.types.ts +++ b/public/app/percona/inventory/Inventory.types.ts @@ -34,7 +34,7 @@ export enum AgentType { mysql = 'mysql', mysqldExporter = 'mysqldExporter', nodeExporter = 'nodeExporter', - pmmAgent = 'pmm_agent', + pmmAgent = 'pmm-agent', postgresExporter = 'postgresExporter', postgresql = 'postgresql', proxysql = 'proxysql', diff --git a/public/app/percona/inventory/Tabs/Services.utils.ts b/public/app/percona/inventory/Tabs/Services.utils.ts index 158e9aa7cc294..b696e517a34df 100644 --- a/public/app/percona/inventory/Tabs/Services.utils.ts +++ b/public/app/percona/inventory/Tabs/Services.utils.ts @@ -2,7 +2,7 @@ import { BadgeColor, IconName } from '@grafana/ui'; import { capitalizeText } from 'app/percona/shared/helpers/capitalizeText'; import { DbAgent, ServiceStatus } from 'app/percona/shared/services/services/Services.types'; -import { FlattenService, MonitoringStatus, ServiceAgentStatus } from '../Inventory.types'; +import { AgentType, FlattenService, MonitoringStatus, ServiceAgentStatus } from '../Inventory.types'; import { stripNodeId } from './Nodes.utils'; @@ -43,24 +43,19 @@ export const getBadgeTextForServiceStatus = (status: ServiceStatus): string => { }; export const getAgentsMonitoringStatus = (agents: DbAgent[]) => { - const allAgentsOk = agents?.every( - (agent) => - agent.status === ServiceAgentStatus.RUNNING || agent.status === ServiceAgentStatus.STARTING || !!agent.isConnected - ); - console.log('allAgentsOk', allAgentsOk); - const hasUnknownAgents = agents?.some( - (agent) => - agent.agentType !== 'pmm-agent' && - (agent.status === ServiceAgentStatus.UNKNOWN || - agent.status === ServiceAgentStatus.INVALID || - agent.status === undefined) - ); - - console.log('hasUnknownAgents', hasUnknownAgents); - console.log('agents', agents); + const allAgentsOk = agents?.every(isAgentOk); + const hasUnknownAgents = agents?.some(isAgentUnknown); + return allAgentsOk ? MonitoringStatus.OK : hasUnknownAgents ? MonitoringStatus.NA : MonitoringStatus.FAILED; }; +const isAgentOk = (agent: DbAgent) => + agent.status === ServiceAgentStatus.RUNNING || agent.status === ServiceAgentStatus.STARTING || !!agent.isConnected; + +const isAgentUnknown = ({ status, agentType }: DbAgent) => + agentType !== AgentType.pmmAgent && + (status === ServiceAgentStatus.INVALID || status === ServiceAgentStatus.UNKNOWN || !status); + export const stripServiceId = (serviceId: string) => { const regex = /\/service_id\/(.*)/gm; const match = regex.exec(serviceId); diff --git a/public/app/percona/inventory/components/StatusLink/StatusLink.styles.ts b/public/app/percona/inventory/components/StatusLink/StatusLink.styles.ts index 3f1fb28c62d0f..fb2779a332c5a 100644 --- a/public/app/percona/inventory/components/StatusLink/StatusLink.styles.ts +++ b/public/app/percona/inventory/components/StatusLink/StatusLink.styles.ts @@ -3,7 +3,7 @@ import { css } from '@emotion/css'; import { GrafanaTheme2 } from '@grafana/data'; import { MonitoringStatus } from 'app/percona/inventory/Inventory.types'; -export const getStyles = ({ visualization }: GrafanaTheme2, status: string | undefined) => ({ +export const getStyles = ({ visualization }: GrafanaTheme2, status?: string) => ({ link: css` text-decoration: underline; color: ${status === MonitoringStatus.OK From 830fe5622cd7e557cf1a46295a88cf9f18c30cf2 Mon Sep 17 00:00:00 2001 From: Matej Kubinec Date: Fri, 13 Sep 2024 14:14:10 +0200 Subject: [PATCH 07/10] PMM-13348 Update StatusLink unit tests --- .../components/StatusLink/StatusLink.test.tsx | 49 +++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/public/app/percona/inventory/components/StatusLink/StatusLink.test.tsx b/public/app/percona/inventory/components/StatusLink/StatusLink.test.tsx index b04cff161770e..4ff244ccedbd2 100644 --- a/public/app/percona/inventory/components/StatusLink/StatusLink.test.tsx +++ b/public/app/percona/inventory/components/StatusLink/StatusLink.test.tsx @@ -36,6 +36,7 @@ describe('StatusLink', () => { expect(screen.getByText('OK')).toBeInTheDocument(); expect(screen.queryByText('Failed')).not.toBeInTheDocument(); }); + it('should show "Failed" if some agent is not connected', () => { const agents: DbAgent[] = [ { @@ -60,6 +61,7 @@ describe('StatusLink', () => { expect(screen.queryByText('OK')).not.toBeInTheDocument(); expect(screen.getByText('Failed')).toBeInTheDocument(); }); + it('should show "Failed" if some agent is not starting or running', () => { const agents: DbAgent[] = [ { @@ -70,9 +72,27 @@ describe('StatusLink', () => { agentId: 'agent2', status: ServiceAgentStatus.STOPPING, }, + ]; + const agentsStatus = getAgentsMonitoringStatus(agents); + render( + + + + ); + expect(screen.queryByText('OK')).not.toBeInTheDocument(); + expect(screen.queryByText('N/A')).not.toBeInTheDocument(); + expect(screen.getByText('Failed')).toBeInTheDocument(); + }); + + it('should show "N/A" if there are unknown agents', () => { + const agents: DbAgent[] = [ { - agentId: 'agent3', - isConnected: true, + agentId: 'agent1', + status: ServiceAgentStatus.RUNNING, + }, + { + agentId: 'agent2', + status: ServiceAgentStatus.UNKNOWN, }, ]; const agentsStatus = getAgentsMonitoringStatus(agents); @@ -82,6 +102,29 @@ describe('StatusLink', () => { ); expect(screen.queryByText('OK')).not.toBeInTheDocument(); - expect(screen.getByText('Failed')).toBeInTheDocument(); + expect(screen.queryByText('Failed')).not.toBeInTheDocument(); + expect(screen.getByText('N/A')).toBeInTheDocument(); + }); + + it('should show "N/A" if there are invalid agents', () => { + const agents: DbAgent[] = [ + { + agentId: 'agent1', + status: ServiceAgentStatus.RUNNING, + }, + { + agentId: 'agent2', + status: ServiceAgentStatus.INVALID, + }, + ]; + const agentsStatus = getAgentsMonitoringStatus(agents); + render( + + + + ); + expect(screen.queryByText('OK')).not.toBeInTheDocument(); + expect(screen.queryByText('Failed')).not.toBeInTheDocument(); + expect(screen.getByText('N/A')).toBeInTheDocument(); }); }); From 56ee5257c9ff15485ce0cd678ec1e6ec1ffbbd0a Mon Sep 17 00:00:00 2001 From: Matej Kubinec Date: Fri, 13 Sep 2024 14:26:38 +0200 Subject: [PATCH 08/10] PMM-13348 Update status handling for disconnected agents --- .../components/StatusLink/StatusLink.test.tsx | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/public/app/percona/inventory/components/StatusLink/StatusLink.test.tsx b/public/app/percona/inventory/components/StatusLink/StatusLink.test.tsx index 4ff244ccedbd2..c457cbaf63b0e 100644 --- a/public/app/percona/inventory/components/StatusLink/StatusLink.test.tsx +++ b/public/app/percona/inventory/components/StatusLink/StatusLink.test.tsx @@ -5,7 +5,7 @@ import { Router } from 'react-router-dom'; import { locationService } from '@grafana/runtime'; import { DbAgent } from 'app/percona/shared/services/services/Services.types'; -import { ServiceAgentStatus } from '../../Inventory.types'; +import { AgentType, ServiceAgentStatus } from '../../Inventory.types'; import { getAgentsMonitoringStatus } from '../../Tabs/Services.utils'; import { StatusLink } from './StatusLink'; @@ -49,6 +49,7 @@ describe('StatusLink', () => { }, { agentId: 'agent3', + agentType: AgentType.pmmAgent, isConnected: false, }, ]; @@ -59,9 +60,37 @@ describe('StatusLink', () => { ); expect(screen.queryByText('OK')).not.toBeInTheDocument(); + expect(screen.queryByText('N/A')).not.toBeInTheDocument(); expect(screen.getByText('Failed')).toBeInTheDocument(); }); + it('should show "N/A" if some agent is not connected and is an external exporter', () => { + const agents: DbAgent[] = [ + { + agentId: 'agent1', + status: ServiceAgentStatus.RUNNING, + }, + { + agentId: 'agent2', + status: ServiceAgentStatus.STARTING, + }, + { + agentId: 'agent3', + agentType: AgentType.externalExporter, + isConnected: false, + }, + ]; + const agentsStatus = getAgentsMonitoringStatus(agents); + render( + + + + ); + expect(screen.queryByText('OK')).not.toBeInTheDocument(); + expect(screen.queryByText('Failed')).not.toBeInTheDocument(); + expect(screen.getByText('N/A')).toBeInTheDocument(); + }); + it('should show "Failed" if some agent is not starting or running', () => { const agents: DbAgent[] = [ { From c2e77e2144766773f42e6d6d7993c2a84324ffe3 Mon Sep 17 00:00:00 2001 From: Nurlan Moldomurov Date: Mon, 16 Sep 2024 12:27:51 +0300 Subject: [PATCH 09/10] PMM-13348 more test cases. --- .../percona/inventory/Tabs/Services.utils.ts | 2 +- .../components/StatusLink/StatusLink.test.tsx | 54 ++++++++++++++++++- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/public/app/percona/inventory/Tabs/Services.utils.ts b/public/app/percona/inventory/Tabs/Services.utils.ts index b696e517a34df..e45d3b91f1d94 100644 --- a/public/app/percona/inventory/Tabs/Services.utils.ts +++ b/public/app/percona/inventory/Tabs/Services.utils.ts @@ -53,7 +53,7 @@ const isAgentOk = (agent: DbAgent) => agent.status === ServiceAgentStatus.RUNNING || agent.status === ServiceAgentStatus.STARTING || !!agent.isConnected; const isAgentUnknown = ({ status, agentType }: DbAgent) => - agentType !== AgentType.pmmAgent && + agentType === AgentType.externalExporter && (status === ServiceAgentStatus.INVALID || status === ServiceAgentStatus.UNKNOWN || !status); export const stripServiceId = (serviceId: string) => { diff --git a/public/app/percona/inventory/components/StatusLink/StatusLink.test.tsx b/public/app/percona/inventory/components/StatusLink/StatusLink.test.tsx index c457cbaf63b0e..605c55123c29d 100644 --- a/public/app/percona/inventory/components/StatusLink/StatusLink.test.tsx +++ b/public/app/percona/inventory/components/StatusLink/StatusLink.test.tsx @@ -77,7 +77,6 @@ describe('StatusLink', () => { { agentId: 'agent3', agentType: AgentType.externalExporter, - isConnected: false, }, ]; const agentsStatus = getAgentsMonitoringStatus(agents); @@ -101,6 +100,10 @@ describe('StatusLink', () => { agentId: 'agent2', status: ServiceAgentStatus.STOPPING, }, + { + agentId: 'agent3', + agentType: AgentType.mongodbExporter, + } ]; const agentsStatus = getAgentsMonitoringStatus(agents); render( @@ -121,6 +124,7 @@ describe('StatusLink', () => { }, { agentId: 'agent2', + agentType: AgentType.externalExporter, status: ServiceAgentStatus.UNKNOWN, }, ]; @@ -135,7 +139,30 @@ describe('StatusLink', () => { expect(screen.getByText('N/A')).toBeInTheDocument(); }); - it('should show "N/A" if there are invalid agents', () => { + it('should show "Failed" if there are invalid agents', () => { + const agents: DbAgent[] = [ + { + agentId: 'agent1', + status: ServiceAgentStatus.RUNNING, + }, + { + agentId: 'agent2', + agentType: AgentType.mysqldExporter, + status: ServiceAgentStatus.INVALID, + }, + ]; + const agentsStatus = getAgentsMonitoringStatus(agents); + render( + + + + ); + expect(screen.queryByText('OK')).not.toBeInTheDocument(); + expect(screen.queryByText('Failed')).toBeInTheDocument(); + expect(screen.queryByText('N/A')).not.toBeInTheDocument(); + }); + + it('should show "N/A" if there are invalid external agents', () => { const agents: DbAgent[] = [ { agentId: 'agent1', @@ -143,6 +170,7 @@ describe('StatusLink', () => { }, { agentId: 'agent2', + agentType: AgentType.externalExporter, status: ServiceAgentStatus.INVALID, }, ]; @@ -156,4 +184,26 @@ describe('StatusLink', () => { expect(screen.queryByText('Failed')).not.toBeInTheDocument(); expect(screen.getByText('N/A')).toBeInTheDocument(); }); + + it('should show "N/A" if there are external agents with no status', () => { + const agents: DbAgent[] = [ + { + agentId: 'agent1', + status: ServiceAgentStatus.RUNNING, + }, + { + agentId: 'agent2', + agentType: AgentType.externalExporter, + }, + ]; + const agentsStatus = getAgentsMonitoringStatus(agents); + render( + + + + ); + expect(screen.queryByText('OK')).not.toBeInTheDocument(); + expect(screen.queryByText('Failed')).not.toBeInTheDocument(); + expect(screen.getByText('N/A')).toBeInTheDocument(); + }); }); From e37e9e99f58e87be5f6b34c112eaa5934740f894 Mon Sep 17 00:00:00 2001 From: Nurlan Moldomurov Date: Mon, 16 Sep 2024 12:32:09 +0300 Subject: [PATCH 10/10] PMM-13348 prettify. --- .../percona/inventory/components/StatusLink/StatusLink.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/percona/inventory/components/StatusLink/StatusLink.test.tsx b/public/app/percona/inventory/components/StatusLink/StatusLink.test.tsx index 605c55123c29d..4d59433cd7c7f 100644 --- a/public/app/percona/inventory/components/StatusLink/StatusLink.test.tsx +++ b/public/app/percona/inventory/components/StatusLink/StatusLink.test.tsx @@ -103,7 +103,7 @@ describe('StatusLink', () => { { agentId: 'agent3', agentType: AgentType.mongodbExporter, - } + }, ]; const agentsStatus = getAgentsMonitoringStatus(agents); render(