feat(collector): 采集命名空间多选 + app 标签来源可自定义 + app 白名单

=== 一、采集命名空间改为多选(原来只有文本输入)===
- CollectorEditDialog 重写:勾选式多选面板,从
  GET /clusters/:id/namespaces 拉取真实命名空间列表
- "所有命名空间(全集群采集)"一键全选(targetNamespaces 置空即全集群)
- 支持搜索过滤命名空间;已选数量实时显示
- 保存时为空数组 → Promtail 不加 namespaces 白名单

=== 二、app 标签取值来源可配置 ===
新增 Collector.AppLabelSource:
  留空(默认)= app.kubernetes.io/name → app → controller 名(去hash) → pod 名 四级回退
  可填任意 Pod 标签,如 app.kubernetes.io/name / app / k8s.kuboard.cn/name
  也可直接写 __meta_kubernetes_pod_label_xxx
  → 作为最高优先级插到回退链最前,其余仍兜底

模板侧新增:
  sanitizePromLabel()      标签名 → Prometheus meta label(. / 等转 _)
  promtailAppSourceLabel() 解析用户配置
  promtailAppIncludeFilter() 生成白名单 keep 规则

=== 三、app 白名单(控制采集量)===
新增 Collector.AppInclude []string:
  填了之后生成
    - source_labels: [app]
      regex: ^(app1|app2)$
      action: keep
  只保留匹配的日志流 —— 这是收敛日志量最直接的手段

service.Update 同步支持 appLabelSource / appInclude(兼容 []string 与逗号分隔字符串)。

前端 CollectorEditDialog:
  采集命名空间 = 勾选多选 + 全选
  app 标签取值来源 = 输入框 + 5 个常用值 datalist 提示
  只采集这些 app = 逗号分隔输入

镜像:lghost/lokistack:latest + v0.1 = sha256:43369d06cb28
This commit is contained in:
opsx committed 2026-10-27 03:55:13 +00:00
1 parent e006fc1a0e
commit 41633f0b38
7 files changed
+280 -33

No files matched your search

+62 -4
View File
@@ -3,6 +3,7 @@ package services
import (
"encoding/json"
"fmt"
"regexp"
"sort"
"strings"
)
@@ -196,6 +197,55 @@ extraVolumeMounts:
// PromtailDaemonsetYAML DaemonSet 模式纯 YAML 安装(SA/RBAC/ConfigMap/DaemonSet),
// 取代 helm 安装 —— 后端无需安装 helm 二进制。
// relabel 体系与主流 helm chart 对齐:namespace/pod/container/node_name + __path__ 按 pod uid 精确匹配。
// sanitizePromLabel 把 K8s 标签名转成 Prometheus/Promtail 的 meta label 片段。
//
// k8s.kuboard.cn/name → k8s_kuboard_cn_name
// app.kubernetes.io/name → app_kubernetes_io_name
func sanitizePromLabel(name string) string {
var b strings.Builder
for _, r := range strings.TrimSpace(name) {
switch {
case r >= 'a' && r <= 'z', r >= 'A' && r <= 'Z', r >= '0' && r <= '9', r == '_':
b.WriteRune(r)
default:
b.WriteRune('_')
}
}
return b.String()
}
// promtailAppSourceLabel 把用户配置的 AppLabelSource 转成 Promtail 的 meta label 名。
// 返回空串表示「用默认的四级回退链」。
func promtailAppSourceLabel(src string) string {
src = strings.TrimSpace(src)
if src == "" || src == "controller_name" {
return ""
}
if strings.HasPrefix(src, "label:") {
src = strings.TrimPrefix(src, "label:")
}
// 已经是 __meta_ 开头就直接用
if strings.HasPrefix(src, "__meta_kubernetes_") {
return src
}
return "__meta_kubernetes_pod_label_" + sanitizePromLabel(src)
}
// promtailAppIncludeFilter 生成 app 白名单的 keep 规则(为空则不限)。
func promtailAppIncludeFilter(apps []string) string {
clean := make([]string, 0, len(apps))
for _, a := range apps {
if a = strings.TrimSpace(a); a != "" {
clean = append(clean, regexp.QuoteMeta(a))
}
}
if len(clean) == 0 {
return ""
}
return fmt.Sprintf("\n - source_labels: [app]\n regex: ^(%s)$\n action: keep",
strings.Join(clean, "|"))
}
// promtailNamespaceFilter 生成 kubernetes_sd_configs 的命名空间白名单。
// namespaces 为空 → 返回空串(采集全集群所有命名空间)。
func promtailNamespaceFilter(namespaces []string) string {
@@ -218,10 +268,16 @@ func promtailNamespaceFilter(namespaces []string) string {
return b.String()
}
func PromtailDaemonsetYAML(ns, lokiURL, clusterName, labelsJSON string, targetNamespaces []string) string {
func PromtailDaemonsetYAML(ns, lokiURL, clusterName, labelsJSON string, targetNamespaces []string, appLabelSource string, appInclude []string) string {
promtailImage := ResolveImageFor("promtail", "grafana/promtail", "3.4.0")
extLabels := promtailExternalLabels(clusterName, labelsJSON)
nsFilter := promtailNamespaceFilter(targetNamespaces)
// 自定义 app 标签来源(用户可用自己注入的私有标签),插到回退链最前面
appSourceLine := ""
if lbl := promtailAppSourceLabel(appLabelSource); lbl != "" {
appSourceLine = " - " + lbl + "\n"
}
appIncludeFilter := promtailAppIncludeFilter(appInclude)
return fmt.Sprintf(`apiVersion: v1
kind: ServiceAccount
metadata:
@@ -310,8 +366,10 @@ data:
#
# 不使用 k8s.kuboard.cn/name 之类的平台私有标签:那只是 Kuboard 管理的集群才有,
# 换 Rancher/Lens/Helm/kubectl 部署的集群就不存在,会破坏通用性。
# 如集群确实有私有规范标签,可在「采集器 → 编辑」里配置 AppLabelSource,
# 它会作为最高优先级插到下面列表最前(其余仍兜底)。
- source_labels:
- __meta_kubernetes_pod_label_app_kubernetes_io_name
%s - __meta_kubernetes_pod_label_app_kubernetes_io_name
- __meta_kubernetes_pod_label_app
- __tmp_controller_name
- __meta_kubernetes_pod_name
@@ -350,7 +408,7 @@ data:
replacement: /var/log/pods/*$1/*.log
separator: /
source_labels: [__meta_kubernetes_pod_uid, __meta_kubernetes_pod_container_name]
target_label: __path__
target_label: __path__%s
---
apiVersion: apps/v1
kind: DaemonSet
@@ -424,7 +482,7 @@ spec:
- name: containers
hostPath:
path: /var/lib/docker/containers
`, ns, ns, ns, lokiURL, extLabels, nsFilter, ns, promtailImage)
`, ns, ns, ns, lokiURL, extLabels, nsFilter, appSourceLine, promtailImage, appIncludeFilter)
}
// FluentbitConfig Sidecar 模式 Fluent Bit 配置(采集 logPath,推送至 lokiHost:lokiPort)