feat(k8s): 事件页补全时间/次数/来源等字段
- 后端解析 source/reportingComponent 与 object_kind/name - 新增 EventTable 统一展示:最后/首次时间、次数、重复跨度、类型、原因、对象、来源、消息 - Deployment 事件 Tab 与事件中心共用表格组件
This commit is contained in:
1 parent
ee2588fb52
commit
b2939470f4
8 files changed
+323
-176
No files matched your search
@@ -7,6 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
"ezops/model"
|
||||
k8sclient "ezops/pkg/kubernetesclient"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -23,31 +24,42 @@ func (h *KubernetesHandler) ListEvents(c *gin.Context) {
|
||||
if err != nil { c.JSON(500, model.Response{Code: 500, Message: "K8s API error: " + err.Error()}); return }
|
||||
|
||||
type EventSummary struct {
|
||||
Namespace string `json:"namespace"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Reason string `json:"reason"`
|
||||
Message string `json:"message"`
|
||||
Object string `json:"object"`
|
||||
Count int `json:"count"`
|
||||
FirstTime string `json:"first_time"`
|
||||
LastTime string `json:"last_time"`
|
||||
Namespace string `json:"namespace"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Reason string `json:"reason"`
|
||||
Message string `json:"message"`
|
||||
Object string `json:"object"`
|
||||
ObjectKind string `json:"object_kind"`
|
||||
ObjectName string `json:"object_name"`
|
||||
Source string `json:"source"`
|
||||
Count int `json:"count"`
|
||||
FirstTime string `json:"first_time"`
|
||||
LastTime string `json:"last_time"`
|
||||
EventTime string `json:"event_time"`
|
||||
}
|
||||
result := []EventSummary{}
|
||||
for _, e := range events.Items {
|
||||
if eventType != "" && e.Type != eventType { continue }
|
||||
object := fmt.Sprintf("%s/%s", e.InvolvedObject.Kind, e.InvolvedObject.Name)
|
||||
objectKind := e.InvolvedObject.Kind
|
||||
objectName := e.InvolvedObject.Name
|
||||
object := fmt.Sprintf("%s/%s", objectKind, objectName)
|
||||
if e.InvolvedObject.Namespace != "" {
|
||||
object = fmt.Sprintf("%s/%s/%s", e.InvolvedObject.Namespace, e.InvolvedObject.Kind, e.InvolvedObject.Name)
|
||||
object = fmt.Sprintf("%s/%s/%s", e.InvolvedObject.Namespace, objectKind, objectName)
|
||||
}
|
||||
firstTime, lastTime, eventTime := formatEventTimes(e)
|
||||
count := int(e.Count)
|
||||
if count <= 0 {
|
||||
count = 1
|
||||
}
|
||||
firstTime := ""; if !e.FirstTimestamp.IsZero() { firstTime = e.FirstTimestamp.Format(time.RFC3339) }
|
||||
lastTime := ""; if !e.LastTimestamp.IsZero() { lastTime = e.LastTimestamp.Format(time.RFC3339) }
|
||||
result = append(result, EventSummary{
|
||||
Namespace: e.Metadata.Namespace, Name: e.Metadata.Name, Type: e.Type, Reason: e.Reason,
|
||||
Message: e.Message, Object: object, Count: int(e.Count),
|
||||
FirstTime: firstTime, LastTime: lastTime,
|
||||
Message: e.Message, Object: object, ObjectKind: objectKind, ObjectName: objectName,
|
||||
Source: formatEventSource(e), Count: count,
|
||||
FirstTime: firstTime, LastTime: lastTime, EventTime: eventTime,
|
||||
})
|
||||
}
|
||||
sort.Slice(result, func(i, j int) bool { return result[i].LastTime > result[j].LastTime })
|
||||
c.JSON(200, model.Response{Code: 200, Data: result})
|
||||
}
|
||||
|
||||
@@ -122,15 +134,20 @@ func (h *KubernetesHandler) GetEventsSummary(c *gin.Context) {
|
||||
|
||||
// Collect recent warning events (top 10 by lastTimestamp)
|
||||
if len(recentWarnings) < 50 {
|
||||
firstTime, lastTime, eventTime := formatEventTimes(e)
|
||||
recentWarnings = append(recentWarnings, map[string]interface{}{
|
||||
"namespace": nsName,
|
||||
"type": e.Type,
|
||||
"reason": e.Reason,
|
||||
"message": e.Message,
|
||||
"object": fmt.Sprintf("%s/%s", e.InvolvedObject.Kind, e.InvolvedObject.Name),
|
||||
"count": count,
|
||||
"last_time": e.LastTimestamp.Format(time.RFC3339),
|
||||
"first_time": e.FirstTimestamp.Format(time.RFC3339),
|
||||
"namespace": nsName,
|
||||
"type": e.Type,
|
||||
"reason": e.Reason,
|
||||
"message": e.Message,
|
||||
"object": fmt.Sprintf("%s/%s", e.InvolvedObject.Kind, e.InvolvedObject.Name),
|
||||
"object_kind": e.InvolvedObject.Kind,
|
||||
"object_name": e.InvolvedObject.Name,
|
||||
"source": formatEventSource(e),
|
||||
"count": count,
|
||||
"last_time": lastTime,
|
||||
"first_time": firstTime,
|
||||
"event_time": eventTime,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
@@ -200,6 +217,44 @@ func (h *KubernetesHandler) GetEventsSummary(c *gin.Context) {
|
||||
c.JSON(200, model.Response{Code: 200, Data: result})
|
||||
}
|
||||
|
||||
// formatEventSource 格式化事件来源(component / reportingComponent)// Logan.Li
|
||||
func formatEventSource(e k8sclient.EventItem) string {
|
||||
if e.ReportingComponent != "" {
|
||||
if e.ReportingInstance != "" {
|
||||
return e.ReportingComponent + "/" + e.ReportingInstance
|
||||
}
|
||||
return e.ReportingComponent
|
||||
}
|
||||
src := e.Source.Component
|
||||
if e.Source.Host != "" {
|
||||
if src != "" {
|
||||
return src + "@" + e.Source.Host
|
||||
}
|
||||
return e.Source.Host
|
||||
}
|
||||
return src
|
||||
}
|
||||
|
||||
// formatEventTimes 提取首次/最后/事件时间(RFC3339)// Logan.Li
|
||||
func formatEventTimes(e k8sclient.EventItem) (first, last, eventTime string) {
|
||||
if !e.FirstTimestamp.IsZero() {
|
||||
first = e.FirstTimestamp.Format(time.RFC3339)
|
||||
}
|
||||
if !e.LastTimestamp.IsZero() {
|
||||
last = e.LastTimestamp.Format(time.RFC3339)
|
||||
}
|
||||
if !e.EventTime.IsZero() {
|
||||
eventTime = e.EventTime.Format(time.RFC3339)
|
||||
}
|
||||
if last == "" && eventTime != "" {
|
||||
last = eventTime
|
||||
}
|
||||
if first == "" && eventTime != "" {
|
||||
first = eventTime
|
||||
}
|
||||
return first, last, eventTime
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Capacity Analysis — CPU/Memory request/limit per Deployment
|
||||
// ============================================================================
|
||||
|
||||
Reference in new issue
Block a user