-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ClusterInfo): add slo logs link (#1850)
- Loading branch information
1 parent
e99b217
commit 7e0429b
Showing
6 changed files
with
209 additions
and
124 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
51 changes: 51 additions & 0 deletions
51
src/containers/Cluster/ClusterInfo/utils/__tests__/prepareLinks.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import {prepareClusterCoresLink, prepareClusterLoggingLinks} from '../useClusterLinks'; | ||
|
||
describe('prepareClusterCoresLink', () => { | ||
it('It should parse stringified json with cores url', () => { | ||
expect( | ||
prepareClusterCoresLink('{"url":"https://coredumps.com?cluster=my_cluster"}'), | ||
).toEqual('https://coredumps.com?cluster=my_cluster'); | ||
}); | ||
|
||
it('It should return undefined if input is undefined', () => { | ||
expect(prepareClusterCoresLink(undefined)).toEqual(undefined); | ||
}); | ||
it('It should return undefined if input is incorrect', () => { | ||
expect(prepareClusterCoresLink('hello')).toEqual(undefined); | ||
}); | ||
}); | ||
|
||
describe('prepareClusterLoggingLinks', () => { | ||
it('It should parse stringified json with logging and slo logs urls', () => { | ||
expect( | ||
prepareClusterLoggingLinks( | ||
'{"url":"https://logging.com/logs?cluster=my_cluster","slo_logs_url":"https://logging.com/slo-logs?cluster=my_cluster"}', | ||
), | ||
).toEqual({ | ||
logsUrl: 'https://logging.com/logs?cluster=my_cluster', | ||
sloLogsUrl: 'https://logging.com/slo-logs?cluster=my_cluster', | ||
}); | ||
}); | ||
it('It should parse stringified json with only logging url', () => { | ||
expect( | ||
prepareClusterLoggingLinks('{"url":"https://logging.com/logs?cluster=my_cluster"}'), | ||
).toEqual({ | ||
logsUrl: 'https://logging.com/logs?cluster=my_cluster', | ||
}); | ||
}); | ||
it('It should parse stringified json with only slo logs url', () => { | ||
expect( | ||
prepareClusterLoggingLinks( | ||
'{"slo_logs_url":"https://logging.com/slo-logs?cluster=my_cluster"}', | ||
), | ||
).toEqual({ | ||
sloLogsUrl: 'https://logging.com/slo-logs?cluster=my_cluster', | ||
}); | ||
}); | ||
it('It should return empty object if input is undefined', () => { | ||
expect(prepareClusterLoggingLinks(undefined)).toEqual({}); | ||
}); | ||
it('It should return empty object if input is incorrect', () => { | ||
expect(prepareClusterLoggingLinks('hello')).toEqual({}); | ||
}); | ||
}); |
83 changes: 83 additions & 0 deletions
83
src/containers/Cluster/ClusterInfo/utils/useClusterLinks.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import React from 'react'; | ||
|
||
import {useClusterBaseInfo} from '../../../../store/reducers/cluster/cluster'; | ||
import type {ClusterLink} from '../../../../types/additionalProps'; | ||
import {parseJson} from '../../../../utils/utils'; | ||
import i18n from '../../i18n'; | ||
|
||
/** | ||
* parses stringified json in format {url: "href"} | ||
*/ | ||
export function prepareClusterCoresLink(rawCoresString?: string) { | ||
try { | ||
const linkObject = parseJson(rawCoresString) as unknown; | ||
|
||
if ( | ||
linkObject && | ||
typeof linkObject === 'object' && | ||
'url' in linkObject && | ||
typeof linkObject.url === 'string' | ||
) { | ||
return linkObject.url; | ||
} | ||
} catch {} | ||
|
||
return undefined; | ||
} | ||
|
||
/** | ||
* parses stringified json in format {url: "href", slo_logs_url: "href"} | ||
*/ | ||
export function prepareClusterLoggingLinks(rawLoggingString?: string) { | ||
try { | ||
const linkObject = parseJson(rawLoggingString) as unknown; | ||
|
||
if (linkObject && typeof linkObject === 'object') { | ||
const logsUrl = | ||
'url' in linkObject && typeof linkObject.url === 'string' | ||
? linkObject.url | ||
: undefined; | ||
const sloLogsUrl = | ||
'slo_logs_url' in linkObject && typeof linkObject.slo_logs_url === 'string' | ||
? linkObject.slo_logs_url | ||
: undefined; | ||
return {logsUrl, sloLogsUrl}; | ||
} | ||
} catch {} | ||
|
||
return {}; | ||
} | ||
|
||
export function useClusterLinks() { | ||
const {cores, logging} = useClusterBaseInfo(); | ||
|
||
return React.useMemo(() => { | ||
const result: ClusterLink[] = []; | ||
|
||
const coresUrl = prepareClusterCoresLink(cores); | ||
const {logsUrl, sloLogsUrl} = prepareClusterLoggingLinks(logging); | ||
|
||
if (coresUrl) { | ||
result.push({ | ||
title: i18n('link_cores'), | ||
url: coresUrl, | ||
}); | ||
} | ||
|
||
if (logsUrl) { | ||
result.push({ | ||
title: i18n('link_logging'), | ||
url: logsUrl, | ||
}); | ||
} | ||
|
||
if (sloLogsUrl) { | ||
result.push({ | ||
title: i18n('link_slo-logs'), | ||
url: sloLogsUrl, | ||
}); | ||
} | ||
|
||
return result; | ||
}, [cores, logging]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import React from 'react'; | ||
|
||
import {Flex} from '@gravity-ui/uikit'; | ||
|
||
import {ProgressViewer} from '../../../../components/ProgressViewer/ProgressViewer'; | ||
import {Tags} from '../../../../components/Tags'; | ||
import {isClusterInfoV2} from '../../../../types/api/cluster'; | ||
import type {TClusterInfo} from '../../../../types/api/cluster'; | ||
import type {EFlag} from '../../../../types/api/enums'; | ||
import type {InfoItem} from '../../../../types/components'; | ||
import {formatNumber} from '../../../../utils/dataFormatters/dataFormatters'; | ||
import i18n from '../../i18n'; | ||
import {NodesState} from '../components/NodesState/NodesState'; | ||
import {b} from '../shared'; | ||
|
||
const COLORS_PRIORITY: Record<EFlag, number> = { | ||
Green: 5, | ||
Blue: 4, | ||
Yellow: 3, | ||
Orange: 2, | ||
Red: 1, | ||
Grey: 0, | ||
}; | ||
|
||
const getDCInfo = (cluster: TClusterInfo) => { | ||
if (isClusterInfoV2(cluster) && cluster.MapDataCenters) { | ||
return Object.entries(cluster.MapDataCenters).map(([dc, count]) => ( | ||
<React.Fragment key={dc}> | ||
{dc}: {formatNumber(count)} | ||
</React.Fragment> | ||
)); | ||
} | ||
return undefined; | ||
}; | ||
|
||
export const getInfo = (cluster: TClusterInfo, additionalInfo: InfoItem[]) => { | ||
const info: InfoItem[] = []; | ||
|
||
if (isClusterInfoV2(cluster) && cluster.MapNodeStates) { | ||
const arrayNodesStates = Object.entries(cluster.MapNodeStates) as [EFlag, number][]; | ||
// sort stack to achieve order "green, orange, yellow, red, blue, grey" | ||
arrayNodesStates.sort((a, b) => COLORS_PRIORITY[b[0]] - COLORS_PRIORITY[a[0]]); | ||
const nodesStates = arrayNodesStates.map(([state, count]) => { | ||
return ( | ||
<NodesState state={state as EFlag} key={state}> | ||
{formatNumber(count)} | ||
</NodesState> | ||
); | ||
}); | ||
info.push({ | ||
label: i18n('label_nodes-state'), | ||
value: <Flex gap={2}>{nodesStates}</Flex>, | ||
}); | ||
} | ||
|
||
const dataCenters = getDCInfo(cluster); | ||
if (dataCenters?.length) { | ||
info.push({ | ||
label: i18n('label_dc'), | ||
value: <Tags tags={dataCenters} gap={2} className={b('dc')} />, | ||
}); | ||
} | ||
|
||
info.push({ | ||
label: i18n('label_load'), | ||
value: <ProgressViewer value={cluster?.LoadAverage} capacity={cluster?.NumberOfCpus} />, | ||
}); | ||
|
||
info.push(...additionalInfo); | ||
|
||
return info; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters