Skip to content

Commit f14840d

Browse files
authored
Merge pull request #1889 from redpanda-data/backport-2.8-ui-bundle
[2.8] UI: Custom debug bundle form improvements
2 parents 40b7bbe + ca6709d commit f14840d

File tree

1 file changed

+135
-53
lines changed

1 file changed

+135
-53
lines changed

frontend/src/components/pages/admin/Admin.DebugBundle.tsx

Lines changed: 135 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,28 @@ import { DefaultSkeleton } from '../../../utils/tsxUtils';
4848
import DebugBundleLink from '../../debugBundle/DebugBundleLink';
4949
import { SingleSelect } from '../../misc/Select';
5050

51+
// Unit mappings for consistent dropdown handling
52+
const SIZE_UNITS = [
53+
{ value: 1, label: 'Bytes' },
54+
{ value: 1024, label: 'KB' },
55+
{ value: 1024 * 1024, label: 'MB' },
56+
{ value: 1024 * 1024 * 1024, label: 'GB' },
57+
];
58+
59+
const TIME_UNITS = [
60+
{ value: 1, label: 'Seconds' },
61+
{ value: 60, label: 'Minutes' },
62+
];
63+
64+
// Helper functions to get labels from unit values
65+
const getSizeUnitLabel = (unitValue: number): string => {
66+
return SIZE_UNITS.find((unit) => unit.value === unitValue)?.label || "";
67+
};
68+
69+
const getTimeUnitLabel = (unitValue: number): string => {
70+
return TIME_UNITS.find((unit) => unit.value === unitValue)?.label || "";
71+
};
72+
5173
const Header = () => (
5274
<Text>
5375
Collect environment data that can help debug and diagnose issues with a Redpanda cluster, a broker, or the machine
@@ -185,15 +207,18 @@ const NewDebugBundleForm: FC<{
185207
brokerIds: [] as number[],
186208
tlsEnabled: false,
187209
tlsInsecureSkipVerify: false,
188-
controllerLogsSizeLimitBytes: 0 as number,
189-
cpuProfilerWaitSeconds: undefined as number | undefined,
190-
logsSince: undefined as number | undefined,
191-
logsSizeLimitBytes: 0 as number,
192-
logsSizeLimitUnit: 1,
210+
controllerLogsSizeLimitBytes: 132 as number, // Default 132MB
211+
controllerLogsSizeLimitUnit: 1024 * 1024, // Default to MB
212+
cpuProfilerWaitSeconds: 30 as number | undefined, // Default 30s
213+
cpuProfilerWaitUnit: 1, // Default to seconds
214+
logsSince: new Date().setDate(new Date().getDate() - 1) as number | undefined, // Default yesterday
215+
logsSizeLimitBytes: 100 as number, // Default 100MB
216+
logsSizeLimitUnit: 1024 * 1024, // Default to MB
193217
logsUntil: undefined as number | undefined,
194-
metricsIntervalSeconds: 0 as number,
195-
metricsSamples: '' as string,
196-
namespace: '' as string,
218+
metricsIntervalSeconds: 10 as number, // Default 10s
219+
metricsIntervalUnit: 1, // Default to seconds
220+
metricsSamples: '2' as string, // Default 2 samples
221+
namespace: 'redpanda' as string, // Default "redpanda"
197222
partitions: [] as string[],
198223
labelSelectors: [] as Array<{ key: string; value: string }>,
199224

@@ -210,9 +235,15 @@ const NewDebugBundleForm: FC<{
210235
setControllerLogsSizeLimitBytes(size: number) {
211236
this.controllerLogsSizeLimitBytes = size;
212237
},
238+
setControllerLogsSizeLimitUnit(unit: number) {
239+
this.controllerLogsSizeLimitUnit = unit;
240+
},
213241
setCpuProfilerWaitSeconds(seconds: number) {
214242
this.cpuProfilerWaitSeconds = seconds;
215243
},
244+
setCpuProfilerWaitUnit(unit: number) {
245+
this.cpuProfilerWaitUnit = unit;
246+
},
216247
setLogsSince(date: number) {
217248
this.logsSince = date;
218249
},
@@ -228,6 +259,9 @@ const NewDebugBundleForm: FC<{
228259
setMetricsIntervalSeconds(seconds: number) {
229260
this.metricsIntervalSeconds = seconds;
230261
},
262+
setMetricsIntervalUnit(unit: number) {
263+
this.metricsIntervalUnit = unit;
264+
},
231265
setMetricsSamples(samples: string) {
232266
this.metricsSamples = samples;
233267
},
@@ -270,12 +304,15 @@ const NewDebugBundleForm: FC<{
270304
}
271305
: undefined,
272306
brokerIds: formState.brokerIds,
273-
controllerLogsSizeLimitBytes: formState.controllerLogsSizeLimitBytes,
274-
cpuProfilerWaitSeconds: formState.cpuProfilerWaitSeconds,
307+
controllerLogsSizeLimitBytes:
308+
formState.controllerLogsSizeLimitBytes * formState.controllerLogsSizeLimitUnit,
309+
cpuProfilerWaitSeconds: formState.cpuProfilerWaitSeconds
310+
? formState.cpuProfilerWaitSeconds * formState.cpuProfilerWaitUnit
311+
: undefined,
275312
logsSince: formState.logsSince ? Timestamp.fromDate(new Date(formState.logsSince)) : undefined,
276313
logsSizeLimitBytes: formState.logsSizeLimitBytes * formState.logsSizeLimitUnit,
277314
logsUntil: formState.logsUntil ? Timestamp.fromDate(new Date(formState.logsUntil)) : undefined,
278-
metricsIntervalSeconds: formState.metricsIntervalSeconds,
315+
metricsIntervalSeconds: formState.metricsIntervalSeconds * formState.metricsIntervalUnit,
279316
tlsEnabled: formState.tlsEnabled,
280317
tlsInsecureSkipVerify: formState.tlsInsecureSkipVerify,
281318
namespace: formState.namespace,
@@ -368,31 +405,69 @@ const NewDebugBundleForm: FC<{
368405
</FormField>
369406
<FormField
370407
label="Controller log size limit"
371-
description={
372-
'The size limit of the controller logs that can be stored in the bundle (e.g. 3MB, 1GiB) (default "132MB")'
373-
}
408+
description='The size limit of the controller logs that can be stored in the bundle (default "132MB")'
374409
errorText={fieldViolationsMap?.controllerLogsSizeLimitBytes}
375410
isInvalid={!!fieldViolationsMap?.controllerLogsSizeLimitBytes}
376411
>
377-
<Input
378-
type="number"
379-
data-testid="controller-log-size-input"
380-
value={formState.controllerLogsSizeLimitBytes}
381-
onChange={(e) => formState.setControllerLogsSizeLimitBytes(e.target.valueAsNumber)}
382-
/>
412+
<Flex gap={2}>
413+
<Input
414+
type="number"
415+
data-testid="controller-log-size-input"
416+
value={formState.controllerLogsSizeLimitBytes}
417+
onChange={(e) => formState.setControllerLogsSizeLimitBytes(e.target.valueAsNumber)}
418+
/>
419+
<Select
420+
chakraStyles={{
421+
container: (provided) => ({
422+
...provided,
423+
minWidth: 150,
424+
}),
425+
}}
426+
options={SIZE_UNITS}
427+
value={{
428+
value: formState.controllerLogsSizeLimitUnit,
429+
label: getSizeUnitLabel(formState.controllerLogsSizeLimitUnit),
430+
}}
431+
onChange={(value) => {
432+
if (value && isSingleValue(value)) {
433+
formState.setControllerLogsSizeLimitUnit(value.value);
434+
}
435+
}}
436+
/>
437+
</Flex>
383438
</FormField>
384439
<FormField
385440
label="CPU profiler wait"
386-
description="How long in seconds to collect samples for the CPU profiler. Must be higher than 15s (default 30s)"
441+
description="How long to collect samples for the CPU profiler. Must be higher than 15s (default 30s)"
387442
errorText={fieldViolationsMap?.cpuProfilerWaitSeconds}
388443
isInvalid={!!fieldViolationsMap?.cpuProfilerWaitSeconds}
389444
>
390-
<Input
391-
data-testid="cpu-profiler-input"
392-
value={formState.cpuProfilerWaitSeconds}
393-
type="number"
394-
onChange={(e) => formState.setCpuProfilerWaitSeconds(e.target.valueAsNumber)}
395-
/>
445+
<Flex gap={2}>
446+
<Input
447+
data-testid="cpu-profiler-input"
448+
value={formState.cpuProfilerWaitSeconds}
449+
type="number"
450+
onChange={(e) => formState.setCpuProfilerWaitSeconds(e.target.valueAsNumber)}
451+
/>
452+
<Select
453+
chakraStyles={{
454+
container: (provided) => ({
455+
...provided,
456+
minWidth: 150,
457+
}),
458+
}}
459+
options={TIME_UNITS}
460+
value={{
461+
value: formState.cpuProfilerWaitUnit,
462+
label: getTimeUnitLabel(formState.cpuProfilerWaitUnit),
463+
}}
464+
onChange={(value) => {
465+
if (value && isSingleValue(value)) {
466+
formState.setCpuProfilerWaitUnit(value.value);
467+
}
468+
}}
469+
/>
470+
</Flex>
396471
</FormField>
397472
<FormField
398473
label="Logs since"
@@ -430,24 +505,11 @@ const NewDebugBundleForm: FC<{
430505
minWidth: 150,
431506
}),
432507
}}
433-
options={[
434-
{
435-
value: 1,
436-
label: 'Bytes',
437-
},
438-
{
439-
value: 1024,
440-
label: 'KB',
441-
},
442-
{
443-
value: 1024 * 1024,
444-
label: 'MB',
445-
},
446-
{
447-
value: 1024 * 1024 * 1024,
448-
label: 'GB',
449-
},
450-
]}
508+
options={SIZE_UNITS}
509+
value={{
510+
value: formState.logsSizeLimitUnit,
511+
label: getSizeUnitLabel(formState.logsSizeLimitUnit),
512+
}}
451513
onChange={(value) => {
452514
if (value && isSingleValue(value)) {
453515
formState.setLogsSizeLimitUnit(value.value);
@@ -458,16 +520,36 @@ const NewDebugBundleForm: FC<{
458520
</FormField>
459521
<FormField
460522
label="Metrics interval duration"
461-
description="Interval between metrics snapshots (e.g. 30s, 1.5m) (default 10s)"
523+
description="Interval between metrics snapshots (default 10s)"
462524
errorText={fieldViolationsMap?.metricsIntervalSeconds}
463525
isInvalid={!!fieldViolationsMap?.metricsIntervalSeconds}
464526
>
465-
<Input
466-
type="number"
467-
data-testid="metrics-interval-duration-input"
468-
value={formState.metricsIntervalSeconds}
469-
onChange={(e) => formState.setMetricsIntervalSeconds(e.target.valueAsNumber)}
470-
/>
527+
<Flex gap={2}>
528+
<Input
529+
type="number"
530+
data-testid="metrics-interval-duration-input"
531+
value={formState.metricsIntervalSeconds}
532+
onChange={(e) => formState.setMetricsIntervalSeconds(e.target.valueAsNumber)}
533+
/>
534+
<Select
535+
chakraStyles={{
536+
container: (provided) => ({
537+
...provided,
538+
minWidth: 150,
539+
}),
540+
}}
541+
options={TIME_UNITS}
542+
value={{
543+
value: formState.metricsIntervalUnit,
544+
label: getTimeUnitLabel(formState.metricsIntervalUnit),
545+
}}
546+
onChange={(value) => {
547+
if (value && isSingleValue(value)) {
548+
formState.setMetricsIntervalUnit(value.value);
549+
}
550+
}}
551+
/>
552+
</Flex>
471553
</FormField>
472554
<FormField
473555
label="Metrics samples"
@@ -495,7 +577,7 @@ const NewDebugBundleForm: FC<{
495577
</FormField>
496578
<FormField
497579
label="Partition(s)"
498-
description="Partition IDs."
580+
description="Partition ID. If set, the bundle will include extra information about the requested partitions."
499581
errorText={fieldViolationsMap?.partitions}
500582
isInvalid={!!fieldViolationsMap?.partitions}
501583
>

0 commit comments

Comments
 (0)