fix(log-center): 修复 demo 数据源、ES 502、查询页关联
This commit is contained in:
1 parent
c624ca5b4a
commit
36bd0a6155
3 files changed
+27
-13
No files matched your search
@@ -137,7 +137,9 @@ func (h *LogProxyHandler) QueryES(c *gin.Context) {
|
|||||||
if searchBody == nil {
|
if searchBody == nil {
|
||||||
searchBody = map[string]interface{}{
|
searchBody = map[string]interface{}{
|
||||||
"size": req.Size,
|
"size": req.Size,
|
||||||
"sort": []map[string]interface{}{{"@timestamp": map[string]string{"order": "desc"}}},
|
"sort": []interface{}{
|
||||||
|
map[string]interface{}{"_score": map[string]string{"order": "desc"}},
|
||||||
|
},
|
||||||
"query": map[string]interface{}{
|
"query": map[string]interface{}{
|
||||||
"bool": map[string]interface{}{
|
"bool": map[string]interface{}{
|
||||||
"must": []interface{}{
|
"must": []interface{}{
|
||||||
|
|||||||
@@ -12,10 +12,16 @@ import { logCenterApi, type LogDataSource } from '@/api/monitor/log-center';
|
|||||||
import { LogDatasourceDialog } from './LogDatasourceDialog';
|
import { LogDatasourceDialog } from './LogDatasourceDialog';
|
||||||
import type { LogEngine } from './log-center-types';
|
import type { LogEngine } from './log-center-types';
|
||||||
|
|
||||||
|
// Demo 兜底数据源(API 无数据时展示) // Logan.Li
|
||||||
|
const DEMO_FALLBACK: LogDataSource[] = [
|
||||||
|
{ id: -1, name: 'demo-loki', type: 'loki', url: '' },
|
||||||
|
{ id: -2, name: 'demo-es', type: 'elasticsearch', url: '' },
|
||||||
|
];
|
||||||
|
|
||||||
export function LogDatasourcePage() {
|
export function LogDatasourcePage() {
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const confirm = useConfirm();
|
const confirm = useConfirm();
|
||||||
const [sources, setSources] = useState<LogDataSource[]>([]);
|
const [sources, setSources] = useState<LogDataSource[]>(DEMO_FALLBACK);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [dialog, setDialog] = useState<{ open: boolean; engine: LogEngine; editing?: LogDataSource | null }>({
|
const [dialog, setDialog] = useState<{ open: boolean; engine: LogEngine; editing?: LogDataSource | null }>({
|
||||||
open: false, engine: 'loki', editing: null,
|
open: false, engine: 'loki', editing: null,
|
||||||
@@ -25,9 +31,11 @@ export function LogDatasourcePage() {
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const res = await logCenterApi.listDatasources();
|
const res = await logCenterApi.listDatasources();
|
||||||
setSources(Array.isArray(res) ? res : []);
|
const apiList: LogDataSource[] = Array.isArray(res) ? res : [];
|
||||||
|
// API 有数据 → 展示真实数据源;无数据 → demo 兜底 // Logan.Li
|
||||||
|
setSources(apiList.length > 0 ? apiList : DEMO_FALLBACK);
|
||||||
} catch {
|
} catch {
|
||||||
setSources([]);
|
setSources(DEMO_FALLBACK);
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
@@ -108,28 +116,31 @@ export function LogDatasourcePage() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'actions', header: '操作', align: 'right', hideable: false,
|
key: 'actions', header: '操作', align: 'right', hideable: false,
|
||||||
render: (ds) => (
|
render: (ds) => {
|
||||||
|
const isDemo = ds.id < 0 || !ds.url;
|
||||||
|
return (
|
||||||
<div className="flex items-center justify-end gap-0.5">
|
<div className="flex items-center justify-end gap-0.5">
|
||||||
<Button variant="ghost" size="icon" className="h-7 w-7 text-[var(--dg-text-muted)] hover:text-[var(--dg-text-primary)]"
|
<Button variant="ghost" size="icon" className="h-7 w-7 text-[var(--dg-text-muted)] hover:text-[var(--dg-text-primary)]"
|
||||||
title="测试连接" onClick={() => handleTest(ds)}>
|
title={isDemo ? '模拟数据不可测试' : '测试连接'} onClick={() => !isDemo && handleTest(ds)} disabled={isDemo}>
|
||||||
<Plug className="h-3.5 w-3.5" />
|
<Plug className="h-3.5 w-3.5" />
|
||||||
</Button>
|
</Button>
|
||||||
{!ds.is_default && (
|
{!ds.is_default && (
|
||||||
<Button variant="ghost" size="icon" className="h-7 w-7 text-[var(--dg-text-muted)] hover:text-amber-400"
|
<Button variant="ghost" size="icon" className="h-7 w-7 text-[var(--dg-text-muted)] hover:text-amber-400"
|
||||||
title="设为默认" onClick={() => handleSetDefault(ds)}>
|
title={isDemo ? '模拟数据不可设置' : '设为默认'} onClick={() => !isDemo && handleSetDefault(ds)} disabled={isDemo}>
|
||||||
<Star className="h-3.5 w-3.5" />
|
<Star className="h-3.5 w-3.5" />
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<Button variant="ghost" size="icon" className="h-7 w-7 text-[var(--dg-text-muted)] hover:text-[var(--dg-text-primary)]"
|
<Button variant="ghost" size="icon" className="h-7 w-7 text-[var(--dg-text-muted)] hover:text-[var(--dg-text-primary)]"
|
||||||
title="编辑" onClick={() => handleEdit(ds)}>
|
title={isDemo ? '模拟数据不可编辑' : '编辑'} onClick={() => !isDemo && handleEdit(ds)} disabled={isDemo}>
|
||||||
<Pencil className="h-3.5 w-3.5" />
|
<Pencil className="h-3.5 w-3.5" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="ghost" size="icon" className="h-7 w-7 text-[var(--dg-text-muted)] hover:text-red-400"
|
<Button variant="ghost" size="icon" className="h-7 w-7 text-[var(--dg-text-muted)] hover:text-red-400"
|
||||||
title="删除" onClick={() => handleDelete(ds)}>
|
title={isDemo ? '模拟数据不可删除' : '删除'} onClick={() => !isDemo && handleDelete(ds)} disabled={isDemo}>
|
||||||
<Trash2 className="h-3.5 w-3.5" />
|
<Trash2 className="h-3.5 w-3.5" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
),
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -132,12 +132,13 @@ export function UnifiedQueryPanel({ engine, onRuleCreated }: Props) {
|
|||||||
const meta = ENGINE_META[effEngine];
|
const meta = ENGINE_META[effEngine];
|
||||||
const badge = ENGINE_BADGE[effEngine];
|
const badge = ENGINE_BADGE[effEngine];
|
||||||
|
|
||||||
// 从后端加载真实数据源,无数据时用 demo 兜底 // Logan.Li
|
// 从后端加载真实数据源,同时保留 demo 兜底 // Logan.Li
|
||||||
const [sources, setSources] = useState<LogDataSource[]>(DEMO_SOURCES[effEngine]);
|
const [sources, setSources] = useState<LogDataSource[]>(DEMO_SOURCES[effEngine]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
logCenterApi.listDatasources(effEngine).then((res: any) => {
|
logCenterApi.listDatasources(effEngine).then((res: any) => {
|
||||||
const list: LogDataSource[] = Array.isArray(res) ? res : (res?.list || []);
|
const list: LogDataSource[] = Array.isArray(res) ? res : (res?.list || []);
|
||||||
if (list.length > 0) setSources(list);
|
// 合并真实数据源 + demo 兜底(真实源在前) // Logan.Li
|
||||||
|
if (list.length > 0) setSources([...list, ...DEMO_SOURCES[effEngine]]);
|
||||||
else setSources(DEMO_SOURCES[effEngine]);
|
else setSources(DEMO_SOURCES[effEngine]);
|
||||||
}).catch(() => setSources(DEMO_SOURCES[effEngine]));
|
}).catch(() => setSources(DEMO_SOURCES[effEngine]));
|
||||||
}, [effEngine]);
|
}, [effEngine]);
|
||||||
@@ -277,7 +278,7 @@ export function UnifiedQueryPanel({ engine, onRuleCreated }: Props) {
|
|||||||
<TimeRangePicker value={timeRange} onChange={setTimeRange} />
|
<TimeRangePicker value={timeRange} onChange={setTimeRange} />
|
||||||
|
|
||||||
<select value={dsId} onChange={e => setDsId(e.target.value)} className="h-10 px-2 text-xs rounded flex-shrink-0" style={{ background: 'var(--dg-bg-tertiary)', border: '1px solid var(--dg-border)', color: 'var(--dg-text-primary)' }}>
|
<select value={dsId} onChange={e => setDsId(e.target.value)} className="h-10 px-2 text-xs rounded flex-shrink-0" style={{ background: 'var(--dg-bg-tertiary)', border: '1px solid var(--dg-border)', color: 'var(--dg-text-primary)' }}>
|
||||||
{sources.map(s => <option key={s.id} value={s.id}>{s.name}{isDemo ? ' (模拟)' : ''}</option>)}
|
{sources.map(s => <option key={s.id} value={s.id}>{s.name}{(s.id < 0 || !s.url) ? ' (模拟)' : ''}</option>)}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<button onClick={handleRun} disabled={loading} className="h-10 px-4 rounded text-xs font-medium text-white flex items-center gap-1.5 flex-shrink-0 transition-opacity hover:opacity-90" style={{ background: '#22c55e' }}>
|
<button onClick={handleRun} disabled={loading} className="h-10 px-4 rounded text-xs font-medium text-white flex items-center gap-1.5 flex-shrink-0 transition-opacity hover:opacity-90" style={{ background: '#22c55e' }}>
|
||||||
|
|||||||
Reference in new issue
Block a user