Speed up alerts page by not rendering collapsed details (#9005)

All this is doing is wrapping the inner alert details display with a
conditional `{open && ...}`.

This already improves https://github.com/prometheus/prometheus/issues/8548 a
lot for cases where there are many individual firing/pending alert elements
under each alerting rule.

E.g. for a list of 200 rules with ~100 alert elements each, this changed the page
render time from 30 seconds to 1s.

Signed-off-by: Julius Volz <julius.volz@gmail.com>
This commit is contained in:
Julius Volz 2021-06-28 16:14:48 +02:00 committed by GitHub
parent 67fae26b29
commit 664b391573
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -28,81 +28,85 @@ const CollapsibleAlertPanel: FC<CollapsibleAlertPanelProps> = ({ rule, showAnnot
<strong>{rule.name}</strong> ({`${rule.alerts.length} active`})
</Alert>
<Collapse isOpen={open} className="mb-2">
<pre className="alert-cell">
<code>
<div>
name: <Link to={createExpressionLink(`ALERTS{alertname="${rule.name}"}`)}>{rule.name}</Link>
</div>
<div>
expr: <Link to={createExpressionLink(rule.query)}>{rule.query}</Link>
</div>
{rule.duration > 0 && (
<div>
<div>for: {formatDuration(rule.duration * 1000)}</div>
</div>
)}
{rule.labels && Object.keys(rule.labels).length > 0 && (
<div>
<div>labels:</div>
{Object.entries(rule.labels).map(([key, value]) => (
<div className="ml-4" key={key}>
{key}: {value}
{open && (
<>
<pre className="alert-cell">
<code>
<div>
name: <Link to={createExpressionLink(`ALERTS{alertname="${rule.name}"}`)}>{rule.name}</Link>
</div>
<div>
expr: <Link to={createExpressionLink(rule.query)}>{rule.query}</Link>
</div>
{rule.duration > 0 && (
<div>
<div>for: {formatDuration(rule.duration * 1000)}</div>
</div>
))}
</div>
)}
{rule.annotations && Object.keys(rule.annotations).length > 0 && (
<div>
<div>annotations:</div>
{Object.entries(rule.annotations).map(([key, value]) => (
<div className="ml-4" key={key}>
{key}: {value}
)}
{rule.labels && Object.keys(rule.labels).length > 0 && (
<div>
<div>labels:</div>
{Object.entries(rule.labels).map(([key, value]) => (
<div className="ml-4" key={key}>
{key}: {value}
</div>
))}
</div>
))}
</div>
)}
{rule.annotations && Object.keys(rule.annotations).length > 0 && (
<div>
<div>annotations:</div>
{Object.entries(rule.annotations).map(([key, value]) => (
<div className="ml-4" key={key}>
{key}: {value}
</div>
))}
</div>
)}
</code>
</pre>
{rule.alerts.length > 0 && (
<Table bordered size="sm">
<thead>
<tr>
<th>Labels</th>
<th>State</th>
<th>Active Since</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{rule.alerts.map((alert, i) => {
return (
<Fragment key={i}>
<tr>
<td style={{ verticalAlign: 'middle' }}>
{Object.entries(alert.labels).map(([k, v], j) => {
return (
<Badge key={j} color="primary" className="mr-1">
{k}={v}
</Badge>
);
})}
</td>
<td>
<h5 className="m-0">
<Badge color={alertColors[alert.state] + ' text-uppercase'} className="px-3">
{alert.state}
</Badge>
</h5>
</td>
<td>{alert.activeAt}</td>
<td>{parsePrometheusFloat(alert.value)}</td>
</tr>
{showAnnotations && <Annotations annotations={alert.annotations} />}
</Fragment>
);
})}
</tbody>
</Table>
)}
</code>
</pre>
{rule.alerts.length > 0 && (
<Table bordered size="sm">
<thead>
<tr>
<th>Labels</th>
<th>State</th>
<th>Active Since</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{rule.alerts.map((alert, i) => {
return (
<Fragment key={i}>
<tr>
<td style={{ verticalAlign: 'middle' }}>
{Object.entries(alert.labels).map(([k, v], j) => {
return (
<Badge key={j} color="primary" className="mr-1">
{k}={v}
</Badge>
);
})}
</td>
<td>
<h5 className="m-0">
<Badge color={alertColors[alert.state] + ' text-uppercase'} className="px-3">
{alert.state}
</Badge>
</h5>
</td>
<td>{alert.activeAt}</td>
<td>{parsePrometheusFloat(alert.value)}</td>
</tr>
{showAnnotations && <Annotations annotations={alert.annotations} />}
</Fragment>
);
})}
</tbody>
</Table>
</>
)}
</Collapse>
</>