-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Top n queries configuration page (#8)
* Add 2 tabs to home screen Signed-off-by: Emily Guo <[email protected]> * two tabs for query insights and configuration Signed-off-by: Emily Guo <[email protected]> * Breadcrumbs + restructuring Signed-off-by: Emily Guo <[email protected]> * Top n queries table + search Signed-off-by: Emily Guo <[email protected]> * search in general Signed-off-by: Emily Guo <[email protected]> * Search includes indices and time selection fully works Signed-off-by: Emily Guo <[email protected]> * Fix tabs display Signed-off-by: Emily Guo <[email protected]> * Basic functionalities of configuration page Signed-off-by: Emily Guo <[email protected]> * Save button + cancel button working Signed-off-by: Emily Guo <[email protected]> * Fixing lint and including relevant files Signed-off-by: Emily Guo <[email protected]> * Typo Signed-off-by: Emily Guo <[email protected]> * ignore lintcache Signed-off-by: Emily Guo <[email protected]> * Delete .eslintcache Signed-off-by: Emily Guo <[email protected]> * remove commented out lines Signed-off-by: Emily Guo <[email protected]> * Update based on comments on overview page Signed-off-by: Emily Guo <[email protected]> * Rerun security check? Signed-off-by: Emily Guo <[email protected]> * Added updates to all configurations Signed-off-by: Emily Guo <[email protected]> * Updated unit test Signed-off-by: Emily Guo <[email protected]> * Fix based on comments Signed-off-by: Emily Guo <[email protected]> * Fixed lint issues Signed-off-by: Emily Guo <[email protected]> * Update TopNQueries.tsx Signed-off-by: Emily Guo <[email protected]> --------- Signed-off-by: Emily Guo <[email protected]> Signed-off-by: Emily Guo <[email protected]> Signed-off-by: Emily Guo <[email protected]>
- Loading branch information
1 parent
4987001
commit afe9a0c
Showing
3 changed files
with
7,113 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,345 @@ | ||
import React, { useMemo, useCallback, useState, useEffect } from 'react'; | ||
import { | ||
EuiBottomBar, | ||
EuiButton, | ||
EuiButtonEmpty, | ||
EuiFieldNumber, | ||
EuiFlexGrid, | ||
EuiFlexGroup, | ||
EuiFlexItem, | ||
EuiForm, | ||
EuiFormRow, | ||
EuiHealth, | ||
EuiPanel, | ||
EuiSelect, | ||
EuiSpacer, | ||
EuiSwitch, | ||
EuiText, | ||
EuiTitle, | ||
} from '@elastic/eui'; | ||
import { useHistory, useLocation } from 'react-router-dom'; | ||
import { CoreStart } from '../../../../../src/core/public'; | ||
import { QUERY_INSIGHTS, MetricSettings } from '../TopNQueries/TopNQueries'; | ||
|
||
const Configuration = ({ | ||
latencySettings, | ||
cpuSettings, | ||
memorySettings, | ||
configInfo, | ||
core, | ||
}: { | ||
latencySettings: MetricSettings; | ||
cpuSettings: MetricSettings; | ||
memorySettings: MetricSettings; | ||
configInfo: any; | ||
core: CoreStart; | ||
}) => { | ||
const metricTypes = [ | ||
{ value: 'latency', text: 'Latency' }, | ||
{ value: 'cpu', text: 'CPU' }, | ||
{ value: 'memory', text: 'Memory' }, | ||
]; | ||
|
||
const timeUnits = [ | ||
{ value: 'MINUTES', text: 'Minute(s)' }, | ||
{ value: 'HOURS', text: 'Hour(s)' }, | ||
]; | ||
|
||
const minutesOptions = [ | ||
{ value: '1', text: '1' }, | ||
{ value: '5', text: '5' }, | ||
{ value: '10', text: '10' }, | ||
{ value: '30', text: '30' }, | ||
]; | ||
|
||
const history = useHistory(); | ||
const location = useLocation(); | ||
|
||
const [metric, setMetric] = useState<'latency' | 'cpu' | 'memory'>('latency'); | ||
const [isEnabled, setIsEnabled] = useState<boolean>(false); | ||
const [topNSize, setTopNSize] = useState(latencySettings.currTopN); | ||
const [windowSize, setWindowSize] = useState(latencySettings.currWindowSize); | ||
const [time, setTime] = useState(latencySettings.currTimeUnit); | ||
|
||
const metricSettingsMap = useMemo( | ||
() => ({ | ||
latency: latencySettings, | ||
cpu: cpuSettings, | ||
memory: memorySettings, | ||
}), | ||
[latencySettings, cpuSettings, memorySettings] | ||
); | ||
|
||
const newOrReset = useCallback(() => { | ||
const currMetric = metricSettingsMap[metric]; | ||
setTopNSize(currMetric.currTopN); | ||
setWindowSize(currMetric.currWindowSize); | ||
setTime(currMetric.currTimeUnit); | ||
setIsEnabled(currMetric.isEnabled); | ||
}, [metric, metricSettingsMap]); | ||
|
||
useEffect(() => { | ||
newOrReset(); | ||
}, [newOrReset]); | ||
|
||
useEffect(() => { | ||
core.chrome.setBreadcrumbs([ | ||
{ | ||
text: 'Query insights', | ||
href: QUERY_INSIGHTS, | ||
onClick: (e) => { | ||
e.preventDefault(); | ||
history.push(QUERY_INSIGHTS); | ||
}, | ||
}, | ||
]); | ||
}, [core.chrome, history, location]); | ||
|
||
const onMetricChange = (e: any) => { | ||
setMetric(e.target.value); | ||
}; | ||
|
||
const onEnabledChange = (e: any) => { | ||
setIsEnabled(e.target.checked); | ||
}; | ||
|
||
const onTopNSizeChange = (e: React.ChangeEvent<HTMLInputElement>) => { | ||
setTopNSize(e.target.value); | ||
}; | ||
|
||
const onWindowSizeChange = ( | ||
e: React.ChangeEvent<HTMLInputElement> | React.ChangeEvent<HTMLSelectElement> | ||
) => { | ||
setWindowSize(e.target.value); | ||
}; | ||
|
||
const onTimeChange = (e: React.ChangeEvent<HTMLSelectElement>) => { | ||
setTime(e.target.value); | ||
}; | ||
|
||
const MinutesBox = () => ( | ||
<EuiSelect | ||
id="minutes" | ||
required={true} | ||
options={minutesOptions} | ||
value={windowSize} | ||
onChange={onWindowSizeChange} | ||
/> | ||
); | ||
|
||
const HoursBox = () => ( | ||
<EuiFieldNumber | ||
min={1} | ||
max={24} | ||
required={true} | ||
value={windowSize} | ||
onChange={onWindowSizeChange} | ||
/> | ||
); | ||
|
||
const WindowChoice = time === timeUnits[0].value ? MinutesBox : HoursBox; | ||
|
||
const isChanged = | ||
isEnabled !== metricSettingsMap[metric].isEnabled || | ||
topNSize !== metricSettingsMap[metric].currTopN || | ||
windowSize !== metricSettingsMap[metric].currWindowSize || | ||
time !== metricSettingsMap[metric].currTimeUnit; | ||
|
||
const isValid = (() => { | ||
const nVal = parseInt(topNSize, 10); | ||
if (nVal < 1 || nVal > 100) return false; | ||
if (time === timeUnits[0].value) return true; | ||
const windowVal = parseInt(windowSize, 10); | ||
return windowVal >= 1 && windowVal <= 24; | ||
})(); | ||
|
||
const textPadding = { lineHeight: '22px', padding: '5px 0px' }; | ||
const formRowPadding = { padding: '0px 0px 20px' }; | ||
const enabledSymb = <EuiHealth color="primary">Enabled</EuiHealth>; | ||
const disabledSymb = <EuiHealth color="default">Disabled</EuiHealth>; | ||
|
||
return ( | ||
<div> | ||
<EuiFlexGroup> | ||
<EuiFlexItem grow={6}> | ||
<EuiPanel paddingSize="m"> | ||
<EuiForm> | ||
<EuiFlexItem> | ||
<EuiTitle size="s"> | ||
<EuiText size="s"> | ||
<h2>Top n queries monitoring configuration settings</h2> | ||
</EuiText> | ||
</EuiTitle> | ||
</EuiFlexItem> | ||
<EuiFlexItem> | ||
<EuiFlexGrid columns={2} gutterSize="s" style={{ padding: '15px 0px' }}> | ||
<EuiFlexItem> | ||
<EuiText size="xs"> | ||
<h3>Metric Type</h3> | ||
</EuiText> | ||
<EuiText size="xs" style={textPadding}> | ||
Specify the metric type to set settings for. | ||
</EuiText> | ||
</EuiFlexItem> | ||
<EuiFlexItem> | ||
<EuiFormRow style={formRowPadding}> | ||
<EuiSelect | ||
id="metricType" | ||
required={true} | ||
options={metricTypes} | ||
value={metric} | ||
onChange={onMetricChange} | ||
/> | ||
</EuiFormRow> | ||
</EuiFlexItem> | ||
<EuiFlexItem> | ||
<EuiText size="xs"> | ||
<h3>Enabled</h3> | ||
</EuiText> | ||
<EuiText size="xs" style={textPadding}> | ||
{`Enable/disable top N query monitoring by ${metric}.`} | ||
</EuiText> | ||
</EuiFlexItem> | ||
<EuiFlexItem> | ||
<EuiFormRow style={formRowPadding}> | ||
<EuiFlexItem> | ||
<EuiSpacer size="s" /> | ||
<EuiSwitch label="" checked={isEnabled} onChange={onEnabledChange} /> | ||
</EuiFlexItem> | ||
</EuiFormRow> | ||
</EuiFlexItem> | ||
{isEnabled ? ( | ||
<> | ||
<EuiFlexItem> | ||
<EuiText size="xs"> | ||
<h3>Value of N (count)</h3> | ||
</EuiText> | ||
<EuiText size="xs" style={textPadding}> | ||
Specify the value of N. N is the number of queries to be collected within | ||
the window size. | ||
</EuiText> | ||
</EuiFlexItem> | ||
<EuiFlexItem> | ||
<EuiFormRow | ||
label={`${metric}.top_n_size`} | ||
helpText="Max allowed limit 100." | ||
style={formRowPadding} | ||
> | ||
<EuiFieldNumber | ||
min={1} | ||
max={100} | ||
required={isEnabled} | ||
value={topNSize} | ||
onChange={onTopNSizeChange} | ||
/> | ||
</EuiFormRow> | ||
</EuiFlexItem> | ||
<EuiFlexItem> | ||
<EuiText size="xs"> | ||
<h3>Window size</h3> | ||
</EuiText> | ||
<EuiText size="xs" style={textPadding}> | ||
The duration during which the Top N queries are collected. | ||
</EuiText> | ||
</EuiFlexItem> | ||
<EuiFlexItem> | ||
<EuiFormRow | ||
label={`${metric}.window_size`} | ||
helpText="Max allowed limit 24 hours." | ||
style={{ padding: '15px 0px 5px' }} | ||
> | ||
<EuiFlexGroup> | ||
<EuiFlexItem style={{ flexDirection: 'row' }}> | ||
<WindowChoice /> | ||
</EuiFlexItem> | ||
<EuiFlexItem> | ||
<EuiSelect | ||
id="timeUnit" | ||
required={isEnabled} | ||
options={timeUnits} | ||
value={time} | ||
onChange={onTimeChange} | ||
/> | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
</EuiFormRow> | ||
</EuiFlexItem> | ||
</> | ||
) : null} | ||
</EuiFlexGrid> | ||
</EuiFlexItem> | ||
</EuiForm> | ||
</EuiPanel> | ||
</EuiFlexItem> | ||
<EuiFlexItem grow={2}> | ||
<EuiPanel paddingSize="m" grow={false}> | ||
<EuiFlexItem> | ||
<EuiTitle size="s"> | ||
<EuiText size="s"> | ||
<h2>Statuses for configuration metrics</h2> | ||
</EuiText> | ||
</EuiTitle> | ||
</EuiFlexItem> | ||
<EuiFlexItem> | ||
<EuiFlexGroup> | ||
<EuiFlexItem> | ||
<EuiText size="m">Latency</EuiText> | ||
</EuiFlexItem> | ||
<EuiFlexItem> | ||
<EuiSpacer size="xs" /> | ||
{latencySettings.isEnabled ? enabledSymb : disabledSymb} | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
<EuiFlexGroup> | ||
<EuiFlexItem> | ||
<EuiText size="m">CPU Usage</EuiText> | ||
</EuiFlexItem> | ||
<EuiFlexItem> | ||
<EuiSpacer size="xs" /> | ||
{cpuSettings.isEnabled ? enabledSymb : disabledSymb} | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
<EuiFlexGroup> | ||
<EuiFlexItem> | ||
<EuiText size="m">Memory</EuiText> | ||
</EuiFlexItem> | ||
<EuiFlexItem> | ||
<EuiSpacer size="xs" /> | ||
{memorySettings.isEnabled ? enabledSymb : disabledSymb} | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
</EuiFlexItem> | ||
</EuiPanel> | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
{isChanged && isValid ? ( | ||
<EuiBottomBar> | ||
<EuiFlexGroup gutterSize="s" justifyContent="flexEnd"> | ||
<EuiFlexItem grow={false}> | ||
<EuiButtonEmpty color="ghost" size="s" iconType="cross" onClick={newOrReset}> | ||
Cancel | ||
</EuiButtonEmpty> | ||
</EuiFlexItem> | ||
<EuiFlexItem grow={false}> | ||
<EuiButton | ||
color="primary" | ||
fill | ||
size="s" | ||
iconType="check" | ||
onClick={() => { | ||
configInfo(false, isEnabled, metric, topNSize, windowSize, time); | ||
return history.push(QUERY_INSIGHTS); | ||
}} | ||
> | ||
Save | ||
</EuiButton> | ||
</EuiFlexItem> | ||
</EuiFlexGroup> | ||
</EuiBottomBar> | ||
) : null} | ||
</div> | ||
); | ||
}; | ||
|
||
// eslint-disable-next-line import/no-default-export | ||
export default Configuration; |
Oops, something went wrong.