Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"FILTER_TOPIC": "Topic",
"FROM": "From",
"HELP": "Help",
"HEAP_DUMP": "Heap Dump",
"HOUR": "Hour",
"HOUR_one": "Hour",
"HOUR_other": "Hours",
Expand Down Expand Up @@ -96,6 +97,7 @@
"TARGET": "Target",
"TEMPLATE": "Template",
"TEST": "Test",
"THREAD_DUMP": "Thread Dump",
"TIME": "Time",
"TIMEZONE": "Timezone",
"TO": "To",
Expand Down
2 changes: 2 additions & 0 deletions locales/en/public.json
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@
"ENABLE_SWITCH_HELPER_TEXT": "Rules take effect when created if enabled and will be matched against all discovered target applications immediately. When new target applications appear they are checked against all enabled rules. Disabled rules have no effect but are available to be enabled in the future.",
"EVALUATING_EXPRESSION": "Evaluating Match Expression...",
"FAILING_EVALUATION": "The expression matching failed.",
"HEAP_DUMP_SWITCH_HELPER_TEXT": "Trigger a heap dump in all matching targets.",
"INITIAL_DELAY_HELPER_TEXT": "Initial delay before archiving starts. The first archived copy will be made this long after the Recording is started. The second archived copy will occur one Archival period later.",
"MATCH_EXPRESSION_HELPER_TEXT": "Enter a Match Expression. This is a <a>Common Expression Language (CEL)</a> code snippet that is evaluated against each target application to determine whether the rule should be applied.",
"MATCH_EXPRESSION_HINT_BODY": "Try an expression like:",
Expand All @@ -244,6 +245,7 @@
"PRESERVED_ARCHIVES_HELPER_TEXT": "The number of Archived Recording copies to preserve in archives for each target application affected by this rule.",
"TEMPLATE_HELPER_TEXT": "The Event Template to be applied by this Rule against matching target applications.",
"TEMPLATE_HINT": "A Template must be selected.",
"THREAD_DUMP_SWITCH_HELPER_TEXT": "Trigger a thread dump in all matching targets",
"WARNING_NO_MATCH": "Warning: Match Expression matches no targets."
},
"CredentialTestTable": {
Expand Down
44 changes: 44 additions & 0 deletions src/app/Rules/CreateRule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ export const CreateRuleForm: React.FC<CreateRuleFormProps> = ({ onExit }) => {
initialDelay: 0,
initialDelayUnit: 1,
preservedArchives: 0,
threaddump: false,
heapdump: false,
});
const [templates, setTemplates] = React.useState<EventTemplate[]>([]);
const [loading, setLoading] = React.useState(false);
Expand Down Expand Up @@ -238,6 +240,16 @@ export const CreateRuleForm: React.FC<CreateRuleFormProps> = ({ onExit }) => {
[setFormData],
);

const handleThreadDumpChange = React.useCallback(
(_, threaddump: boolean) => setFormData((old) => ({ ...old, threaddump })),
[setFormData],
);

const handleHeapDumpChange = React.useCallback(
(_, heapdump: boolean) => setFormData((old) => ({ ...old, heapdump })),
[setFormData],
);

