背景:基于 f3733f0(品牌统一 + i18n 重构)构建部署后发现,采集器 API
返回里完全没有了 targetNamespaces / appLabelSource / appInclude 三个键。
根因:重构引入了 models.SanitizedJSON() + Collector.Sanitized(),
后者是**白名单式** map 输出,写的时候这三个字段还不存在,重构时也没补进去。
controller 全部走 SanitizedJSON(collector),所以这三个字段被静默丢弃。
影响(比"少显示几个字段"严重):
编辑采集策略弹框读 collector.targetNamespaces 为 undefined
→ 命名空间面板显示"全集群采集"(实际配的是 astralx+log)
→ 用户只要点一次保存,就会把 targetNamespaces 写成 []
→ 下次「部署」生成的 Promtail 白名单消失,开始全集群采集(日志量暴涨)
appLabelSource / appInclude 同理。
修复:Collector.Sanitized() 补三个字段。
验证:
GET /api/v1/collectors/1
targetNamespaces = ['astralx', 'log'] ← 修复前该键不存在
appLabelSource = ''
appInclude = null
三个键均存在 ✅
Promtail DaemonSet 12/12 未受影响 ✅
Promtail ConfigMap 白名单(astralx, log)、app 四级回退、pod_phase drop 全部保留 ✅
镜像:lghost/lokistack:latest + v0.1 = sha256:648316ae13c5
82 lines
3.7 KiB
Go
82 lines
3.7 KiB
Go
package models
|
||
|
||
import "time"
|
||
|
||
// Collector 日志采集器(部署客户端),关联一个已部署的 Loki 作为推送目标
|
||
type Collector struct {
|
||
ID uint `json:"id"`
|
||
Name string `json:"name"`
|
||
Type string `json:"type"` // host-promtail | k8s-daemonset | k8s-fluentbit-sidecar
|
||
LokiDeploymentID uint `json:"lokiDeploymentID"`
|
||
LokiDeployment *LokiDeployment `json:"lokiDeployment,omitempty"`
|
||
RefType string `json:"refType"` // host | cluster
|
||
HostID *uint `json:"hostID,omitempty"`
|
||
Host *Host `json:"host,omitempty"`
|
||
ClusterID *uint `json:"clusterID,omitempty"`
|
||
Cluster *Cluster `json:"cluster,omitempty"`
|
||
TargetDeployment string `json:"targetDeployment"` // sidecar 专用:目标 deployment 名
|
||
Namespace string `json:"namespace"` // 采集器自身部署所在的 k8s 命名空间
|
||
// AppLabelSource 决定 app 标签从哪里取值(可填私有标签,便于按自己的规范匹配)。
|
||
// 留空 = 默认:app.kubernetes.io/name → app → Pod 的 controller_name(去 hash) → pod 名
|
||
// 可填:controller_name / app.kubernetes.io/name / app / k8s.kuboard.cn/name 等任意 Pod 标签
|
||
AppLabelSource string `json:"appLabelSource"`
|
||
// AppInclude 只采集这些 app 的日志(白名单,按 AppLabelSource 解析出的 app 值匹配)。
|
||
// 留空 = 不限制。配合 TargetNamespaces 可显著收敛日志量。
|
||
AppInclude []string `json:"appInclude"`
|
||
// TargetNamespaces 只采集这些命名空间的 Pod 日志;为空表示采集全集群。
|
||
// 对应 promtail 里 kubernetes_sd_configs.namespaces.names
|
||
TargetNamespaces []string `json:"targetNamespaces"`
|
||
LogPath string `json:"logPath"` // 采集日志路径
|
||
Labels string `json:"labels"` // 额外标签(JSON)
|
||
Status string `json:"status"` // pending | active | error
|
||
StatusMessage string `json:"statusMessage"`
|
||
Config string `json:"config"` // 生成的配置快照
|
||
CreatedAt time.Time `json:"createdAt"`
|
||
UpdatedAt time.Time `json:"updatedAt"`
|
||
}
|
||
|
||
func (c *Collector) Sanitized() map[string]interface{} {
|
||
var loki map[string]interface{}
|
||
if c.LokiDeployment != nil {
|
||
loki = map[string]interface{}{
|
||
"id": c.LokiDeployment.ID,
|
||
"name": c.LokiDeployment.Name,
|
||
"endpoint": c.LokiDeployment.Endpoint,
|
||
"status": c.LokiDeployment.Status,
|
||
}
|
||
}
|
||
var host map[string]interface{}
|
||
if c.Host != nil {
|
||
host = c.Host.Sanitized()
|
||
}
|
||
var cluster map[string]interface{}
|
||
if c.Cluster != nil {
|
||
cluster = c.Cluster.Sanitized()
|
||
}
|
||
return map[string]interface{}{
|
||
"id": c.ID,
|
||
"name": c.Name,
|
||
"type": c.Type,
|
||
"lokiDeploymentID": c.LokiDeploymentID,
|
||
"lokiDeployment": loki,
|
||
"refType": c.RefType,
|
||
"hostID": c.HostID,
|
||
"host": host,
|
||
"clusterID": c.ClusterID,
|
||
"cluster": cluster,
|
||
"targetDeployment": c.TargetDeployment,
|
||
"namespace": c.Namespace,
|
||
// 采集范围配置:必须一起输出,否则前端编辑框读不到(显示为空),
|
||
// 用户一保存就会把现有配置写空 —— 这是重构加 Sanitized() 时漏字段导致的回归。
|
||
"targetNamespaces": c.TargetNamespaces,
|
||
"appLabelSource": c.AppLabelSource,
|
||
"appInclude": c.AppInclude,
|
||
"logPath": c.LogPath,
|
||
"labels": c.Labels,
|
||
"status": c.Status,
|
||
"statusMessage": c.StatusMessage,
|
||
"createdAt": c.CreatedAt,
|
||
"updatedAt": c.UpdatedAt,
|
||
}
|
||
}
|