ambiguous-pointer opened a new pull request, #1487:
URL: https://github.com/apache/dubbo-admin/pull/1487

   This change introduces a complete event timeline feature for applications, 
instances, and services
     based on [discussion 
#1474](https://github.com/apache/dubbo-admin/discussions/1474) and
     [issue #1472](https://github.com/apache/dubbo-admin/issues/1472).
   
     It ingests Kubernetes events via the cluster API and records platform 
events from ZooKeeper
     and Nacos registration centers, merging them into a unified, time-sorted 
timeline with full
     frontend visualization.
   
     ---
   
     ## ๐Ÿ“Œ What's New
   
     ### Kubernetes Event Ingestion
   
     * **K8sEvent resource type**
       `K8sEventResource` with proto `K8sEvent` spec 
(`api/mesh/v1alpha1/k8s_event.proto` +
       Go generated code). Captures namespace, reason, message, type, involved 
object kind/name,
       source component/host, first/last timestamps, count, and a static 
`EventSource: "KUBERNETES"` marker.
   
     * **K8sEventListerWatcher**
       New `K8sEventListerWatcher` 
(`pkg/engine/kubernetes/listerwatcher/k8s_event.go`) watches
       `api/v1/events` across all namespaces using `client-go`'s `ListWatch` + 
`TransformFunc`.
       Registered in the K8s `EngineFactory` alongside the existing 
`PodListerWatcher`.
   
     * **K8sEvent store indexes** (`pkg/core/store/index/k8s_event.go`)
       `ByK8sEventInvolvedObjKind`, `ByK8sEventInvolvedObjName`, 
`ByK8sEventType`, `ByK8sEventSource`
       โ€” enables efficient queries by mesh, involved object, event type, and 
source.
   
     ### Platform Event Recording (ZooKeeper & Nacos)
   
     * **PlatformEvent resource type**
       `PlatformEventResource` with `PlatformEvent` spec 
(`pkg/core/resource/apis/mesh/v1alpha1/platformevent_types.go`).
       Carries `AppName`, `InstanceName`, `InstanceIP`, `ServiceName`, `Type` 
(normal/warning),
       `Message`, `Source` (Zookeeper/Nacos), `SourceType` 
(provider/consumer/config), `Category`,
       `Action`, and `EventTime`.
   
     * **Shared platform event recorder** 
(`pkg/core/discovery/subscriber/platform_event_recorder.go`)
       `recordPlatformEvent()` utility that creates `PlatformEventResource` 
instances and persists
       them directly to the store via 
`storeRouter.ResourceKindRoute(PlatformEventKind)`.
   
     * **ZooKeeper config change events**
       `ZKConfigEventSubscriber` (`pkg/core/discovery/subscriber/zk_config.go`) 
records
       `tag-route`, `condition-route`, and `dynamic-config` 
added/updated/deleted events
       via `recordConfigPlatformEvent()`.
   
     * **ZooKeeper metadata change events**
       `ZKMetadataEventSubscriber` 
(`pkg/core/discovery/subscriber/zk_metadata.go`) records
       provider and consumer metadata added/updated events via 
`recordMetadataPlatformEvent()`.
   
     * **Nacos instance registration/deregistration events**
       `NacosServiceEventSubscriber` 
(`pkg/core/discovery/subscriber/nacos_service.go`)
       records `Nacos instance registered`, `deregistered`, and `updated` 
events with
       application name, IP, and port via `recordNacosInstanceEvents()`.
   
     * **Nacos consumer metadata change events**
       Same subscriber records `Nacos consumer metadata added` / `updated` 
events
       via `recordNacosConsumerEvents()`.
   
     * **PlatformEvent store indexes** 
(`pkg/core/store/index/platform_event.go`)
       `ByPlatformEventAppName`, `ByPlatformEventInstanceName`, 
`ByPlatformEventInstanceIP`,
       `ByPlatformEventServiceName`, `ByPlatformEventSourceType` โ€” enables 
per-entity event queries.
   
     ### Unified Event Timeline Query Service
   
     * **Console API endpoints** (`pkg/console/service/event.go`)
   
     | Endpoint | Description |
     |---|---|
     | `GET /application/event` | Lists K8s + Platform events for an 
application |
     | `GET /instance/event` | Lists K8s + Platform events for an instance (by 
name/IP) |
     | `GET /service/event` | Lists K8s + Platform events for a service |
   
     Each endpoint queries both `K8sEvent` and `PlatformEvent` stores in 
parallel,
     merges results, sorts by time descending, and returns paginated unified 
timeline entries.
   
     ```json
     {
         "code": "Success",
         "message": "success",
         "data": {
             "list": [
                 {
                     "time": "2026-06-07 17:39:14",
                     "type": "warning",
                     "message": "Error updating Endpoint Slices...",
                     "source": "endpoint-slice-controller"
                 },
                 {
                     "time": "2026-06-07 10:25:04",
                     "type": "normal",
                     "message": "Zookeeper provider metadata added: demo-app โ†’ 
com.example.TestService",
                     "source": "Zookeeper"
                 },
                 {
                     "time": "2026-06-07 10:25:05",
                     "type": "normal",
                     "message": "Nacos instance registered: shop-order 
10.244.1.29:20882",
                     "source": "Nacos"
                 }
             ],
             "total": 78
         }
     }
     ```
   
     ### Frontend Event Timeline Visualization
   
     * **EventTimeline shared component** 
(`ui-vue3/src/components/EventTimeline.vue`)
       Reusable Vue component with alternating left/right timeline layout using 
Ant Design.
       Each event node displays: timestamp, icon (check-circle for normal, 
warning for warnings),
       message text, and source tag. Supports infinite scroll with "load more" 
pagination.
       Degraded/expired events show an empty state with "่ฟ‡ๆœŸไบ‹ไปถไธไผšๅญ˜ๅ‚จ" (expired 
events
       are not stored) watermark.
   
     * **Application event tab** 
(`ui-vue3/src/views/resources/applications/tabs/event.vue`)
       Wires the EventTimeline component into the application detail page as an 
"ไบ‹ไปถ" tab.
       Queries events filtered by `appName` and current `mesh`.
   
     * **Instance event tab** 
(`ui-vue3/src/views/resources/instances/tabs/event.vue`)
       Wires the EventTimeline component into the instance detail page as an 
"ไบ‹ไปถ" tab.
       Queries events filtered by `instanceName` and `instanceIP`.
   
     * **Service event tab** 
(`ui-vue3/src/views/resources/services/tabs/event.vue`)
       Wires the EventTimeline component into the service detail page as an 
"ไบ‹ไปถ" tab.
       Queries events filtered by `serviceName`.
   
     * **Event tab restored in routes** (`ui-vue3/src/router/defaultRoutes.ts`)
       Event tab routes previously commented out are now enabled for all three 
resource types.
   
     ### Minor Improvements
   
     * **EventBus log level** (`pkg/core/events/component.go`)
       "no subscriber for resource" message downgraded from `INFO` to `DEBUG` 
to reduce
       log noise (991 occurrences per 5 minutes for `K8sEvent` and `Service`).
   
     ---
   
     ## ๐Ÿ“ Affected Areas / Review Checklist
   
     | Area | Files | What to Review |
     |---|---|---|
     | API | `api/mesh/v1alpha1/k8s_event.go`, `k8s_event.proto` | New proto + 
generated code for K8sEvent |
     | Console API | `pkg/console/service/event.go`, `handler/event.go`, 
`model/event.go`, `router/router.go` | Event query logic, merge + sort + 
pagination |
     | Core Component | `pkg/core/events/component.go` | Log level change |
     | Core Component | 
`pkg/core/resource/apis/mesh/v1alpha1/k8sevent_types.go`, 
`platformevent_types.go` | Resource type definitions |
     | Core Component | `pkg/core/store/index/k8s_event.go`, 
`platform_event.go` | Index definitions for queries |
     | Discovery Subscriber | `pkg/core/discovery/subscriber/nacos_service.go`, 
`zk_config.go`, `zk_metadata.go` | PlatformEvent recording side-effects |
     | Discovery Subscriber | 
`pkg/core/discovery/subscriber/platform_event_recorder.go` | Shared recording 
utility |
     | Engine | `pkg/engine/kubernetes/factory.go`, 
`listerwatcher/k8s_event.go` | K8s Event ListWatcher registration + transform |
     | Frontend | `ui-vue3/src/components/EventTimeline.vue` | Reusable 
timeline component |
     | Frontend | 
`ui-vue3/src/views/resources/{applications,instances,services}/tabs/event.vue` 
| Event tab pages |
     | Frontend | `ui-vue3/src/api/service/{app,instance,service}.ts` | Event 
API calls |
     | Frontend | `ui-vue3/src/router/defaultRoutes.ts` | Route restoration |
     | Frontend | `ui-vue3/src/types/api.ts` | EventItem type definition |
   
     ---
   
     ## ๐Ÿ”„ Data Flow Architecture
   
     ```
     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
     โ”‚ K8s API      โ”‚   โ”‚ ZK /services/*   โ”‚   โ”‚ Nacos naming    โ”‚
     โ”‚ /api/v1/     โ”‚   โ”‚ /dubbo/metadata/ โ”‚   โ”‚ service list    โ”‚
     โ”‚ events       โ”‚   โ”‚ /dubbo/config/   โ”‚   โ”‚ / config page   โ”‚
     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
            โ”‚                    โ”‚                      โ”‚
            โ–ผ                    โ–ผ                      โ–ผ
     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
     โ”‚ ListerWatcher (List + Watch via client-go / ZK client / โ”‚
     โ”‚               nacos-sdk-go)                             โ”‚
     โ”‚                                                         โ”‚
     โ”‚  K8sEventLW  PodLW  ZKLW(x4)  NacosLW(x6)             โ”‚
     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
                              โ–ผ
     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
     โ”‚ Informer (DeltaFIFO โ†’ Store + EventBus)                 โ”‚
     โ”‚  HandleDeltas():                                        โ”‚
     โ”‚    indexer.Add/Update/Delete(resource)  โ†’ Store         โ”‚
     โ”‚    EmitEvent()  โ†’ eventBus.Send(ResourceChangedEvent)   โ”‚
     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
                 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                 โ–ผ                         โ–ผ
     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
     โ”‚ Store (PG/Memory/  โ”‚   โ”‚ EventBus โ†’ Subscribers          โ”‚
     โ”‚  MySQL)            โ”‚   โ”‚                                 โ”‚
     โ”‚                    โ”‚   โ”‚ ZKConfigEventSubscriber         โ”‚
     โ”‚ K8sEvent           โ”‚   โ”‚   โ””โ†’ recordConfigPlatformEvent()โ”‚
     โ”‚ PlatformEvent      โ”‚   โ”‚ ZKMetadataEventSubscriber       โ”‚
     โ”‚ Application        โ”‚   โ”‚   โ””โ†’ recordMetadataPlatformEvt()โ”‚
     โ”‚ Instance           โ”‚   โ”‚ NacosServiceEventSubscriber     โ”‚
     โ”‚ Service            โ”‚   โ”‚   โ””โ†’ recordNacosInstanceEvents()โ”‚
     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚   โ””โ†’ recordNacosConsumerEvents()โ”‚
              โ”‚               โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
              โ”‚                               โ”‚
              โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
              โ”‚              โ”‚ recordPlatformEvent()        โ”‚
              โ”‚              โ”‚  โ†’ eventStore.Add(           โ”‚
              โ”‚              โ”‚      PlatformEventResource)  โ”‚
              โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
              โ”‚                             โ”‚
              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                             โ–ผ
     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
     โ”‚ Console API (event.go)                                   โ”‚
     โ”‚  ListApplicationEvents() / ListInstanceEvents() /        โ”‚
     โ”‚  ListServiceEvents()                                     โ”‚
     โ”‚                                                          โ”‚
     โ”‚  Query K8sEvent + PlatformEvent stores                   โ”‚
     โ”‚  โ†’ Merge โ†’ Sort by time DESC โ†’ Paginate                  โ”‚
     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
                              โ–ผ
     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
     โ”‚ Frontend EventTimeline.vue                               โ”‚
     โ”‚  Alternating L/R timeline with infinite scroll           โ”‚
     โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
     โ”‚  โ”‚ 2026-06-07 17:39:14                              โ”‚   โ”‚
     โ”‚  โ”‚ โš  Error updating Endpoint Slices...              โ”‚   โ”‚
     โ”‚  โ”‚                               endpoint-slice-ctrlโ”‚   โ”‚
     โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค   โ”‚
     โ”‚  โ”‚ 2026-06-07 10:25:04                              โ”‚   โ”‚
     โ”‚  โ”‚ โœ“ Zookeeper provider metadata added:             โ”‚   โ”‚
     โ”‚  โ”‚   demo-app โ†’ com.example.TestService             โ”‚   โ”‚
     โ”‚  โ”‚                                    Zookeeper     โ”‚   โ”‚
     โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
     ```
   
     ---
   
     ## ๐Ÿงช E2E Verification
   
     Tested against a 6-node kind cluster (`cluster-ha-new`, k8s v1.35.1) with:
   
     | Component | Status | Events Recorded |
     |---|---|---|
     | K8s Engine | 78 K8sEvent rows | Pod scheduling, creation, readiness 
probes, restart |
     | ZooKeeper discovery | 11 PlatformEvent rows | Consumer/provider metadata 
added/updated |
     | Nacos2 discovery | 2 PlatformEvent rows | Instance 
registered/deregistered |
     | PostgreSQL persistence | 9 PlatformEvent rows persisted across restart | 
Events survive backend restart |
     | Frontend event tabs | All 3 resource types verified | Timeline, source 
tags, icons render correctly |
     | Registry dropdown | Switching between ZK / Nacos / default mesh | Events 
filter correctly by mesh |
   
     ---
   
     ## ๐Ÿ”ฎ Known Limitations
   
     1. **K8s events use mesh "default"** โ€” K8s events are not associated with 
any discovery
        mesh. The frontend registry selector must be set to "default" (or 
unset) to view
        K8s events. There is a UX gap: the registry dropdown does not show 
"default" as an
        explicit option.
   
     2. **No event TTL / cleanup** โ€” Events accumulate indefinitely in the 
store. There is
        no retention policy, TTL, or automatic cleanup mechanism for any store 
backend.
   
     3. **No subscriber for K8sEvent and Service** โ€” K8sEvent and Service 
resources are
        stored but no event subscriber processes them (by design โ€” they only 
need storage).
        The EventBus emits a "no subscriber" debug log for these kinds.
   
     4. **PlatformEvent bypasses EventBus** โ€” PlatformEvents are created as 
side-effects
        within subscriber `ProcessEvent` methods and stored directly via
        `eventStore.Add()`, bypassing the EventBus entirely. This means 
PlatformEvents
        themselves cannot be observed by downstream subscribers.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to