const handleAutoAnalyzeChange = React.useCallback(
(_, autoanalyze: boolean) => setAutoanalyze(autoanalyze),
[setAutoanalyze],
Expand Down Expand Up @@ -308,6 +320,8 @@ export const CreateRuleForm: React.FC<CreateRuleFormProps> = ({ onExit }) => {
maxAgeUnit,
maxSize,
maxSizeUnit,
threaddump,
heapdump,
} = formData;
if (nameValid !== ValidatedOptions.success) {
notificationMessages.push(`Rule name ${name} is invalid`);
Expand Down Expand Up @@ -337,6 +351,8 @@ export const CreateRuleForm: React.FC<CreateRuleFormProps> = ({ onExit }) => {
maxAgeSeconds: maxAge * maxAgeUnit,
maxSizeBytes: maxSize * maxSizeUnit,
metadata,
threadDump: threaddump,
heapDump: heapdump,
};
setLoading(true);
addSubscription(
Expand Down Expand Up @@ -547,6 +563,34 @@ export const CreateRuleForm: React.FC<CreateRuleFormProps> = ({ onExit }) => {
</HelperText>
</FormHelperText>
</FormGroup>
<FormGroup label={t('THREAD_DUMP')} isRequired fieldId="rule-thread-dump">
<Switch
id="rule-thread-dump"
isDisabled={loading}
aria-label="Trigger a thread dump in matching targets"
isChecked={formData.threaddump}
onChange={handleThreadDumpChange}
/>
<FormHelperText>
<HelperText>
<HelperTextItem>{t('CreateRule.THREAD_DUMP_SWITCH_HELPER_TEXT')}</HelperTextItem>
</HelperText>
</FormHelperText>
</FormGroup>
<FormGroup label={t('HEAP_DUMP')} isRequired fieldId="rule-heap-dump">
<Switch
id="rule-heap-dump"
isDisabled={loading}
aria-label="Trigger a heap dump in matching targets"
isChecked={formData.heapdump}
onChange={handleHeapDumpChange}
/>
<FormHelperText>
<HelperText>
<HelperTextItem>{t('CreateRule.HEAP_DUMP_SWITCH_HELPER_TEXT')}</HelperTextItem>
</HelperText>
</FormHelperText>
</FormGroup>
<FormGroup label={t('TEMPLATE')} isRequired fieldId="recording-template" data-quickstart-id="rule-evt-template">
<SelectTemplateSelectorForm
selected={selectedSpecifier}
Expand Down
16 changes: 16 additions & 0 deletions src/app/Rules/Rules.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,16 @@ export const RulesTable: React.FC<RulesTableProps> = () => {
keyPaths: ['options'],
sortable: false,
},
{
title: t('THREAD_DUMP'),
keyPaths: ['threaddump'],
sortable: false,
},
{
title: t('HEAP_DUMP'),
keyPaths: ['dump'],
sortable: false,
},
],
[t],
);
Expand Down Expand Up @@ -438,6 +448,12 @@ export const RulesTable: React.FC<RulesTableProps> = () => {
)}
</LabelGroup>
</Td>
<Td key={`automatic-rule-threaddump-${index}`} dataLabel={tableColumns[6].title}>
{`${r.threadDump}`}
</Td>
<Td key={`automatic-rule-heapdump-${index}`} dataLabel={tableColumns[7].title}>
{`${r.heapDump}`}
</Td>
<Td key={`automatic-rule-action-${index}`} isActionCell style={{ paddingRight: '0' }}>
<ActionsColumn
items={actionResolver(r)}
Expand Down
2 changes: 2 additions & 0 deletions src/app/Rules/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ interface _FormBaseData {
initialDelay: number;
initialDelayUnit: number;
preservedArchives: number;
threaddump: boolean;
heapdump: boolean;
}

interface _FormValidationData {
Expand Down
2 changes: 2 additions & 0 deletions src/app/Shared/Services/api.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,8 @@ export interface Rule {
maxAgeSeconds: number;
maxSizeBytes: number;
metadata: Metadata;
threadDump: boolean;
heapDump: boolean;
}

// ======================================
Expand Down
2 changes: 2 additions & 0 deletions src/test/Rules/CreateRule.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,14 @@ const mockRule: Rule = {
matchExpression: "target.alias == 'io.cryostat.Cryostat' || target.annotations.cryostat['PORT'] == 9091",
enabled: true,
eventSpecifier: 'template=Profiling,type=TARGET',
heapDump: false,
archivalPeriodSeconds: 0,
initialDelaySeconds: 0,
preservedArchives: 0,
maxAgeSeconds: 0,
maxSizeBytes: 0,
metadata: { labels: [] },
threadDump: false,
};

const mockNavigate = jest.fn();
Expand Down
2 changes: 2 additions & 0 deletions src/test/Rules/Rules.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@ const mockRule: Rule = {
matchExpression: "target.alias == 'io.cryostat.Cryostat' || target.annotations.cryostat['PORT'] == 9091",
enabled: true,
eventSpecifier: 'template=Profiling,type=TARGET',
heapDump: false,
archivalPeriodSeconds: 0,
initialDelaySeconds: 0,
preservedArchives: 0,
maxAgeSeconds: 0,
maxSizeBytes: 0,
metadata: { labels: [] },
threadDump: true,
};
const mockRuleListResponse: Rule[] = [mockRule];
const mockRuleListEmptyResponse: Rule[] = [];
Expand Down
Loading