feat: complete Loki query, insights, settings and deployment workflows
Add the Loki query UI, access policies, ingress insights, alert and registry settings, and their backend APIs. Include the related Kubernetes deployment and collector updates required by the integrated application. Validated with go test ./..., npm run build, and npm run lint.
This commit is contained in:
1 parent
f9c6c1d826
commit
2d73661dd1
127 files changed
+8117
-2876
No files matched your search
@@ -0,0 +1,42 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
// AlertRule 日志告警规则:对选定数据源周期执行 LogQL 计数,超过阈值即通知。
|
||||
// 参照运维侧 app-alert.py 的两类模式:
|
||||
//
|
||||
// critical(出现即报,threshold=1)/ surge(突增才报,自定义阈值),统一收敛为「N 条 / 窗口 > 阈值」。
|
||||
type AlertRule struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
SourceID uint `json:"sourceId"` // LogSource
|
||||
ChannelIDs []uint `json:"channelIds"` // NotifyChannel 列表(告警扇出到多个群)
|
||||
Query string `json:"query"` // 完整 LogQL({app="x"} |= "FATAL")
|
||||
WindowMin int `json:"windowMin"` // 统计窗口(分钟)
|
||||
Threshold int `json:"threshold"` // 窗口内条数 > 阈值触发
|
||||
Enabled bool `json:"enabled"`
|
||||
CooldownMin int `json:"cooldownMin"` // 同规则告警冷却(分钟,默认 60)
|
||||
LastFiredAt time.Time `json:"lastFiredAt"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
func (r *AlertRule) Sanitized() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"id": r.ID, "name": r.Name, "sourceId": r.SourceID, "channelIds": r.ChannelIDs,
|
||||
"query": r.Query, "windowMin": r.WindowMin, "threshold": r.Threshold,
|
||||
"enabled": r.Enabled, "cooldownMin": r.CooldownMin,
|
||||
"lastFiredAt": r.LastFiredAt, "createdAt": r.CreatedAt, "updatedAt": r.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
// AlertDelivery 告警发送历史(飞书 webhook 投递记录)
|
||||
type AlertDelivery struct {
|
||||
ID uint `json:"id"`
|
||||
RuleID uint `json:"ruleId"`
|
||||
RuleName string `json:"ruleName"`
|
||||
Count int `json:"count"` // 窗口内命中条数
|
||||
Status string `json:"status"` // sent | failed | cooldown-skipped
|
||||
Reason string `json:"reason"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
}
|
||||
@@ -17,6 +17,8 @@ type LokiDeployment struct {
|
||||
Cluster *Cluster `json:"cluster,omitempty"`
|
||||
HostID *uint `json:"hostID,omitempty"`
|
||||
Host *Host `json:"host,omitempty"`
|
||||
ListenIP string `json:"listenIP,omitempty"`
|
||||
ListenPort int `json:"listenPort,omitempty"`
|
||||
Namespace string `json:"namespace"`
|
||||
StorageConfigID uint `json:"storageConfigID"`
|
||||
StorageConfig *StorageConfig `json:"storageConfig,omitempty"`
|
||||
@@ -58,6 +60,8 @@ func (d *LokiDeployment) Sanitized() map[string]interface{} {
|
||||
"mode": d.Mode,
|
||||
"clusterID": d.ClusterID,
|
||||
"hostID": d.HostID,
|
||||
"listenIP": d.ListenIP,
|
||||
"listenPort": d.ListenPort,
|
||||
"namespace": d.Namespace,
|
||||
"storageConfigID": d.StorageConfigID,
|
||||
"authEnabled": d.AuthEnabled,
|
||||
|
||||
@@ -24,6 +24,7 @@ type LogSource struct {
|
||||
Headers map[string]string `json:"headers,omitempty"`
|
||||
SkipTLSVerify bool `json:"skipTLSVerify"`
|
||||
IsDefault bool `json:"isDefault"`
|
||||
Managed bool `json:"managed"` // 平台部署自动注册(固定不可编辑)
|
||||
Access []LogSourceAccess `json:"access,omitempty"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
@@ -34,7 +35,7 @@ func (s *LogSource) Sanitized() map[string]interface{} {
|
||||
"id": s.ID, "name": s.Name, "targetType": s.TargetType,
|
||||
"clusterID": s.ClusterID, "namespace": s.Namespace, "service": s.Service, "port": s.Port,
|
||||
"url": s.URL, "authType": s.AuthType, "basicUser": s.BasicUser,
|
||||
"hasBasicPass": s.BasicPass != "", "isDefault": s.IsDefault,
|
||||
"hasBasicPass": s.BasicPass != "", "isDefault": s.IsDefault, "managed": s.Managed,
|
||||
"hasBearerToken": s.BearerToken != "", "headerNames": headerNames(s.Headers), "skipTLSVerify": s.SkipTLSVerify,
|
||||
"access": s.Access,
|
||||
"createdAt": s.CreatedAt, "updatedAt": s.UpdatedAt,
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
// NotifyChannel 通知通道:一个飞书/Lark 群机器人 webhook。
|
||||
// 支持多通道对应不同告警群(如「应用告警群」「Nginx 告警群」),告警规则各自关联。
|
||||
type NotifyChannel struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Webhook string `json:"webhook"` // ENC: 加密存储,不外发
|
||||
SigningSecret string `json:"signingSecret"` // ENC: 可选签名校验
|
||||
Enabled bool `json:"enabled"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
func (c *NotifyChannel) Sanitized() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"id": c.ID, "name": c.Name,
|
||||
"hasWebhook": c.Webhook != "", "hasSecret": c.SigningSecret != "",
|
||||
"enabled": c.Enabled, "createdAt": c.CreatedAt, "updatedAt": c.UpdatedAt,
|
||||
}
|
||||
}
|
||||
+12
-11
@@ -20,16 +20,17 @@ type StorageConfig struct {
|
||||
|
||||
func (s *StorageConfig) Sanitized() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"id": s.ID,
|
||||
"name": s.Name,
|
||||
"storageType": s.StorageType,
|
||||
"endpoint": s.Endpoint,
|
||||
"bucket": s.Bucket,
|
||||
"region": s.Region,
|
||||
"pathPrefix": s.PathPrefix,
|
||||
"insecure": s.Insecure,
|
||||
"isDefault": s.IsDefault,
|
||||
"createdAt": s.CreatedAt,
|
||||
"updatedAt": s.UpdatedAt,
|
||||
"id": s.ID,
|
||||
"name": s.Name,
|
||||
"storageType": s.StorageType,
|
||||
"endpoint": s.Endpoint,
|
||||
"bucket": s.Bucket,
|
||||
"region": s.Region,
|
||||
"pathPrefix": s.PathPrefix,
|
||||
"insecure": s.Insecure,
|
||||
"isDefault": s.IsDefault,
|
||||
"hasSecretKey": s.SecretKey != "",
|
||||
"createdAt": s.CreatedAt,
|
||||
"updatedAt": s.UpdatedAt,
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user