add README for usage-dashboard
This commit is contained in:
@@ -0,0 +1,406 @@
|
||||
# CLIProxyAPI Usage Dashboard
|
||||
|
||||
Dashboard theo dõi và thống kê sử dụng CLIProxyAPI - Giám sát token usage, quota, và performance của các tài khoản ChatGPT.
|
||||
|
||||
## 📋 Tính năng
|
||||
|
||||
### 📊 Thống kê tổng quan
|
||||
- **KPI Cards**: Hiển thị tổng số requests, tokens (input/output/reasoning), và failed requests
|
||||
- **Biểu đồ theo giờ**: Theo dõi token usage theo từng giờ
|
||||
- **Biểu đồ theo model**: Phân tích usage theo từng model AI
|
||||
- **Bảng theo tài khoản**: Chi tiết usage của từng tài khoản
|
||||
- **Bảng quota**: Hiển thị hạn mức còn lại (5h và 7d window) của mỗi tài khoản
|
||||
- **Recent requests**: Danh sách các request gần đây với chi tiết
|
||||
|
||||
### 🎨 Giao diện
|
||||
- **Dark/Light mode**: Chuyển đổi theme sáng/tối
|
||||
- **Đa ngôn ngữ**: Hỗ trợ tiếng Anh và tiếng Việt
|
||||
- **Responsive**: Tương thích mobile, tablet, desktop
|
||||
- **Real-time**: Auto-refresh mỗi 30 giây
|
||||
|
||||
### 🔒 Bảo vệ API
|
||||
- **Quota refresh cooldown**: Nút "Refresh Quota" bị khóa 5 phút sau mỗi lần bấm
|
||||
- **Threading lock**: Ngăn chặn multiple concurrent quota refresh calls
|
||||
- **Rate limiting**: Tránh spam ChatGPT API
|
||||
|
||||
## 🚀 Cài đặt
|
||||
|
||||
### Yêu cầu hệ thống
|
||||
- Python 3.8+
|
||||
- Redis server (cho CLIProxyAPI)
|
||||
- SQLite3
|
||||
- Các file auth JSON của ChatGPT (`~/.cliproxyapi/codex-*.json`)
|
||||
|
||||
### Cài đặt dependencies
|
||||
|
||||
```bash
|
||||
# Clone hoặc copy mã nguồn
|
||||
cd ~/cliproxyapi/usage-dashboard/
|
||||
|
||||
# Không cần cài thêm package, script chỉ dùng Python stdlib
|
||||
```
|
||||
|
||||
### Cấu trúc thư mục
|
||||
|
||||
```
|
||||
~/cliproxyapi/usage-dashboard/
|
||||
├── usage-dashboard.py # Backend Python script
|
||||
├── usage-dashboard.html # Frontend HTML
|
||||
├── config.json # Configuration file (tùy chọn)
|
||||
└── usage.db # SQLite database (tự động tạo)
|
||||
|
||||
~/.cliproxyapi/
|
||||
├── codex-account1@gmail.com.json
|
||||
├── codex-account2@gmail.com.json
|
||||
└── ... # Các file auth JSON
|
||||
```
|
||||
|
||||
## ⚙️ Cấu hình
|
||||
|
||||
### File config.json (tùy chọn)
|
||||
|
||||
Nếu không có file này, script sẽ dùng giá trị mặc định:
|
||||
|
||||
```json
|
||||
{
|
||||
"cliproxy_host": "127.0.0.1",
|
||||
"cliproxy_port": 6379,
|
||||
"management_password": "",
|
||||
"poll_interval_seconds": 2,
|
||||
"quota_refresh_seconds": 300,
|
||||
"dashboard_host": "0.0.0.0",
|
||||
"dashboard_port": 8320
|
||||
}
|
||||
```
|
||||
|
||||
**Các tham số:**
|
||||
- `cliproxy_host`: Redis host của CLIProxyAPI
|
||||
- `cliproxy_port`: Redis port (mặc định 6379)
|
||||
- `management_password`: Password cho Redis management channel
|
||||
- `poll_interval_seconds`: Tần suất poll events từ Redis (2 giây)
|
||||
- `quota_refresh_seconds`: Thời gian giữa các lần auto-refresh quota (300 giây = 5 phút) - **Đã tắt auto-refresh**
|
||||
- `dashboard_host`: Host để bind web server
|
||||
- `dashboard_port`: Port cho dashboard (mặc định 8320)
|
||||
|
||||
## 🎯 Sử dụng
|
||||
|
||||
### Khởi động dashboard
|
||||
|
||||
```bash
|
||||
cd ~/cliproxyapi/usage-dashboard/
|
||||
python3 usage-dashboard.py start
|
||||
```
|
||||
|
||||
Dashboard sẽ tự động mở browser tại `http://localhost:8320`
|
||||
|
||||
### Chạy ở background (không mở browser)
|
||||
|
||||
```bash
|
||||
python3 usage-dashboard.py start --no-browser
|
||||
```
|
||||
|
||||
### Dừng dashboard
|
||||
|
||||
```bash
|
||||
# Nếu chạy foreground: Ctrl+C
|
||||
|
||||
# Nếu chạy background:
|
||||
pkill -f usage-dashboard.py
|
||||
```
|
||||
|
||||
### Chạy như systemd service
|
||||
|
||||
Tạo file `/etc/systemd/system/cliproxy-dashboard.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=CLIProxyAPI Usage Dashboard
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=admin
|
||||
WorkingDirectory=/home/admin/cliproxyapi/usage-dashboard
|
||||
ExecStart=/usr/bin/python3 /home/admin/cliproxyapi/usage-dashboard/usage-dashboard.py start --no-browser
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Kích hoạt service:
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable cliproxy-dashboard
|
||||
sudo systemctl start cliproxy-dashboard
|
||||
sudo systemctl status cliproxy-dashboard
|
||||
```
|
||||
|
||||
## 📖 Hướng dẫn sử dụng Dashboard
|
||||
|
||||
### 1. Chọn khoảng thời gian
|
||||
|
||||
Dropdown **Range** cho phép lọc dữ liệu:
|
||||
- **Today**: Hôm nay
|
||||
- **Last 1 hour**: 1 giờ qua
|
||||
- **Last 5 hours**: 5 giờ qua
|
||||
- **Last 24 hours**: 24 giờ qua
|
||||
- **Last 7 days**: 7 ngày qua
|
||||
|
||||
### 2. Refresh dữ liệu
|
||||
|
||||
**Nút "Refresh"** (xám):
|
||||
- Làm mới usage data từ database
|
||||
- Không gọi ChatGPT API
|
||||
- Có thể bấm bất cứ lúc nào
|
||||
|
||||
**Nút "Refresh Quota"** (xanh):
|
||||
- Fetch quota mới từ ChatGPT API cho tất cả tài khoản
|
||||
- **Bị khóa 5 phút** sau mỗi lần bấm (hiển thị countdown)
|
||||
- Chỉ dùng khi cần kiểm tra quota thực tế
|
||||
|
||||
### 3. Đọc hiểu các chỉ số
|
||||
|
||||
**KPI Cards:**
|
||||
- **Requests / Tasks**: Tổng số requests (thành công + thất bại)
|
||||
- **Total Tokens**: Tổng tokens = Input + Output + Reasoning
|
||||
- **Input Tokens**: Tokens đầu vào (prompt)
|
||||
- **Output Tokens**: Tokens đầu ra (response)
|
||||
- **Reasoning Tokens**: Tokens suy luận (o1/o3 models)
|
||||
|
||||
**Quota Table:**
|
||||
- **5h Remaining**: % quota còn lại trong 5 giờ window
|
||||
- **7d Remaining**: % quota còn lại trong 7 ngày window
|
||||
- **Status**:
|
||||
- 🟢 Active: Tài khoản hoạt động bình thường
|
||||
- 🔴 Limited: Đã đạt giới hạn quota
|
||||
- **Reset Time**: Thời gian reset quota (local timezone)
|
||||
|
||||
**Color coding:**
|
||||
- 🟢 Xanh: > 30% quota còn lại
|
||||
- 🟠 Cam: 10-30% quota còn lại
|
||||
- 🔴 Đỏ: < 10% quota còn lại
|
||||
|
||||
### 4. Chuyển đổi theme và ngôn ngữ
|
||||
|
||||
- **🌙 / ☀️**: Toggle Dark/Light mode
|
||||
- **EN / VI**: Chuyển đổi tiếng Anh / tiếng Việt
|
||||
|
||||
Cài đặt được lưu trong browser localStorage.
|
||||
|
||||
## 🔧 Troubleshooting
|
||||
|
||||
### Dashboard không hiển thị dữ liệu
|
||||
|
||||
**Kiểm tra:**
|
||||
1. CLIProxyAPI đang chạy và có events trong Redis queue
|
||||
2. File auth JSON tồn tại trong `~/.cliproxyapi/`
|
||||
3. Database `usage.db` đã được tạo
|
||||
|
||||
```bash
|
||||
# Kiểm tra database
|
||||
sqlite3 ~/cliproxyapi/usage-dashboard/usage.db "SELECT COUNT(*) FROM events;"
|
||||
```
|
||||
|
||||
### Quota không cập nhật
|
||||
|
||||
**Nguyên nhân:**
|
||||
- Nút "Refresh Quota" đang trong cooldown (5 phút)
|
||||
- Access token trong file JSON đã hết hạn
|
||||
- Network timeout khi gọi ChatGPT API
|
||||
|
||||
**Giải pháp:**
|
||||
```bash
|
||||
# Xem log để debug
|
||||
tail -f /var/log/syslog | grep usage-dashboard
|
||||
|
||||
# Hoặc nếu chạy foreground, xem console output
|
||||
```
|
||||
|
||||
### Lỗi "refresh_quota: already running"
|
||||
|
||||
**Nguyên nhân:** Có request khác đang fetch quota (threading lock hoạt động đúng)
|
||||
|
||||
**Giải pháp:** Đợi request hiện tại hoàn tất (thường < 30 giây cho 8 tài khoản)
|
||||
|
||||
### Port 8320 đã được sử dụng
|
||||
|
||||
**Giải pháp:**
|
||||
```bash
|
||||
# Tìm process đang dùng port
|
||||
sudo lsof -i :8320
|
||||
|
||||
# Hoặc đổi port trong config.json
|
||||
{
|
||||
"dashboard_port": 8321
|
||||
}
|
||||
```
|
||||
|
||||
## 🏗️ Kiến trúc hệ thống
|
||||
|
||||
### Backend (usage-dashboard.py)
|
||||
|
||||
**Collector Thread:**
|
||||
- Poll events từ Redis queue mỗi 2 giây
|
||||
- Parse và lưu vào SQLite database
|
||||
- **KHÔNG** tự động refresh quota (tránh spam API)
|
||||
|
||||
**Web Server:**
|
||||
- HTTP server đơn giản (Python http.server)
|
||||
- Serve static HTML và JSON APIs
|
||||
- Endpoints:
|
||||
- `GET /` → usage-dashboard.html
|
||||
- `GET /api/summary?range=<range>` → Usage statistics
|
||||
- `GET /api/quota` → Quota snapshots (từ DB)
|
||||
- `GET /api/quota?force=1` → Force refresh từ ChatGPT API
|
||||
- `GET /api/requests?limit=<n>` → Recent requests
|
||||
|
||||
**Database Schema:**
|
||||
```sql
|
||||
-- Usage events
|
||||
CREATE TABLE events (
|
||||
id INTEGER PRIMARY KEY,
|
||||
timestamp TEXT,
|
||||
ts_epoch REAL,
|
||||
auth_index INTEGER,
|
||||
source TEXT,
|
||||
model TEXT,
|
||||
input_tokens INTEGER,
|
||||
output_tokens INTEGER,
|
||||
reasoning_tokens INTEGER,
|
||||
total_tokens INTEGER,
|
||||
latency_ms INTEGER,
|
||||
failed INTEGER
|
||||
);
|
||||
|
||||
-- Quota snapshots
|
||||
CREATE TABLE quota_snapshots (
|
||||
id INTEGER PRIMARY KEY,
|
||||
timestamp TEXT,
|
||||
ts_epoch REAL,
|
||||
email TEXT,
|
||||
plan TEXT,
|
||||
allowed INTEGER,
|
||||
limit_reached INTEGER,
|
||||
primary_used_percent INTEGER,
|
||||
primary_remaining_percent INTEGER,
|
||||
primary_reset_at TEXT,
|
||||
secondary_used_percent INTEGER,
|
||||
secondary_remaining_percent INTEGER,
|
||||
secondary_reset_at TEXT,
|
||||
credits_balance TEXT,
|
||||
raw_json TEXT
|
||||
);
|
||||
```
|
||||
|
||||
### Frontend (usage-dashboard.html)
|
||||
|
||||
**Single-page application:**
|
||||
- Vanilla JavaScript (no frameworks)
|
||||
- Canvas-based charts (no external libraries)
|
||||
- CSS variables cho theming
|
||||
- LocalStorage cho preferences
|
||||
|
||||
**Auto-refresh:**
|
||||
- Usage data: Mỗi 30 giây
|
||||
- Quota data: Chỉ khi user bấm nút (với 5 phút cooldown)
|
||||
|
||||
## 🔐 Bảo mật
|
||||
|
||||
### Access token protection
|
||||
- Tokens được đọc từ file JSON nhưng **không** được log ra console
|
||||
- Raw JSON trong database có thể chứa sensitive data → Bảo vệ file `usage.db`
|
||||
|
||||
### Recommendations
|
||||
```bash
|
||||
# Set proper permissions
|
||||
chmod 600 ~/.cliproxyapi/*.json
|
||||
chmod 600 ~/cliproxyapi/usage-dashboard/usage.db
|
||||
chmod 700 ~/.cliproxyapi/
|
||||
```
|
||||
|
||||
### Network security
|
||||
- Dashboard mặc định bind `0.0.0.0:8320` (accessible từ mạng)
|
||||
- Nếu chỉ dùng local: Đổi `dashboard_host` thành `127.0.0.1`
|
||||
- Hoặc dùng reverse proxy (nginx) với authentication
|
||||
|
||||
## 📊 Performance
|
||||
|
||||
### Resource usage
|
||||
- **Memory**: ~50-100 MB (Python process)
|
||||
- **CPU**: < 1% (idle), ~5% (khi refresh quota)
|
||||
- **Disk**: Database size ~1 MB / 10,000 events
|
||||
- **Network**: Minimal (chỉ khi refresh quota)
|
||||
|
||||
### Scalability
|
||||
- Tested với 8 tài khoản ChatGPT
|
||||
- Database có thể handle hàng triệu events
|
||||
- Quota refresh: ~3-5 giây / tài khoản (sequential)
|
||||
|
||||
## 🛠️ Development
|
||||
|
||||
### Thêm tính năng mới
|
||||
|
||||
**Backend API endpoint:**
|
||||
```python
|
||||
# Trong usage-dashboard.py, thêm vào handle_api()
|
||||
elif path == '/api/custom':
|
||||
data = {"result": "custom data"}
|
||||
self.send_json(data)
|
||||
```
|
||||
|
||||
**Frontend:**
|
||||
```javascript
|
||||
// Trong usage-dashboard.html
|
||||
async function loadCustomData() {
|
||||
const data = await getJSON('/api/custom');
|
||||
console.log(data);
|
||||
}
|
||||
```
|
||||
|
||||
### Debug mode
|
||||
|
||||
Thêm logging chi tiết:
|
||||
```python
|
||||
# Trong refresh_quota(), đã có 6 logging points
|
||||
print(f"refresh_quota: found {len(files)} auth files", flush=True)
|
||||
print(f"refresh_quota: fetching quota for {email}...", flush=True)
|
||||
print(f"refresh_quota: saved quota for {email}", flush=True)
|
||||
```
|
||||
|
||||
## 📝 Changelog
|
||||
|
||||
### Version 2.0 (2025-05-21)
|
||||
- ✅ Thêm threading lock cho `refresh_quota()` (tránh concurrent calls)
|
||||
- ✅ Tắt auto-refresh quota trong collector thread
|
||||
- ✅ Frontend: 5-minute cooldown cho nút "Refresh Quota"
|
||||
- ✅ Đổi thứ tự nút: "Refresh Quota" trước "Refresh"
|
||||
- ✅ Thêm footer với copyright và link TTAI Solutions
|
||||
- ✅ Thêm icon 📊 vào header
|
||||
- ✅ Fix RPOP protocol issue (loop individual calls)
|
||||
- ✅ Tách `JSON_DIR` và `BASE_DIR` cho auth files
|
||||
|
||||
### Version 1.0 (Initial)
|
||||
- ✅ Basic usage tracking và quota monitoring
|
||||
- ✅ Dark/Light theme
|
||||
- ✅ Bilingual support (EN/VI)
|
||||
- ✅ Canvas charts
|
||||
- ✅ SQLite storage
|
||||
|
||||
## 📞 Hỗ trợ
|
||||
|
||||
**Developed by:** TTAI Solutions Software
|
||||
**Website:** [https://ttaisolutions.com](https://ttaisolutions.com)
|
||||
**Copyright:** 2025 - CLIProxyAPI Usage Dashboard
|
||||
|
||||
---
|
||||
|
||||
## 📄 License
|
||||
|
||||
Proprietary software. All rights reserved.
|
||||
|
||||
---
|
||||
|
||||
**Lưu ý:** Dashboard này được thiết kế để hoạt động với CLIProxyAPI. Đảm bảo CLIProxyAPI đang chạy và có events trong Redis queue trước khi khởi động dashboard.
|
||||
Reference in New Issue
Block a user