// 日志查询纯工具(与组件分离) /** 从 LogQL 提取 {...} 选择器部分 */ export function extractSelector(query: string): string { const i = query.indexOf('{') const j = query.indexOf('}', i) return i >= 0 && j > i ? query.slice(i, j + 1) : '' } /** * 替换 LogQL 的 {...} 选择器,保留其后的管道过滤(|= "x" 等); * 原查询没有选择器时把新选择器前置到最前面 */ export function replaceSelector(query: string, nextSelector: string): string { const current = extractSelector(query) if (!current) return nextSelector + query.trim().replace(/^\{[^}]*\}/, '') const i = query.indexOf(current) return query.slice(0, i) + nextSelector + query.slice(i + current.length) } /** 从选择器里删除指定标签的所有匹配条件(=、!=、=~、!~) */ export function removeLabelFilter(query: string, key: string): string { const current = extractSelector(query) if (!current) return query const inner = current.slice(1, -1).trim() if (!inner) return query const pattern = new RegExp(`^${key}(=|!=|=~|!~)`) const kept = inner.split(',').map((s) => s.trim()).filter(Boolean).filter((p) => !pattern.test(p)) const next = kept.length ? `{${kept.join(', ')}}` : '{}' return replaceSelector(query, next) } /** 选择器里是否已包含指定标签的匹配条件 */ export function hasLabelFilter(query: string, key: string): boolean { const current = extractSelector(query) if (!current) return false return current .slice(1, -1) .split(',') .some((part) => new RegExp(`^\\s*${key}(=|!=|=~|!~)`).test(part)) } /** * 把 key="value" 合并进 LogQL 的 {...} 选择器(同名标签替换旧值);exclude=true 用 != 排除 */ export function applyLabelFilter(query: string, key: string, value: string, exclude = false): string { const op = exclude ? '!=' : '=' const frag = `${key}${op}"${value}"` const i = query.indexOf('{') if (i < 0) return `{${frag}}` const j = query.indexOf('}', i) if (j < 0) return query const inner = query.slice(i + 1, j).trim() // 同名标签(=、!=、=~、!~)替换,其余保留 const parts = inner ? inner.split(',').map((s) => s.trim()).filter(Boolean) : [] const kept = parts.filter((p) => !new RegExp(`^${key}(=|!=|=~|!~)`).test(p)) kept.push(frag) return query.slice(0, i + 1) + kept.join(', ') + query.slice(j) } /** 提取 LogQL 管道中的字面过滤词(|= "x" 与 != "y"),用于结果行高亮 */ export function literalFilters(query: string): string[] { const terms: string[] = [] const re = /\|=\s*"((?:[^"\\]|\\.)*)"/g let m: RegExpExecArray | null while ((m = re.exec(query)) !== null) { if (m[1]) terms.push(m[1].replace(/\\"/g, '"')) } return terms }