feat(monitor): F6 日志告警引擎 — AlertEngine 支持 type=log 规则查询Loki/ES+触发/恢复 + 数据源认证升级(none/basic/bearer/custom) + 从查询创建告警真实API对接
This commit is contained in:
1 parent
894cb16a05
commit
6bba6144f3
17 files changed
+657
-74
No files matched your search
@@ -149,6 +149,8 @@ export function UnifiedQueryPanel({ engine, onRuleCreated }: Props) {
|
||||
|
||||
const [query, setQuery] = useState(DEFAULT_QUERIES[effEngine]);
|
||||
const [dsId, setDsId] = useState(String(sources[0]?.id || ''));
|
||||
// ES 查询允许在面板内临时覆盖索引(默认取自数据源配置)// Logan.Li
|
||||
const [esIndex, setEsIndex] = useState('');
|
||||
// API 单次查询返回条数上限(后端限制 500),Loki 用 limit / ES 用 size // Logan.Li
|
||||
const [queryLimit, setQueryLimit] = useState(200);
|
||||
const [timeRange, setTimeRange] = useState<TimeRange>(DEFAULT_TIME_RANGE);
|
||||
@@ -182,6 +184,11 @@ export function UnifiedQueryPanel({ engine, onRuleCreated }: Props) {
|
||||
}
|
||||
}, [sources]);
|
||||
|
||||
// 当前数据源变化时,同步 ES 临时索引框为数据源的默认索引 // Logan.Li
|
||||
useEffect(() => {
|
||||
setEsIndex(currentSource?.default_index || '');
|
||||
}, [currentSource]);
|
||||
|
||||
const currentSource = sources.find(s => String(s.id) === dsId);
|
||||
|
||||
const fields = useMemo(() => extractFields(entries), [entries]);
|
||||
@@ -214,6 +221,7 @@ export function UnifiedQueryPanel({ engine, onRuleCreated }: Props) {
|
||||
} else {
|
||||
result = await logCenterApi.queryElasticsearch({
|
||||
datasource_id: dsIdNum,
|
||||
index: esIndex || undefined,
|
||||
query,
|
||||
size: queryLimit,
|
||||
start: startISO,
|
||||
@@ -243,12 +251,17 @@ export function UnifiedQueryPanel({ engine, onRuleCreated }: Props) {
|
||||
setHasQueried(true);
|
||||
historyStorage.add({ engine: effEngine as LogEngine, datasourceName: currentSource.name, query, timeRange: timeRange.label, resultCount: mapped.length });
|
||||
} catch (e: any) {
|
||||
toast({ title: '查询失败', description: e?.message || String(e), variant: 'destructive' });
|
||||
const msg = e?.message || String(e);
|
||||
const title = msg.includes('401') || msg.includes('403') ? '认证失败'
|
||||
: msg.includes('404') ? '接口不存在'
|
||||
: msg.includes('无法连接') || msg.includes('timeout') ? '连接失败'
|
||||
: '查询失败';
|
||||
toast({ title, description: msg, variant: 'destructive' });
|
||||
setEntries([]); setTotalCount(0); setHasQueried(true);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [effEngine, query, currentSource, timeRange, toast, queryLimit]);
|
||||
}, [effEngine, query, currentSource, timeRange, toast, queryLimit, esIndex]);
|
||||
|
||||
const toggleField = useCallback((n: string) => setSelectedFields(p => p.includes(n) ? p.filter(f => f !== n) : [...p, n]), []);
|
||||
const handleSaveMenu = (a: 'query' | 'alert') => { setSaveMenuOpen(false); a === 'query' ? setSaveQueryOpen(true) : setSaveAlertOpen(true); };
|
||||
@@ -280,6 +293,17 @@ export function UnifiedQueryPanel({ engine, onRuleCreated }: Props) {
|
||||
{sources.map(s => <option key={s.id} value={s.id}>{s.name}{s.is_default ? ' (默认)' : ''}</option>)}
|
||||
</select>
|
||||
|
||||
{effEngine === 'elasticsearch' && (
|
||||
<input
|
||||
value={esIndex}
|
||||
onChange={e => setEsIndex(e.target.value)}
|
||||
placeholder="索引通配符"
|
||||
title="临时覆盖数据源默认索引,留空使用数据源配置"
|
||||
className="h-10 px-2 text-xs rounded flex-shrink-0 font-mono"
|
||||
style={{ width: '150px', background: 'var(--dg-bg-tertiary)', border: '1px solid var(--dg-border)', color: 'var(--dg-text-primary)' }}
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="flex items-center gap-1.5 h-10 px-2 rounded flex-shrink-0" style={{ background: 'var(--dg-bg-tertiary)', border: '1px solid var(--dg-border)' }}>
|
||||
<span className="text-xs text-[var(--dg-text-muted)]">上限</span>
|
||||
<input
|
||||
@@ -430,7 +454,7 @@ export function UnifiedQueryPanel({ engine, onRuleCreated }: Props) {
|
||||
|
||||
{/* 对话框 */}
|
||||
<SaveQueryDialog open={saveQueryOpen} onClose={() => setSaveQueryOpen(false)} engine={effEngine as LogEngine} query={query} timeRange={timeRange} datasourceName={currentSource?.name} />
|
||||
<SaveAlertDialog open={saveAlertOpen} onClose={() => setSaveAlertOpen(false)} engine={effEngine as LogEngine} query={query} datasourceName={currentSource?.name} />
|
||||
<SaveAlertDialog open={saveAlertOpen} onClose={() => setSaveAlertOpen(false)} engine={effEngine as LogEngine} query={query} datasourceId={currentSource?.id} datasourceName={currentSource?.name} />
|
||||
<QueryHistoryPanel visible={historyPanelOpen} onClose={() => setHistoryPanelOpen(false)} onSelect={(it: QueryHistoryItem) => { setQuery(it.query); setHistoryPanelOpen(false); }} onCreateAlert={() => { setSaveAlertOpen(true); setHistoryPanelOpen(false); }} />
|
||||
<LogAlertFromQueryDialog open={alertDialogOpen} onOpenChange={setAlertDialogOpen} ctx={{ engine: effEngine as LogEngine, datasourceId: currentSource?.id, datasourceName: currentSource?.name, query, timeRange: timeRange.label }} onSaved={onRuleCreated} />
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user