Skip to content

feature: Implement Event stream for Application/Instance/Service #1472#1487

Open
ambiguous-pointer wants to merge 1 commit into
apache:developfrom
ambiguous-pointer:feature/k8s-event
Open

feature: Implement Event stream for Application/Instance/Service #1472#1487
ambiguous-pointer wants to merge 1 commit into
apache:developfrom
ambiguous-pointer:feature/k8s-event

Conversation

@ambiguous-pointer

Copy link
Copy Markdown
Contributor

This change introduces a complete event timeline feature for applications, instances, and services
based on discussion #1474 and
issue #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.

{
    "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.

…ent ingestion ([apache#1472](apache#1472))

- Add K8sEvent resource type (proto + Go spec) and store indexes
- Add K8sEventListerWatcher to watch K8s /api/v1/events via client-go
- Register K8sEventListerWatcher in Kubernetes EngineFactory
- Add /application/event, /instance/event, /service/event console API endpoints
- Add EventTimeline shared Vue component with normal/warning node styles
- Wire up event tabs for application, instance, and service detail pages
- Un-hide event tab routes in frontend router
- Add mock event handlers for development
- Add PlatformEvent resource type (platformevent_types.go) with store indexes
- Add shared platform_event_recorder utility for event recording
- Record ZK config change events (tag-route, condition-route, dynamic-config)
- Record ZK metadata events (provider/consumer metadata added/updated)
- Record Nacos instance registration/deregistration events
- Record Nacos consumer metadata change events
- Merge K8s events and Platform events into unified timeline in event query service
- Downgrade "no subscriber" log level from INFO to DEBUG to reduce log noise
@ambiguous-pointer ambiguous-pointer changed the title [Feature] Implement Event stream for Application/Instance/Service #1472 feature: Implement Event stream for Application/Instance/Service #1472 Jun 7, 2026
@sonarqubecloud

sonarqubecloud Bot commented Jun 7, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant