@gravito/zenith 1.1.3 → 1.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -10
- package/dist/bin.js +43235 -76691
- package/dist/client/index.html +13 -0
- package/dist/server/index.js +43235 -76691
- package/package.json +16 -7
- package/CHANGELOG.md +0 -62
- package/Dockerfile +0 -46
- package/Dockerfile.demo-worker +0 -29
- package/bin/flux-console.ts +0 -2
- package/doc/ECOSYSTEM_EXPANSION_RFC.md +0 -130
- package/docker-compose.yml +0 -40
- package/docs/ALERTING_GUIDE.md +0 -71
- package/docs/DEPLOYMENT.md +0 -157
- package/docs/DOCS_INTERNAL.md +0 -73
- package/docs/LARAVEL_ZENITH_ROADMAP.md +0 -109
- package/docs/QUASAR_MASTER_PLAN.md +0 -140
- package/docs/QUICK_TEST_GUIDE.md +0 -72
- package/docs/ROADMAP.md +0 -85
- package/docs/integrations/LARAVEL.md +0 -207
- package/postcss.config.js +0 -6
- package/scripts/debug_redis_keys.ts +0 -24
- package/scripts/flood-logs.ts +0 -21
- package/scripts/seed.ts +0 -213
- package/scripts/verify-throttle.ts +0 -49
- package/scripts/worker.ts +0 -124
- package/specs/PULSE_SPEC.md +0 -86
- package/src/bin.ts +0 -6
- package/src/client/App.tsx +0 -72
- package/src/client/Layout.tsx +0 -669
- package/src/client/Sidebar.tsx +0 -112
- package/src/client/ThroughputChart.tsx +0 -158
- package/src/client/WorkerStatus.tsx +0 -202
- package/src/client/components/BrandIcons.tsx +0 -168
- package/src/client/components/ConfirmDialog.tsx +0 -134
- package/src/client/components/JobInspector.tsx +0 -487
- package/src/client/components/LogArchiveModal.tsx +0 -432
- package/src/client/components/NotificationBell.tsx +0 -212
- package/src/client/components/PageHeader.tsx +0 -47
- package/src/client/components/Toaster.tsx +0 -90
- package/src/client/components/UserProfileDropdown.tsx +0 -186
- package/src/client/contexts/AuthContext.tsx +0 -105
- package/src/client/contexts/NotificationContext.tsx +0 -128
- package/src/client/index.css +0 -172
- package/src/client/main.tsx +0 -15
- package/src/client/pages/LoginPage.tsx +0 -164
- package/src/client/pages/MetricsPage.tsx +0 -445
- package/src/client/pages/OverviewPage.tsx +0 -519
- package/src/client/pages/PulsePage.tsx +0 -409
- package/src/client/pages/QueuesPage.tsx +0 -378
- package/src/client/pages/SchedulesPage.tsx +0 -535
- package/src/client/pages/SettingsPage.tsx +0 -1001
- package/src/client/pages/WorkersPage.tsx +0 -380
- package/src/client/pages/index.ts +0 -8
- package/src/client/utils.ts +0 -15
- package/src/server/config/ServerConfigManager.ts +0 -90
- package/src/server/index.ts +0 -860
- package/src/server/middleware/auth.ts +0 -127
- package/src/server/services/AlertService.ts +0 -321
- package/src/server/services/CommandService.ts +0 -136
- package/src/server/services/LogStreamProcessor.ts +0 -93
- package/src/server/services/MaintenanceScheduler.ts +0 -78
- package/src/server/services/PulseService.ts +0 -148
- package/src/server/services/QueueMetricsCollector.ts +0 -138
- package/src/server/services/QueueService.ts +0 -924
- package/src/shared/types.ts +0 -223
- package/tailwind.config.js +0 -80
- package/tests/placeholder.test.ts +0 -7
- package/tsconfig.json +0 -29
- package/tsconfig.node.json +0 -10
- package/vite.config.ts +0 -27
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
# 🚀 Project Zenith: Laravel Integration Roadmap
|
|
2
|
-
|
|
3
|
-
**Repository**: `gravito-framework/laravel-zenith`
|
|
4
|
-
**Target Audience**: Laravel 10/11 Applications
|
|
5
|
-
**Goal**: Provide deep, native introspection into Laravel applications for Gravito Zenith.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## 1. Vision & Architecture
|
|
10
|
-
|
|
11
|
-
Unlike the **Quasar Agent** (which is a sidecar daemon for OS/Infrastructure monitoring), **Laravel Zenith** is a native Composer package that lives *inside* the application.
|
|
12
|
-
|
|
13
|
-
* **Role**: " The Reporter". It sees what the OS cannot see.
|
|
14
|
-
* **Transport**: Direct Redis connection (utilizing `swarrot` or standard `predis`/`phpredis`).
|
|
15
|
-
* **Philosophy**: Zero-blocking. All reporting should be "fire-and-forget" or queued to avoid slowing down the user request lifecycle.
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## 2. Core Features (The "Why")
|
|
20
|
-
|
|
21
|
-
### A. Live Operational Logs (`logs`)
|
|
22
|
-
* **Feature**: A custom `Log Channel` driver.
|
|
23
|
-
* **Goal**: Stream logs (Info/Error/Debug) directly to Zenith's Live Log view.
|
|
24
|
-
* **Implementation**:
|
|
25
|
-
* `config/logging.php`: Add a `zenith` channel.
|
|
26
|
-
* Push JSON payloads to `flux_console:logs` Redis channel.
|
|
27
|
-
|
|
28
|
-
### B. Queue Lifecycle Events (`queues`)
|
|
29
|
-
* **Feature**: Listen to Laravel Queue Events (`JobProcessing`, `JobProcessed`, `JobFailed`).
|
|
30
|
-
* **Goal**: Provide granular job insight that `quasar-go` cannot (e.g., "Job X failed with Exception Y", "Job Z took 45s").
|
|
31
|
-
* **Implementation**:
|
|
32
|
-
* Event Subscriber for `Illuminate\Queue\Events\*`.
|
|
33
|
-
* Capture `job->getRawBody()`, `exception->getMessage()`.
|
|
34
|
-
|
|
35
|
-
### C. Request Performance (`http`)
|
|
36
|
-
* **Feature**: Global Middleware (`ZenithMonitorMiddleware`).
|
|
37
|
-
* **Goal**: Track "Slow Requests", 500 Errors, and Throughput.
|
|
38
|
-
* **Metrics**:
|
|
39
|
-
* Status Codes (2xx, 4xx, 5xx).
|
|
40
|
-
* Duration (ms).
|
|
41
|
-
* Route Name / Controller Action.
|
|
42
|
-
|
|
43
|
-
### D. System Health Checks
|
|
44
|
-
* **Feature**: `php artisan zenith:check`
|
|
45
|
-
* **Goal**: Verify Redis connection and permissions.
|
|
46
|
-
|
|
47
|
-
---
|
|
48
|
-
|
|
49
|
-
## 3. Implementation Roadmap
|
|
50
|
-
|
|
51
|
-
### Phase 1: The Foundation (Logs & Config)
|
|
52
|
-
**Goal**: Get the package installed and streaming basic logs.
|
|
53
|
-
- [ ] Initialize Repository `gravito-framework/laravel-zenith`.
|
|
54
|
-
- [ ] Create `ZenithServiceProvider`.
|
|
55
|
-
- [ ] Implement `ZenithLogger` (Monolog Handler).
|
|
56
|
-
- [ ] Publishing `config/zenith.php` (Redis connection settings).
|
|
57
|
-
- [ ] **Deliverable**: `Log::info('Hello Zenith')` appears in Zenith UI.
|
|
58
|
-
|
|
59
|
-
### Phase 2: The Worker's Eye (Queues)
|
|
60
|
-
**Goal**: Deep visibility into Queue Jobs.
|
|
61
|
-
- [ ] Create `ZenithQueueSubscriber`.
|
|
62
|
-
- [ ] Handle `JobFailed`: Serialize exception and push to Zenith Alerting.
|
|
63
|
-
- [ ] Handle `JobProcessed`: Record metrics for "Jobs per minute".
|
|
64
|
-
- [ ] **Deliverable**: Seeing real-time "Job Completed" toasts and Error details in Zenith.
|
|
65
|
-
|
|
66
|
-
### Phase 3: The Watchtower (HTTP & Exceptions)
|
|
67
|
-
**Goal**: Monitoring web requests.
|
|
68
|
-
- [ ] Create `RecordRequestMetrics` Middleware.
|
|
69
|
-
- [ ] Exception Handler integration (optional, for global error catching).
|
|
70
|
-
- [ ] Filter logic (ignore `/nova`, `/telescope`, etc.).
|
|
71
|
-
- [ ] **Deliverable**: HTTP Throughput graphs in Zenith.
|
|
72
|
-
|
|
73
|
-
### Phase 4: The Bridge (Remote Control Hooks)
|
|
74
|
-
**Goal**: Allow Zenith to trigger Laravel actions safely.
|
|
75
|
-
- [ ] Expose internal hooks for `quasar-go` to call?
|
|
76
|
-
* *Note*: `quasar-go` already calls `artisan`. Phase 4 might be about ensuring `artisan zenith:run-job {id}` exists if we need advanced job re-running that `queue:retry` can't handle.
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
## 4. Technical Specifications
|
|
81
|
-
|
|
82
|
-
### Redis Protocol
|
|
83
|
-
We will reuse the **Gravito Pulse Protocol (GPP)** used by `quasar-go`:
|
|
84
|
-
* **Logs**: `PUBLISH flux_console:logs`
|
|
85
|
-
* **Metrics**: `INCR flux_console:metrics:...`
|
|
86
|
-
|
|
87
|
-
### Configuration (`zenith.php`)
|
|
88
|
-
```php
|
|
89
|
-
return [
|
|
90
|
-
'enabled' => env('ZENITH_ENABLED', true),
|
|
91
|
-
|
|
92
|
-
'connection' => env('ZENITH_REDIS_CONNECTION', 'default'),
|
|
93
|
-
|
|
94
|
-
'logging' => [
|
|
95
|
-
'enabled' => true,
|
|
96
|
-
'level' => 'debug',
|
|
97
|
-
],
|
|
98
|
-
|
|
99
|
-
'queues' => [
|
|
100
|
-
'monitor_all' => true,
|
|
101
|
-
'ignore_jobs' => [],
|
|
102
|
-
],
|
|
103
|
-
];
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
### Dependency Strategy
|
|
107
|
-
* **Support**: Laravel 10.x, 11.x
|
|
108
|
-
* **Php**: 8.1+
|
|
109
|
-
* **Driver**: `phpredis` (preferred) or `predis`.
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
# 🌌 Project Quasar: Master Implementation Plan
|
|
2
|
-
|
|
3
|
-
**Version**: 1.0.0 (Unified)
|
|
4
|
-
**Target**: Zenith v1.0
|
|
5
|
-
**Context**: This document supersedes all previous "Pulse" plans. It is the single source of truth for the Quasar monitoring ecosystem.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## 1. Vision & Identity
|
|
10
|
-
|
|
11
|
-
**Quasar** is the comprehensive observability layer for the Gravito ecosystem. It unifies infrastructure monitoring (CPU/RAM), application insights (Queues/Slow Logs), and availability checks into a single stream.
|
|
12
|
-
|
|
13
|
-
> **Slogan**: *"The brightest signal in your infrastructure."*
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## 2. Architecture & Deployment Matrix
|
|
18
|
-
|
|
19
|
-
We employ a "Right Tool for the Job" strategy for deployment:
|
|
20
|
-
|
|
21
|
-
| Ecosystem | Tool | Package | Strategy |
|
|
22
|
-
| :--- | :--- | :--- | :--- |
|
|
23
|
-
| **Node.js / Bun** | **SDK** | `@gravito/quasar` | **In-App Integration**. Directly imports into the app. Captures Event Loop, Heap, and Queues. |
|
|
24
|
-
| **Legacy / Polyglot** | **Agent** | `gravito/quasar-agent` | **Sidecar / Daemon**. Standalone Go binary. Captures OS-level metrics and external Queue states via Redis/API. |
|
|
25
|
-
| **PHP / Laravel** | **Package** | `gravito/laravel-zenith` | **Native Integration**. Laravel Service Provider. Captures Jobs, Logs, and Exceptions. |
|
|
26
|
-
|
|
27
|
-
### 🚀 Deployment Methods (Zero Friction)
|
|
28
|
-
1. **NPM**: `npm install @gravito/quasar` (For Node developers)
|
|
29
|
-
2. **Docker**: `image: gravito/quasar-agent:latest` (For Container/K8s/Laravel Sail)
|
|
30
|
-
3. **Shell**: `curl -sL get.gravito.dev/quasar | bash` (For Bare Metal/VM)
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## 3. Data Protocol (The Quasar Schema)
|
|
35
|
-
|
|
36
|
-
All agents/SDKs report to Redis using this unified schema.
|
|
37
|
-
|
|
38
|
-
**Namespace**: `gravito:quasar:`
|
|
39
|
-
|
|
40
|
-
### A. Heartbeat (Infrastructure)
|
|
41
|
-
* **Key**: `gravito:quasar:node:{service_name}:{node_id}`
|
|
42
|
-
* **TTL**: 30 seconds
|
|
43
|
-
* **Metrics Philosophy**: Report **BOTH** Process and System metrics to isolate resource usage.
|
|
44
|
-
* `process`: metrics for the specific service (RAM usage, CPU time).
|
|
45
|
-
* `system`: metrics for the host OS (Load avg, Total RAM).
|
|
46
|
-
|
|
47
|
-
### B. Queues (Workload)
|
|
48
|
-
* **Key**: `gravito:quasar:queues:{service_name}`
|
|
49
|
-
* **TTL**: 30 seconds
|
|
50
|
-
* **Purpose**: Snapshots of queue depths from various drivers.
|
|
51
|
-
* Gravito Stream (Native)
|
|
52
|
-
* Laravel Horizon (Redis)
|
|
53
|
-
* BullMQ (Redis)
|
|
54
|
-
* AWS SQS (API)
|
|
55
|
-
|
|
56
|
-
### C. Insights (Performance)
|
|
57
|
-
* **Key**: `gravito:quasar:slow:{service_name}` (Stream)
|
|
58
|
-
* **Purpose**: Log requests or jobs that exceed performance thresholds.
|
|
59
|
-
|
|
60
|
-
---
|
|
61
|
-
|
|
62
|
-
## 4. Execution Roadmap
|
|
63
|
-
|
|
64
|
-
### Phase 1: Foundation & Application Monitoring (Pulse Node)
|
|
65
|
-
**Goal**: Establish the basic dashboard and Node.js SDK for monitoring application health (CPU/RAM).
|
|
66
|
-
|
|
67
|
-
- [x] **Define Schema**: Update `PULSE_SPEC.md` with new Redis key patterns (`gravito:quasar:node:*`) and payload structure.
|
|
68
|
-
- [x] **SDK Update**: Refactor `@gravito/quasar` (formerly pulse-node) to support:
|
|
69
|
-
- [x] Automatic runtime detection (Node, Bun, Deno).
|
|
70
|
-
- [x] System/Process split metrics.
|
|
71
|
-
- [x] Correct Redis namespacing.
|
|
72
|
-
- [x] **Server Update**: Update Zenith's `PulseService` to scan new key patterns.
|
|
73
|
-
- [x] **UI Overhaul**: Redesign `PulsePage` in Zenith:
|
|
74
|
-
- [x] Implement "Card" layout for nodes.
|
|
75
|
-
- [x] Rich metrics visualization (CPU/RAM split bars).
|
|
76
|
-
- [x] Add brand icons for runtimes (Node, Bun, Deno, PHP, Go, Python).
|
|
77
|
-
- [x] **Layout Optimization**: Compact Grid for Service Groups.
|
|
78
|
-
|
|
79
|
-
---
|
|
80
|
-
|
|
81
|
-
### Phase 2: Architecture Evolution - "The Brain-Hand Model" 🧠 🖐️ - **Completed** ✅
|
|
82
|
-
To support advanced features like **Queue Insights** (Phase 2) and **Remote Control** (Phase 3), we are adopting a bidirectional architecture.
|
|
83
|
-
|
|
84
|
-
* **Metric Transport (The Mouth)**: Agent sends metrics to Zenith (via shared Redis).
|
|
85
|
-
* **Local Insight (The Eyes)**: Agent inspects *its own* environment (Local Redis, Local Queue) to gather data. Zenith doesn't need to connect to the App DB directly.
|
|
86
|
-
* **Command execution (The Hand)**: Zenith publishes commands (Retry/Delete), and Agent listens and executes them locally.
|
|
87
|
-
|
|
88
|
-
#### Revised Phase 2: Application Insights (Queues) - **Completed** ✅
|
|
89
|
-
**Goal**: Enable Quasar Agent to "see" local queues and report their status.
|
|
90
|
-
|
|
91
|
-
- [x] **SDK Architecture**: Update `QuasarAgent` to handle **Dual Connections**:
|
|
92
|
-
- `transport`: Connection to Zenith (for sending heartbeat).
|
|
93
|
-
- `app`: Connection to Local App (for inspecting queues/bull/laravel).
|
|
94
|
-
- [x] **Probe Implementation**: Create `QueueProbe` interface and implementations:
|
|
95
|
-
- `RedisListProbe`: Simple `LLEN` checks.
|
|
96
|
-
- [x] `BullProbe` (Future): Check `bull:*:waiting`, etc.
|
|
97
|
-
- [x] `LaravelProbe`: Check `queues:default`, `queues:reserved`, `queues:delayed`.
|
|
98
|
-
- [x] **SDK API**: Expose `.monitorQueue(name, type)` method.
|
|
99
|
-
- [x] **UI Update**: Update `NodeCard` to render a "Queues" section if queue data is present in payload.
|
|
100
|
-
|
|
101
|
-
### Phase 3: Remote Control (Command & Control) - **Completed** ✅
|
|
102
|
-
**Goal**: Allow Zenith to instruct Quasar to perform actions (Retry Job, Delete Job).
|
|
103
|
-
|
|
104
|
-
- [x] **Protocol**: Define Command Protocol (Redis Pub/Sub: `gravito:quasar:cmd:{service}:{node_id}`).
|
|
105
|
-
- [x] **Agent**: Implement `CommandListener` in SDK.
|
|
106
|
-
- [x] **Command Executors**: Implement `RetryJobExecutor` and `DeleteJobExecutor`.
|
|
107
|
-
- [x] **Security (Allowlist Strategy)**:
|
|
108
|
-
- [x] Implement **Command Allowlist** inside Agent code (only `RETRY_JOB`, `DELETE_JOB` allowed).
|
|
109
|
-
- [ ] (Future) Use **Redis ACL** (v6+) to restrict Agent's `transport` connection.
|
|
110
|
-
- [x] **Server**: Add `CommandService` and `/api/pulse/command` endpoint.
|
|
111
|
-
- [x] **UI**: Add "Retry/Delete" buttons in Zenith `PulsePage` for failed queue jobs.
|
|
112
|
-
- [x] **Documentation**: Created `ALERTING_GUIDE.md` for configuration best practices.
|
|
113
|
-
|
|
114
|
-
### Phase 4: Polyglot Agent - **Completed** ✅
|
|
115
|
-
* [x] Create `gravito-framework/quasar` repo (`quasar-go`).
|
|
116
|
-
* [x] Develop Go Agent core (utilizing `gopsutil`).
|
|
117
|
-
* [x] System Probe (CPU/RAM)
|
|
118
|
-
* [x] Agent heartbeat loop
|
|
119
|
-
* [x] Config management (env vars)
|
|
120
|
-
* [x] Implement Queue Monitoring in Go Agent:
|
|
121
|
-
* [x] Redis List Probe
|
|
122
|
-
* [x] Laravel Queue Probe
|
|
123
|
-
* [x] Implement Remote Control in Go Agent:
|
|
124
|
-
* [x] Command Listener (Pub/Sub)
|
|
125
|
-
* [x] RETRY_JOB / DELETE_JOB Executors
|
|
126
|
-
* [x] **Laravel Deep Integration**:
|
|
127
|
-
* [x] `LARAVEL_ACTION` Executor (runs `artisan` safely).
|
|
128
|
-
* [x] Auto-discovery of Laravel project root via process inspection.
|
|
129
|
-
* [x] **Advanced Process Introspection**: Captures real-time CPU/RAM usage per Laravel Worker process.
|
|
130
|
-
* [x] **Virtual Node Mapping**: Visualizes individual Laravel Workers as distinct nodes in Zenith UI.
|
|
131
|
-
* [x] Support for `retry-all`, `retry {id}`, and `restart` (graceful worker reload).
|
|
132
|
-
* [x] Docker & Makefile setup.
|
|
133
|
-
* [x] Binary Release pipeline (GitHub Actions).
|
|
134
|
-
* [x] Publish to Docker Hub (`carllee/quasar-go-agent`).
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## 5. Security & Access
|
|
139
|
-
* **Auth**: Agents authenticate via a shared secret (`QUASAR_TOKEN`) if writing to a remote Redis.
|
|
140
|
-
* **Isolation**: Process metrics only report what they have access to. System metrics require readable `/proc` (in Docker).
|
package/docs/QUICK_TEST_GUIDE.md
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
# 🎯 Flux Console 統一測試指南
|
|
2
|
-
|
|
3
|
-
## 🚀 快速開始
|
|
4
|
-
|
|
5
|
-
我們已經將所有測試腳本整合為 `seed.ts` 與 `worker.ts`,以下是常用的測試流程。
|
|
6
|
-
|
|
7
|
-
### 1. 初始化資料 (Seeding)
|
|
8
|
-
|
|
9
|
-
根據測試需求選擇模式:
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
# 基本資料(Waiting, Delayed, Failed)
|
|
13
|
-
bun scripts/seed.ts standard
|
|
14
|
-
|
|
15
|
-
# 壓力測試(建立 15 個佇列,每個佇列有大量資料)
|
|
16
|
-
bun scripts/seed.ts stress
|
|
17
|
-
|
|
18
|
-
# 批次操作測試(專用大量資料)
|
|
19
|
-
bun scripts/seed.ts batch
|
|
20
|
-
|
|
21
|
-
# 註冊排程管理 (Cron Jobs)
|
|
22
|
-
bun scripts/seed.ts cron
|
|
23
|
-
|
|
24
|
-
# 懶人包:一次執行以上所有模式
|
|
25
|
-
bun scripts/seed.ts all
|
|
26
|
-
|
|
27
|
-
# 清理所有資料
|
|
28
|
-
bun scripts/seed.ts cleanup
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
### 2. 啟動背景處理 (Workers)
|
|
32
|
-
|
|
33
|
-
模擬工作正在被處理、成功或失敗的過程:
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
# 啟動預設佇列的處理
|
|
37
|
-
bun scripts/worker.ts
|
|
38
|
-
|
|
39
|
-
# 模擬高失敗率與處理延遲
|
|
40
|
-
bun scripts/worker.ts orders,reports --fail=0.3 --delay=500
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## 🧪 核心測試情境
|
|
46
|
-
|
|
47
|
-
### 測試 1:排程管理 (Schedules)
|
|
48
|
-
1. 執行 `bun scripts/seed.ts cron`。
|
|
49
|
-
2. 在 UI 點擊側邊欄的 **"Schedules"**。
|
|
50
|
-
3. 檢查是否顯示 `cleanup-tmp`, `daily-report` 等排程。
|
|
51
|
-
4. 點擊 "Run Now" 檢查工作是否立即進入 `system` 或 `reports` 佇列。
|
|
52
|
-
|
|
53
|
-
### 測試 2:批次操作 (Batch Operations)
|
|
54
|
-
1. 執行 `bun scripts/seed.ts batch`。
|
|
55
|
-
2. 進入 `test-batch` 佇列。
|
|
56
|
-
3. 使用 **Cmd+A** 全選,然後點擊 "Delete Selected"。
|
|
57
|
-
4. 測試頁面底部的「刪除所有 X 個工作」警告橫幅。
|
|
58
|
-
|
|
59
|
-
### 測試 3:排版與搜尋
|
|
60
|
-
1. 執行 `bun scripts/seed.ts stress`。
|
|
61
|
-
2. 檢查側邊欄的佇列列表是否正確收合/捲動。
|
|
62
|
-
3. 使用 **Cmd+K** 開啟命令列,輸入 `billing` 跳轉至該佇列。
|
|
63
|
-
|
|
64
|
-
---
|
|
65
|
-
|
|
66
|
-
## 🧹 清理空間
|
|
67
|
-
|
|
68
|
-
測試完成後,建議執行:
|
|
69
|
-
```bash
|
|
70
|
-
bun scripts/seed.ts cleanup
|
|
71
|
-
```
|
|
72
|
-
這會清除 Redis 中所有帶有 `queue:` 前綴的 Key,以及 Console 的日誌快取。
|
package/docs/ROADMAP.md
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
# Gravito Zenith Roadmap (Control Plane)
|
|
2
|
-
|
|
3
|
-
This document outlines the future development plan for **Gravito Zenith**, moving from a basic monitoring tool to a comprehensive polyglot control plane for any job processing system.
|
|
4
|
-
|
|
5
|
-
## 🚀 High Priority (Immediate Next Steps)
|
|
6
|
-
|
|
7
|
-
### 1. Polyglot & Framework Integration (P0)
|
|
8
|
-
**Goal**: Official support for non-Node.js workers, making Zenith a universal dashboard.
|
|
9
|
-
- **Tasks**:
|
|
10
|
-
- [x] **Protocol Specification**: Defined standard Redis structures for Heartbeat and Logs.
|
|
11
|
-
- [x] **Laravel Integration**: Blueprint for `ZenithServiceProvider` and `ZenithConnector` defined.
|
|
12
|
-
- [ ] **Go/Python SDK**: Create lightweight client libraries for other languages.
|
|
13
|
-
|
|
14
|
-
### 2. Docker & Cloud-Native Deployment (P1)
|
|
15
|
-
**Goal**: Enable "One-Click Deployment" for any environment (local, EC2, K8s).
|
|
16
|
-
- **Current Blocker**: Local workspace dependencies (`workspace:*`) cause build failures in standard Docker contexts.
|
|
17
|
-
- **Tasks**:
|
|
18
|
-
- [x] Fix `Dockerfile` dependency resolution (via multi-stage builds).
|
|
19
|
-
- [x] Create `docker-compose.yml` for a full stack setup (Console + Redis + Demo Worker).
|
|
20
|
-
- [x] Implementation of Scheduled Jobs (Cron) Management.
|
|
21
|
-
|
|
22
|
-
### 3. System Pulse Monitoring (Lightweight APM) (P0 - NEW)
|
|
23
|
-
**Goal**: Application-Aware lightweight resource monitoring and alerting.
|
|
24
|
-
**Philosophy**: "If you can connect to Redis, you are monitored." No extra agents, no Prometheus config.
|
|
25
|
-
- **Features**:
|
|
26
|
-
- **Live Resource Cards**: CPU / RAM / Disk Usage per service (Node.js, PHP, Python).
|
|
27
|
-
- **Health Heartbeats**: Auto-discovery of active services via `pulse:{service}:{id}` keys.
|
|
28
|
-
- **Proactive Alerting**: Slack notifications for Disk Space < 10% or High CPU Load.
|
|
29
|
-
- **Protocol-Based**: Language-agnostic design (Gravito Pulse Protocol).
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
### 3. History Persistence (SQL Archive) (Completed ✅)
|
|
33
|
-
**Goal**: Store job history permanently for auditing and long-term analysis.
|
|
34
|
-
- [x] Implement a `PersistenceAdapter` in `@gravito/stream`.
|
|
35
|
-
- [x] Automatically archive completed/failed jobs to a SQL database.
|
|
36
|
-
- [x] **Zero-Config (SQLite)**: Integrated support for local testing.
|
|
37
|
-
- [x] **Time Travel Audit**: comprehensive UI for tracing job history.
|
|
38
|
-
|
|
39
|
-
## ✨ Feature Enhancements (Mid-Term)
|
|
40
|
-
|
|
41
|
-
### 4. Alerting & Notifications (Completed ✅)
|
|
42
|
-
**Goal**: Proactive issue notification system.
|
|
43
|
-
- [x] **AlertService**: Lightweight rules for failure spikes, backlog, and worker loss.
|
|
44
|
-
- [x] **Cooldown Mechanism**: Prevents alerting storms.
|
|
45
|
-
- [x] **Slack Integration**: Webhook support with test notification UI.
|
|
46
|
-
- [x] **Real-time Monitoring**: Integrated directly into server metrics loop.
|
|
47
|
-
|
|
48
|
-
### 5. Scheduled Jobs (Cron) Management (Completed ✅)
|
|
49
|
-
**Goal**: UI-based management for recurring tasks.
|
|
50
|
-
- [x] Dashboard to view all registered Cron jobs.
|
|
51
|
-
- [x] Ability to "Trigger Now" manually.
|
|
52
|
-
- [x] Ability to Pause/Resume (Delete/Register) specific Cron schedules.
|
|
53
|
-
- [x] Real-time ticking via the Console server.
|
|
54
|
-
|
|
55
|
-
### 6. Batch Operations (Completed ✅)
|
|
56
|
-
**Goal**: Bulk management actions.
|
|
57
|
-
- **Problem**: Can only retry/delete one job or "all" jobs. Hard to handle "the 50 jobs that failed due to the bug yesterday".
|
|
58
|
-
- **Tasks**:
|
|
59
|
-
- [x] Multi-select checkboxes in job lists.
|
|
60
|
-
- [x] Bulk Retry / Bulk Delete.
|
|
61
|
-
- [x] Select All Matching Query (Delete/Retry ALL jobs of a type).
|
|
62
|
-
- [x] Confirmation dialogs with loading states.
|
|
63
|
-
- [x] Keyboard shortcuts (Ctrl+A, Escape).
|
|
64
|
-
- [x] Visual feedback and total count display.
|
|
65
|
-
|
|
66
|
-
## 🔮 Enterprise Features (Long-Term)
|
|
67
|
-
|
|
68
|
-
### 7. Role-Based Access Control (RBAC)
|
|
69
|
-
**Goal**: Granular permission management for teams.
|
|
70
|
-
- **Problem**: Single password for everyone. Risky for junior devs to have "Delete Queue" power.
|
|
71
|
-
- **Features**:
|
|
72
|
-
- Roles: `Viewer` (Read-only), `Operator` (Retry/Pause), `Admin` (Delete/Purge).
|
|
73
|
-
- User Management system (potentially integrated with OAuth/SSO).
|
|
74
|
-
|
|
75
|
-
### 8. Multi-Cluster Management
|
|
76
|
-
**Goal**: Centralized control pane for multiple environments.
|
|
77
|
-
- **Problem**: Need to open 3 different tabs for Dev, Staging, and Prop.
|
|
78
|
-
- **Features**:
|
|
79
|
-
- Connection Switcher in the UI header.
|
|
80
|
-
- Unified view of multiple Redis instances.
|
|
81
|
-
|
|
82
|
-
### 9. Enhanced Search (Indexer)
|
|
83
|
-
**Goal**: Full-text search on Job Payloads.
|
|
84
|
-
- **Problem**: Can only search by Job ID. Cannot search by "email: user@example.com".
|
|
85
|
-
- **Solution**: Implement a lightweight search index (RedisSearch or external engine) to index payloads.
|
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
# Laravel Integration Guide for Gravito Zenith
|
|
2
|
-
|
|
3
|
-
This guide outlines the architecture and implementation details for integrating Laravel applications with **Gravito Zenith**, enabling centralized monitoring, logging, and auditing for Laravel Queues.
|
|
4
|
-
|
|
5
|
-
## Architecture Overview
|
|
6
|
-
|
|
7
|
-
+----------------+ +--------------+ +----------------+
|
|
8
|
-
| Laravel App | | Redis Broker | | Gravito Zenith |
|
|
9
|
-
| (Horizon/Queue)| ----> | (Shared) | <---- | Control Plane |
|
|
10
|
-
+----------------+ +--------------+ +----------------+
|
|
11
|
-
| ^
|
|
12
|
-
| | Redis Pub/Sub & Lists
|
|
13
|
-
+--- [Zenith Connector] +
|
|
14
|
-
|
|
15
|
-
The **Zenith Connector** acts as a bridge, translating Laravel's internal queue events into the Zenith Protocol.
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## 1. Protocol Specification
|
|
20
|
-
|
|
21
|
-
To be visible in Zenith, the Laravel connector must implement the following Redis interactions:
|
|
22
|
-
|
|
23
|
-
### Namespace
|
|
24
|
-
Default Prefix: `flux:` (configurable). Ensure this matches your Zenith configuration.
|
|
25
|
-
|
|
26
|
-
### A. Worker Heartbeat (Process Discovery)
|
|
27
|
-
The connector must run a background process (or scheduled command) to announce the worker's presence.
|
|
28
|
-
|
|
29
|
-
- **Key**: `flux_console:worker:<worker-id>`
|
|
30
|
-
- **TTL**: 60 seconds (refresh every 30s)
|
|
31
|
-
- **Format**:
|
|
32
|
-
```json
|
|
33
|
-
{
|
|
34
|
-
"id": "laravel-worker-supervisor-1",
|
|
35
|
-
"hostname": "app-server-01",
|
|
36
|
-
"pid": 1234,
|
|
37
|
-
"uptime": 3600,
|
|
38
|
-
"queues": ["default", "emails"],
|
|
39
|
-
"concurrency": 10,
|
|
40
|
-
"memory": {
|
|
41
|
-
"rss": "100MB",
|
|
42
|
-
"heapTotal": "N/A",
|
|
43
|
-
"heapUsed": "N/A"
|
|
44
|
-
},
|
|
45
|
-
"timestamp": "ISO-8601 String"
|
|
46
|
-
}
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### B. Real-time Logs (Event Stream)
|
|
50
|
-
The connector listens to Laravel Queue events and publishes them to Zenith.
|
|
51
|
-
|
|
52
|
-
- **Channel**: `flux_console:logs`
|
|
53
|
-
- **Format**:
|
|
54
|
-
```json
|
|
55
|
-
{
|
|
56
|
-
"level": "info", // info | warn | error | success
|
|
57
|
-
"message": "Processing Job: App\\Jobs\\SendWelcomeEmail",
|
|
58
|
-
"workerId": "laravel-worker-supervisor-1",
|
|
59
|
-
"queue": "emails",
|
|
60
|
-
"timestamp": "ISO-8601 String",
|
|
61
|
-
"jobId": "uuid-..." // Optional, enables specific tracing
|
|
62
|
-
}
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### C. Job Auditing (Time Travel)
|
|
66
|
-
(Optional) For "Time Travel Audit" features, the connector should write to the persistent store if configured, or rely on Zenith's Redis scanning if utilizing standard Flux queue structures. Since Laravel uses its own queue structure, **Real-time Logs** are the primary integration point for v1.
|
|
67
|
-
|
|
68
|
-
---
|
|
69
|
-
|
|
70
|
-
## 2. Implementation Blueprint (PHP)
|
|
71
|
-
|
|
72
|
-
This section provides the reference implementation for the `gravito/zenith-laravel` composer package.
|
|
73
|
-
|
|
74
|
-
### Service Provider: `ZenithServiceProvider.php`
|
|
75
|
-
|
|
76
|
-
This provider hooks into Laravel's Queue events.
|
|
77
|
-
|
|
78
|
-
```php
|
|
79
|
-
<?php
|
|
80
|
-
|
|
81
|
-
namespace Gravito\Zenith\Laravel;
|
|
82
|
-
|
|
83
|
-
use Illuminate\Support\ServiceProvider;
|
|
84
|
-
use Illuminate\Support\Facades\Queue;
|
|
85
|
-
use Illuminate\Support\Facades\Redis;
|
|
86
|
-
use Illuminate\Queue\Events\JobProcessing;
|
|
87
|
-
use Illuminate\Queue\Events\JobProcessed;
|
|
88
|
-
use Illuminate\Queue\Events\JobFailed;
|
|
89
|
-
|
|
90
|
-
class ZenithServiceProvider extends ServiceProvider
|
|
91
|
-
{
|
|
92
|
-
public function boot()
|
|
93
|
-
{
|
|
94
|
-
// 1. Job Started
|
|
95
|
-
Queue::before(function (JobProcessing $event) {
|
|
96
|
-
$this->publishLog('info', $event);
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
// 2. Job Success
|
|
100
|
-
Queue::after(function (JobProcessed $event) {
|
|
101
|
-
$this->publishLog('success', $event);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
// 3. Job Failed
|
|
105
|
-
Queue::failing(function (JobFailed $event) {
|
|
106
|
-
$this->publishLog('error', $event, $event->exception->getMessage());
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
protected function publishLog($level, $event, $extraMessage = '')
|
|
111
|
-
{
|
|
112
|
-
$payload = $event->job->payload();
|
|
113
|
-
$jobName = $payload['displayName'] ?? 'Unknown Job';
|
|
114
|
-
|
|
115
|
-
// Simplify Job Name (remove namespace for display)
|
|
116
|
-
$shortName = class_basename($jobName);
|
|
117
|
-
|
|
118
|
-
$message = match($level) {
|
|
119
|
-
'info' => "Processing {$shortName}",
|
|
120
|
-
'success' => "Completed {$shortName}",
|
|
121
|
-
'error' => "Failed {$shortName}: {$extraMessage}",
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
$log = [
|
|
125
|
-
'level' => $level,
|
|
126
|
-
'message' => $message,
|
|
127
|
-
'workerId' => gethostname() . '-' . getmypid(), // Simple ID generation
|
|
128
|
-
'queue' => $event->job->getQueue(),
|
|
129
|
-
'timestamp' => now()->toIso8601String(),
|
|
130
|
-
'jobId' => $event->job->getJobId()
|
|
131
|
-
];
|
|
132
|
-
|
|
133
|
-
// Fire and forget to Redis
|
|
134
|
-
try {
|
|
135
|
-
Redis::connection('zenith')->publish('flux_console:logs', json_encode($log));
|
|
136
|
-
} catch (\Exception $e) {
|
|
137
|
-
// Silently fail to not disrupt main application
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
### Heartbeat Command: `zenith:heartbeat`
|
|
144
|
-
|
|
145
|
-
This command should be run as a daemon (Supervisor) or scheduled every minute (less precise). For best results, run as a sidecar process.
|
|
146
|
-
|
|
147
|
-
```php
|
|
148
|
-
<?php
|
|
149
|
-
|
|
150
|
-
namespace Gravito\Zenith\Laravel\Console;
|
|
151
|
-
|
|
152
|
-
use Illuminate\Console\Command;
|
|
153
|
-
use Illuminate\Support\Facades\Redis;
|
|
154
|
-
|
|
155
|
-
class ZenithHeartbeat extends Command
|
|
156
|
-
{
|
|
157
|
-
protected $signature = 'zenith:heartbeat';
|
|
158
|
-
protected $description = 'Send heartbeat to Gravito Zenith';
|
|
159
|
-
|
|
160
|
-
public function handle()
|
|
161
|
-
{
|
|
162
|
-
$this->info('Starting Zenith Heartbeat...');
|
|
163
|
-
|
|
164
|
-
while (true) {
|
|
165
|
-
$workerId = gethostname() . '-' . getmypid();
|
|
166
|
-
|
|
167
|
-
$payload = [
|
|
168
|
-
'id' => $workerId,
|
|
169
|
-
'hostname' => gethostname(),
|
|
170
|
-
'pid' => getmypid(),
|
|
171
|
-
'uptime' => 0, // Calculate real uptime if needed
|
|
172
|
-
'queues' => config('queue.connections.redis.queue', ['default']),
|
|
173
|
-
'memory' => [
|
|
174
|
-
'rss' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB',
|
|
175
|
-
'heapUsed' => 'N/A',
|
|
176
|
-
'heapTotal' => 'N/A'
|
|
177
|
-
],
|
|
178
|
-
'timestamp' => now()->toIso8601String()
|
|
179
|
-
];
|
|
180
|
-
|
|
181
|
-
Redis::connection('zenith')->setex(
|
|
182
|
-
"flux_console:worker:{$workerId}",
|
|
183
|
-
30, // 30s TTL
|
|
184
|
-
json_encode($payload)
|
|
185
|
-
);
|
|
186
|
-
|
|
187
|
-
sleep(5);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
## 3. Configuration
|
|
194
|
-
|
|
195
|
-
Users will need to configure a dedicated Redis connection for Zenith in `config/database.php` to avoid prefix collisions if they modify their default Redis prefix.
|
|
196
|
-
|
|
197
|
-
```php
|
|
198
|
-
'redis' => [
|
|
199
|
-
'zenith' => [
|
|
200
|
-
'host' => env('ZENITH_REDIS_HOST', '127.0.0.1'),
|
|
201
|
-
'password' => env('ZENITH_REDIS_PASSWORD', null),
|
|
202
|
-
'port' => env('ZENITH_REDIS_PORT', '6379'),
|
|
203
|
-
'database' => env('ZENITH_REDIS_DB', '0'),
|
|
204
|
-
'prefix' => '', // Ensure no prefix or match Zenith's expectation
|
|
205
|
-
],
|
|
206
|
-
],
|
|
207
|
-
```
|
package/postcss.config.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Redis } from 'ioredis'
|
|
2
|
-
|
|
3
|
-
const redis = new Redis('redis://localhost:6379')
|
|
4
|
-
|
|
5
|
-
async function check() {
|
|
6
|
-
console.log('Connecting to Redis...')
|
|
7
|
-
try {
|
|
8
|
-
const keys = await redis.keys('gravito:quasar:node:*')
|
|
9
|
-
console.log('Keys found count:', keys.length)
|
|
10
|
-
console.log('Keys:', keys)
|
|
11
|
-
|
|
12
|
-
if (keys.length > 0) {
|
|
13
|
-
const val = await redis.get(keys[0])
|
|
14
|
-
console.log('--- Value of first key ---')
|
|
15
|
-
console.log(val)
|
|
16
|
-
console.log('--- End Value ---')
|
|
17
|
-
}
|
|
18
|
-
} catch (err) {
|
|
19
|
-
console.error('Redis Error:', err)
|
|
20
|
-
}
|
|
21
|
-
process.exit(0)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
check()
|
package/scripts/flood-logs.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { QueueService } from '../src/server/services/QueueService'
|
|
2
|
-
|
|
3
|
-
const svc = new QueueService(process.env.REDIS_URL || 'redis://localhost:6379')
|
|
4
|
-
await svc.connect()
|
|
5
|
-
|
|
6
|
-
console.log('🌊 Flooding 500 logs in burst...')
|
|
7
|
-
const start = Date.now()
|
|
8
|
-
const promises = []
|
|
9
|
-
for (let i = 0; i < 500; i++) {
|
|
10
|
-
promises.push(
|
|
11
|
-
svc.publishLog({
|
|
12
|
-
level: 'info',
|
|
13
|
-
message: `Flood log ${i} - ${Date.now()}`,
|
|
14
|
-
workerId: 'flood-bot',
|
|
15
|
-
queue: 'test-flood',
|
|
16
|
-
})
|
|
17
|
-
)
|
|
18
|
-
}
|
|
19
|
-
await Promise.all(promises)
|
|
20
|
-
console.log(`✅ Sent 500 logs in ${Date.now() - start}ms`)
|
|
21
|
-
process.exit(0)
|