{searchTerm ? '没有找到匹配的网站' : '还没有添加任何监控网站'}
- {!searchTerm && ( + {!searchTerm && !readOnly && ( )} + {!searchTerm && readOnly && ( +站点由管理员在「管理后台」维护
+ )}From aff88ba97d66b510409c24cf6997f7569259a368 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=A0=91=E8=90=8C=E8=8A=BD?= <3205788256@qq.com>
Date: Sat, 16 May 2026 19:03:32 +0800
Subject: [PATCH] chore: sync local updates
---
AGENTS.md | 4 +-
mengyaping-backend/.gitignore | 3 +
mengyaping-backend/Dockerfile | 45 +-
mengyaping-backend/build-linux-amd64.bat | 35 +
mengyaping-backend/cmd/importjson/main.go | 136 +
mengyaping-backend/config/config.go | 269 +-
mengyaping-backend/config/database.go | 25 +
mengyaping-backend/config/monitor_interval.go | 38 +
.../config/monitor_interval_test.go | 24 +
mengyaping-backend/data/.gitkeep | 0
mengyaping-backend/data/config.json | 13 -
mengyaping-backend/data/groups.json | 18 -
mengyaping-backend/data/records.json | 9735 -----------------
mengyaping-backend/data/websites.json | 821 --
mengyaping-backend/docker-compose.yml | 8 +-
mengyaping-backend/go.mod | 8 +
mengyaping-backend/go.sum | 40 +
mengyaping-backend/handlers/settings.go | 87 +
mengyaping-backend/handlers/website.go | 466 +-
mengyaping-backend/main.go | 97 +-
mengyaping-backend/middleware/admin.go | 43 +
mengyaping-backend/models/website.go | 230 +-
mengyaping-backend/router/router.go | 117 +-
mengyaping-backend/schema/mysql.sql | 19 +
mengyaping-backend/services/monitor.go | 906 +-
mengyaping-backend/services/website.go | 319 +-
mengyaping-backend/storage/app_config.go | 161 +
mengyaping-backend/storage/db_kv.go | 14 +
mengyaping-backend/storage/db_models.go | 93 +
mengyaping-backend/storage/kv.go | 62 +
mengyaping-backend/storage/probe.go | 295 +
mengyaping-backend/storage/storage.go | 667 +-
mengyaping-backend/utils/intranet.go | 37 +
mengyaping-backend/utils/intranet_test.go | 24 +
mengyaping-frontend/package-lock.json | 70 +-
mengyaping-frontend/package.json | 3 +-
mengyaping-frontend/src/App.jsx | 15 +-
.../src/components/AdminGroupsPanel.jsx | 179 +
.../src/components/RandomBackdrop.jsx | 57 +
.../src/components/StatsCard.jsx | 6 -
.../src/components/WebsiteCard.jsx | 91 +-
mengyaping-frontend/src/constants/events.js | 2 +
mengyaping-frontend/src/main.jsx | 5 +-
mengyaping-frontend/src/pages/AdminPanel.jsx | 206 +
mengyaping-frontend/src/pages/Dashboard.jsx | 221 +-
.../src/pages/PublicDashboard.jsx | 5 +
mengyaping-frontend/src/services/api.js | 107 +-
47 files changed, 3651 insertions(+), 12175 deletions(-)
create mode 100644 mengyaping-backend/.gitignore
create mode 100644 mengyaping-backend/build-linux-amd64.bat
create mode 100644 mengyaping-backend/cmd/importjson/main.go
create mode 100644 mengyaping-backend/config/database.go
create mode 100644 mengyaping-backend/config/monitor_interval.go
create mode 100644 mengyaping-backend/config/monitor_interval_test.go
create mode 100644 mengyaping-backend/data/.gitkeep
delete mode 100644 mengyaping-backend/data/config.json
delete mode 100644 mengyaping-backend/data/groups.json
delete mode 100644 mengyaping-backend/data/records.json
delete mode 100644 mengyaping-backend/data/websites.json
create mode 100644 mengyaping-backend/handlers/settings.go
create mode 100644 mengyaping-backend/middleware/admin.go
create mode 100644 mengyaping-backend/schema/mysql.sql
create mode 100644 mengyaping-backend/storage/app_config.go
create mode 100644 mengyaping-backend/storage/db_kv.go
create mode 100644 mengyaping-backend/storage/db_models.go
create mode 100644 mengyaping-backend/storage/kv.go
create mode 100644 mengyaping-backend/storage/probe.go
create mode 100644 mengyaping-backend/utils/intranet.go
create mode 100644 mengyaping-backend/utils/intranet_test.go
create mode 100644 mengyaping-frontend/src/components/AdminGroupsPanel.jsx
create mode 100644 mengyaping-frontend/src/components/RandomBackdrop.jsx
create mode 100644 mengyaping-frontend/src/constants/events.js
create mode 100644 mengyaping-frontend/src/pages/AdminPanel.jsx
create mode 100644 mengyaping-frontend/src/pages/PublicDashboard.jsx
diff --git a/AGENTS.md b/AGENTS.md
index f5733d8..e6895df 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -5,7 +5,7 @@ This repository is split into two apps:
- `mengyaping-frontend/`: React + Vite UI. Main code is in `src/` (`components/`, `pages/`, `hooks/`, `services/`), with static assets in `public/`.
- `mengyaping-backend/`: Go + Gin API and monitor service. Core folders are `handlers/`, `services/`, `router/`, `models/`, `storage/`, `config/`, and `utils/`.
-Runtime data is persisted under `mengyaping-backend/data/` (`websites.json`, `records.json`, `groups.json`, `config.json`). Keep data format changes backward-compatible.
+Runtime site/group data is in MySQL. Optional `mengyaping-backend/data/` is only for local tooling (e.g. `cmd/importjson` reading `websites.json` / `groups.json`). App settings and admin token live in table `monitor_kv`.
## Build, Test, and Development Commands
Frontend (run inside `mengyaping-frontend/`):
@@ -44,4 +44,4 @@ Each PR should include:
## Security & Configuration Tips
- Do not commit secrets, tokens, or private endpoints.
- Frontend dev API target is `http://localhost:8080/api` in `mengyaping-frontend/src/services/api.js`.
-- Commit only sanitized sample data in `mengyaping-backend/data/`.
+- Commit only sanitized sample data in `mengyaping-backend/data/`.
diff --git a/mengyaping-backend/.gitignore b/mengyaping-backend/.gitignore
new file mode 100644
index 0000000..fbe4284
--- /dev/null
+++ b/mengyaping-backend/.gitignore
@@ -0,0 +1,3 @@
+# 本地交叉编译产物(部署时再生成)
+dist/mengyaping-backend
+dist/mengyaping-backend.exe
diff --git a/mengyaping-backend/Dockerfile b/mengyaping-backend/Dockerfile
index f1566ec..a66a9d1 100644
--- a/mengyaping-backend/Dockerfile
+++ b/mengyaping-backend/Dockerfile
@@ -1,56 +1,31 @@
-# 多阶段构建 - 使用官方 Golang 镜像作为构建环境
-FROM golang:1.25-alpine AS builder
+# 生产镜像:使用本机预编译的 Linux amd64 二进制(避免在服务器 docker build 时再跑 go build)
+# Windows: 先双击运行 build-linux-amd64.bat,生成 dist/mengyaping-backend 后再执行:
+# docker compose build
+# 若需在容器内编译,请使用: docker build -f Dockerfile.source .
-# 设置工作目录
-WORKDIR /app
+FROM alpine:3.21
-# 安装必要的构建工具
-RUN apk add --no-cache git ca-certificates tzdata
+RUN apk --no-cache add ca-certificates tzdata wget
-# 复制 go.mod 和 go.sum 文件
-COPY go.mod go.sum ./
-
-# 下载依赖
-RUN go mod download
-
-# 复制源代码
-COPY . .
-
-# 构建应用程序
-RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo -o mengyaping-backend .
-
-# 使用轻量级的 alpine 镜像作为运行环境
-FROM alpine:latest
-
-# 安装必要的运行时依赖
-RUN apk --no-cache add ca-certificates tzdata
-
-# 设置时区为上海
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" > /etc/timezone
-# 创建非 root 用户
RUN addgroup -g 1000 appuser && \
adduser -D -u 1000 -G appuser appuser
-# 设置工作目录
WORKDIR /app
-# 从构建阶段复制编译好的二进制文件
-COPY --from=builder /app/mengyaping-backend .
+COPY dist/mengyaping-backend /app/mengyaping-backend
-# 创建数据目录
-RUN mkdir -p /app/data && chown -R appuser:appuser /app
+RUN chmod +x /app/mengyaping-backend && \
+ mkdir -p /app/data && \
+ chown -R appuser:appuser /app
-# 切换到非 root 用户
USER appuser
-# 暴露端口
EXPOSE 8080
-# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/api/health || exit 1
-# 运行应用程序
CMD ["./mengyaping-backend"]
diff --git a/mengyaping-backend/build-linux-amd64.bat b/mengyaping-backend/build-linux-amd64.bat
new file mode 100644
index 0000000..9b6b8ed
--- /dev/null
+++ b/mengyaping-backend/build-linux-amd64.bat
@@ -0,0 +1,35 @@
+@echo off
+chcp 65001 >nul 2>&1
+setlocal
+cd /d "%~dp0"
+
+where go >nul 2>nul
+if errorlevel 1 (
+ echo [ERROR] Go not found in PATH. Install Go and reopen the terminal.
+ pause
+ exit /b 1
+)
+
+set "DIST=dist"
+if not exist "%DIST%" mkdir "%DIST%"
+
+set "GOOS=linux"
+set "GOARCH=amd64"
+set "CGO_ENABLED=0"
+
+echo Cross-compile linux/amd64 -^> "%DIST%\mengyaping-backend"
+go version
+go build -trimpath -ldflags="-s -w" -o "%DIST%\mengyaping-backend" .
+if errorlevel 1 (
+ echo.
+ echo [ERROR] go build failed. See messages above.
+ echo Tips: go.mod requires Go 1.25+; run from mengyaping-backend folder.
+ pause
+ exit /b 1
+)
+
+echo.
+echo [OK] "%CD%\%DIST%\mengyaping-backend"
+echo Next: copy this folder to server, then: docker compose build
+endlocal
+exit /b 0
diff --git a/mengyaping-backend/cmd/importjson/main.go b/mengyaping-backend/cmd/importjson/main.go
new file mode 100644
index 0000000..e2dcc32
--- /dev/null
+++ b/mengyaping-backend/cmd/importjson/main.go
@@ -0,0 +1,136 @@
+// 将 data/*.json(站点与分组)导入 MySQL。建议空库首次使用,或加 -wipe 清空业务表后再导。
+//
+// go run ./cmd/importjson -data ./data -wipe
+package main
+
+import (
+ "encoding/json"
+ "flag"
+ "fmt"
+ "log"
+ "os"
+ "path/filepath"
+
+ "gorm.io/datatypes"
+ "gorm.io/driver/mysql"
+ "gorm.io/gorm"
+ "gorm.io/gorm/logger"
+
+ "mengyaping-backend/config"
+ "mengyaping-backend/models"
+ "mengyaping-backend/storage"
+)
+
+func main() {
+ dataDir := flag.String("data", "./data", "JSON 目录(websites.json、groups.json)")
+ wipe := flag.Bool("wipe", false, "导入前 TRUNCATE 所有 monitor_* 表(慎用)")
+ flag.Parse()
+
+ cfg := config.GetConfig()
+ // 大批量 INSERT 时单条超过 200ms 会触发 GORM 默认「SLOW SQL」提示,易被误认为报错;导入工具改为静默 SQL 日志
+ db, err := gorm.Open(mysql.Open(cfg.DatabaseDSN()), &gorm.Config{
+ Logger: logger.Default.LogMode(logger.Silent),
+ })
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ if err := db.AutoMigrate(
+ &storage.MonitorGroup{},
+ &storage.MonitorWebsite{},
+ &storage.MonitorWebsiteURL{},
+ &storage.MonitorWebsiteGroup{},
+ &storage.MonitorProbeLatest{},
+ &storage.MonitorProbeHour{},
+ &storage.MonitorProbeDay{},
+ &storage.MonitorKV{},
+ ); err != nil {
+ log.Fatal(err)
+ }
+
+ if *wipe {
+ _ = db.Exec("SET FOREIGN_KEY_CHECKS = 0").Error
+ for _, tbl := range []string{
+ "monitor_probe_latest",
+ "monitor_probe_hour",
+ "monitor_probe_day",
+ "monitor_kv",
+ "monitor_checks",
+ "monitor_website_urls",
+ "monitor_website_groups",
+ "monitor_websites",
+ "monitor_groups",
+ } {
+ _ = db.Exec("TRUNCATE TABLE " + tbl).Error
+ }
+ _ = db.Exec("SET FOREIGN_KEY_CHECKS = 1").Error
+ log.Println("已清空 monitor_* 表")
+ }
+
+ websitesPath := filepath.Join(*dataDir, "websites.json")
+ raw, err := os.ReadFile(websitesPath)
+ if err != nil {
+ log.Fatalf("读取 websites.json: %v", err)
+ }
+ var websites []models.Website
+ if err := json.Unmarshal(raw, &websites); err != nil {
+ log.Fatal(err)
+ }
+
+ groupsPath := filepath.Join(*dataDir, "groups.json")
+ var fileGroups []models.Group
+ if g, err := os.ReadFile(groupsPath); err == nil {
+ _ = json.Unmarshal(g, &fileGroups)
+ }
+ if len(fileGroups) == 0 {
+ fileGroups = models.DefaultGroups
+ }
+ for i, g := range fileGroups {
+ if err := db.Create(&storage.MonitorGroup{
+ ID: g.ID, Name: g.Name, SortOrder: i + 1,
+ }).Error; err != nil {
+ log.Printf("导入分组 %s: %v", g.ID, err)
+ }
+ }
+
+ for _, w := range websites {
+ if len(w.Groups) == 0 && w.Group != "" {
+ w.Groups = []string{w.Group}
+ }
+ row := &storage.MonitorWebsite{
+ ID: w.ID,
+ Name: w.Name,
+ LegacyGroup: "",
+ Favicon: w.Favicon,
+ Title: w.Title,
+ IPAddresses: datatypes.JSON(mustJSON(w.IPAddresses)),
+ CreatedAt: w.CreatedAt,
+ UpdatedAt: w.UpdatedAt,
+ }
+ if err := db.Create(row).Error; err != nil {
+ log.Printf("网站 %s: %v", w.ID, err)
+ continue
+ }
+ for i, u := range w.URLs {
+ _ = db.Create(&storage.MonitorWebsiteURL{
+ WebsiteID: w.ID, URLID: u.ID, URL: u.URL, Remark: u.Remark, SortOrder: i,
+ })
+ }
+ for _, gid := range w.Groups {
+ _ = db.Create(&storage.MonitorWebsiteGroup{WebsiteID: w.ID, GroupID: gid})
+ }
+ }
+ fmt.Printf("已导入 %d 个网站\n", len(websites))
+ log.Println("探测历史由运行时写入 monitor_probe_* 汇总表,不再从 records.json 导入")
+}
+
+func mustJSON(v []string) []byte {
+ if v == nil {
+ return []byte("[]")
+ }
+ b, err := json.Marshal(v)
+ if err != nil {
+ return []byte("[]")
+ }
+ return b
+}
diff --git a/mengyaping-backend/config/config.go b/mengyaping-backend/config/config.go
index 1f66719..a6a2ffd 100644
--- a/mengyaping-backend/config/config.go
+++ b/mengyaping-backend/config/config.go
@@ -1,176 +1,93 @@
-package config
-
-import (
- "encoding/json"
- "fmt"
- "os"
- "sync"
- "time"
-)
-
-// Config 应用配置
-type Config struct {
- Server ServerConfig `json:"server"`
- Monitor MonitorConfig `json:"monitor"`
- DataPath string `json:"data_path"`
-}
-
-// ServerConfig 服务器配置
-type ServerConfig struct {
- Port string `json:"port"`
- Host string `json:"host"`
-}
-
-// MonitorConfig 监控配置
-type MonitorConfig struct {
- Interval time.Duration `json:"interval"` // 检测间隔
- Timeout time.Duration `json:"timeout"` // 请求超时时间
- RetryCount int `json:"retry_count"` // 重试次数
- HistoryDays int `json:"history_days"` // 保留历史天数
-}
-
-var (
- cfg *Config
- once sync.Once
-)
-
-// GetConfig 获取配置单例
-func GetConfig() *Config {
- once.Do(func() {
- cfg = &Config{
- Server: ServerConfig{
- Port: getEnv("SERVER_PORT", "8080"),
- Host: getEnv("SERVER_HOST", "0.0.0.0"),
- },
- Monitor: MonitorConfig{
- Interval: parseDuration(getEnv("MONITOR_INTERVAL", "1h"), 1*time.Hour),
- Timeout: parseDuration(getEnv("MONITOR_TIMEOUT", "10s"), 10*time.Second),
- RetryCount: parseInt(getEnv("MONITOR_RETRY_COUNT", "3"), 3),
- HistoryDays: parseInt(getEnv("MONITOR_HISTORY_DAYS", "90"), 90),
- },
- DataPath: getEnv("DATA_PATH", "./data"),
- }
-
- // 尝试从配置文件加载(会覆盖环境变量配置)
- loadConfigFromFile()
- })
- return cfg
-}
-
-// getEnv 获取环境变量,如果不存在则返回默认值
-func getEnv(key, defaultValue string) string {
- if value := os.Getenv(key); value != "" {
- return value
- }
- return defaultValue
-}
-
-// parseInt 解析整数环境变量
-func parseInt(value string, defaultValue int) int {
- if value == "" {
- return defaultValue
- }
- var result int
- if _, err := fmt.Sscanf(value, "%d", &result); err != nil {
- return defaultValue
- }
- return result
-}
-
-// parseDuration 解析时间间隔环境变量
-func parseDuration(value string, defaultValue time.Duration) time.Duration {
- if value == "" {
- return defaultValue
- }
- if duration, err := time.ParseDuration(value); err == nil {
- return duration
- }
- return defaultValue
-}
-
-// loadConfigFromFile 从文件加载配置
-func loadConfigFromFile() {
- configFile := "./data/config.json"
- if _, err := os.Stat(configFile); os.IsNotExist(err) {
- return
- }
-
- data, err := os.ReadFile(configFile)
- if err != nil {
- return
- }
-
- var fileCfg struct {
- Server ServerConfig `json:"server"`
- Monitor struct {
- IntervalMinutes int `json:"interval_minutes"`
- TimeoutSeconds int `json:"timeout_seconds"`
- RetryCount int `json:"retry_count"`
- HistoryDays int `json:"history_days"`
- } `json:"monitor"`
- DataPath string `json:"data_path"`
- }
-
- if err := json.Unmarshal(data, &fileCfg); err != nil {
- return
- }
-
- if fileCfg.Server.Port != "" {
- cfg.Server.Port = fileCfg.Server.Port
- }
- if fileCfg.Server.Host != "" {
- cfg.Server.Host = fileCfg.Server.Host
- }
- if fileCfg.Monitor.IntervalMinutes > 0 {
- cfg.Monitor.Interval = time.Duration(fileCfg.Monitor.IntervalMinutes) * time.Minute
- }
- if fileCfg.Monitor.TimeoutSeconds > 0 {
- cfg.Monitor.Timeout = time.Duration(fileCfg.Monitor.TimeoutSeconds) * time.Second
- }
- if fileCfg.Monitor.RetryCount > 0 {
- cfg.Monitor.RetryCount = fileCfg.Monitor.RetryCount
- }
- if fileCfg.Monitor.HistoryDays > 0 {
- cfg.Monitor.HistoryDays = fileCfg.Monitor.HistoryDays
- }
- if fileCfg.DataPath != "" {
- cfg.DataPath = fileCfg.DataPath
- }
-}
-
-// SaveConfig 保存配置到文件
-func SaveConfig() error {
- configFile := cfg.DataPath + "/config.json"
-
- fileCfg := struct {
- Server ServerConfig `json:"server"`
- Monitor struct {
- IntervalMinutes int `json:"interval_minutes"`
- TimeoutSeconds int `json:"timeout_seconds"`
- RetryCount int `json:"retry_count"`
- HistoryDays int `json:"history_days"`
- } `json:"monitor"`
- DataPath string `json:"data_path"`
- }{
- Server: cfg.Server,
- Monitor: struct {
- IntervalMinutes int `json:"interval_minutes"`
- TimeoutSeconds int `json:"timeout_seconds"`
- RetryCount int `json:"retry_count"`
- HistoryDays int `json:"history_days"`
- }{
- IntervalMinutes: int(cfg.Monitor.Interval.Minutes()),
- TimeoutSeconds: int(cfg.Monitor.Timeout.Seconds()),
- RetryCount: cfg.Monitor.RetryCount,
- HistoryDays: cfg.Monitor.HistoryDays,
- },
- DataPath: cfg.DataPath,
- }
-
- data, err := json.MarshalIndent(fileCfg, "", " ")
- if err != nil {
- return err
- }
-
- return os.WriteFile(configFile, data, 0644)
-}
+package config
+
+import (
+ "fmt"
+ "os"
+ "sync"
+ "time"
+)
+
+// Config 应用配置(持久化在 MySQL monitor_kv,首次启动前由环境变量提供默认值;MySQL 连接信息首次连接仍依赖环境变量/DB_DSN)
+type Config struct {
+ Server ServerConfig `json:"server"`
+ Monitor MonitorConfig `json:"monitor"`
+ DataPath string `json:"data_path"`
+ Database DatabaseConfig `json:"database"`
+}
+
+// ServerConfig 服务器配置
+type ServerConfig struct {
+ Port string `json:"port"`
+ Host string `json:"host"`
+}
+
+// MonitorConfig 监控配置
+type MonitorConfig struct {
+ Interval time.Duration `json:"interval"` // 检测间隔
+ Timeout time.Duration `json:"timeout"` // 请求超时时间
+ RetryCount int `json:"retry_count"` // 重试次数
+ HistoryDays int `json:"history_days"` // 保留历史天数
+}
+
+var (
+ cfg *Config
+ once sync.Once
+)
+
+// GetConfig 获取配置单例(连接 MySQL 后由 storage 根据 monitor_kv 覆盖)
+func GetConfig() *Config {
+ once.Do(func() {
+ cfg = &Config{
+ Server: ServerConfig{
+ Port: getEnv("SERVER_PORT", "8080"),
+ Host: getEnv("SERVER_HOST", "0.0.0.0"),
+ },
+ Monitor: MonitorConfig{
+ Interval: parseDuration(getEnv("MONITOR_INTERVAL", "30m"), 30*time.Minute),
+ Timeout: parseDuration(getEnv("MONITOR_TIMEOUT", "10s"), 10*time.Second),
+ RetryCount: parseInt(getEnv("MONITOR_RETRY_COUNT", "3"), 3),
+ HistoryDays: parseInt(getEnv("MONITOR_HISTORY_DAYS", "90"), 90),
+ },
+ DataPath: getEnv("DATA_PATH", "./data"),
+ Database: DatabaseConfig{
+ Host: getEnv("DB_HOST", "192.168.1.100"),
+ Port: getEnv("DB_PORT", "3306"),
+ User: getEnv("DB_USER", "mengyaping"),
+ Password: getEnv("DB_PASSWORD", "mengyaping"),
+ Database: getEnv("DB_NAME", "mengyaping"),
+ },
+ }
+ })
+ return cfg
+}
+
+// getEnv 获取环境变量,如果不存在则返回默认值
+func getEnv(key, defaultValue string) string {
+ if value := os.Getenv(key); value != "" {
+ return value
+ }
+ return defaultValue
+}
+
+// parseInt 解析整数环境变量
+func parseInt(value string, defaultValue int) int {
+ if value == "" {
+ return defaultValue
+ }
+ var result int
+ if _, err := fmt.Sscanf(value, "%d", &result); err != nil {
+ return defaultValue
+ }
+ return result
+}
+
+// parseDuration 解析时间间隔环境变量
+func parseDuration(value string, defaultValue time.Duration) time.Duration {
+ if value == "" {
+ return defaultValue
+ }
+ if duration, err := time.ParseDuration(value); err == nil {
+ return duration
+ }
+ return defaultValue
+}
diff --git a/mengyaping-backend/config/database.go b/mengyaping-backend/config/database.go
new file mode 100644
index 0000000..ff0dfbd
--- /dev/null
+++ b/mengyaping-backend/config/database.go
@@ -0,0 +1,25 @@
+package config
+
+import (
+ "fmt"
+ "os"
+)
+
+// DatabaseConfig MySQL 连接(环境变量 DB_* 可覆盖;亦支持 DB_DSN 整串)
+type DatabaseConfig struct {
+ Host string `json:"host"`
+ Port string `json:"port"`
+ User string `json:"user"`
+ Password string `json:"password"`
+ Database string `json:"database"`
+}
+
+// DatabaseDSN 返回 GORM/MySQL driver 用连接串
+func (c *Config) DatabaseDSN() string {
+ if dsn := os.Getenv("DB_DSN"); dsn != "" {
+ return dsn
+ }
+ d := c.Database
+ return fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
+ d.User, d.Password, d.Host, d.Port, d.Database)
+}
diff --git a/mengyaping-backend/config/monitor_interval.go b/mengyaping-backend/config/monitor_interval.go
new file mode 100644
index 0000000..165271f
--- /dev/null
+++ b/mengyaping-backend/config/monitor_interval.go
@@ -0,0 +1,38 @@
+package config
+
+import "slices"
+
+// AllowedMonitorIntervalMinutes 后台预设的全局检测周期(分钟)
+var AllowedMonitorIntervalMinutes = []int{10, 20, 30, 60, 180, 360}
+
+// IsAllowedMonitorInterval 是否为允许的检测间隔(分钟)
+func IsAllowedMonitorInterval(minutes int) bool {
+ return minutes > 0 && slices.Contains(AllowedMonitorIntervalMinutes, minutes)
+}
+
+// SnapMonitorIntervalMinutes 将分钟数裁剪到最近的预设值(用于读取旧配置)
+func SnapMonitorIntervalMinutes(minutes int) int {
+ if minutes <= 0 {
+ return 30
+ }
+ if IsAllowedMonitorInterval(minutes) {
+ return minutes
+ }
+ best := AllowedMonitorIntervalMinutes[0]
+ bestDist := absInt(minutes - best)
+ for _, v := range AllowedMonitorIntervalMinutes[1:] {
+ d := absInt(minutes - v)
+ if d < bestDist {
+ bestDist = d
+ best = v
+ }
+ }
+ return best
+}
+
+func absInt(x int) int {
+ if x < 0 {
+ return -x
+ }
+ return x
+}
diff --git a/mengyaping-backend/config/monitor_interval_test.go b/mengyaping-backend/config/monitor_interval_test.go
new file mode 100644
index 0000000..ba3a0ff
--- /dev/null
+++ b/mengyaping-backend/config/monitor_interval_test.go
@@ -0,0 +1,24 @@
+package config
+
+import "testing"
+
+func TestIsAllowedMonitorInterval(t *testing.T) {
+ if !IsAllowedMonitorInterval(10) || !IsAllowedMonitorInterval(360) {
+ t.Fatal("expected 10 and 360 allowed")
+ }
+ if IsAllowedMonitorInterval(5) || IsAllowedMonitorInterval(45) {
+ t.Fatal("expected 5 and 45 disallowed")
+ }
+}
+
+func TestSnapMonitorIntervalMinutes(t *testing.T) {
+ if SnapMonitorIntervalMinutes(5) != 10 {
+ t.Fatalf("5 -> 10, got %d", SnapMonitorIntervalMinutes(5))
+ }
+ if SnapMonitorIntervalMinutes(7) != 10 {
+ t.Fatalf("7 -> 10, got %d", SnapMonitorIntervalMinutes(7))
+ }
+ if SnapMonitorIntervalMinutes(25) != 20 {
+ t.Fatalf("25 -> 20, got %d", SnapMonitorIntervalMinutes(25))
+ }
+}
diff --git a/mengyaping-backend/data/.gitkeep b/mengyaping-backend/data/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/mengyaping-backend/data/config.json b/mengyaping-backend/data/config.json
deleted file mode 100644
index 85ccd04..0000000
--- a/mengyaping-backend/data/config.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "server": {
- "port": "8080",
- "host": "0.0.0.0"
- },
- "monitor": {
- "interval_minutes": 5,
- "timeout_seconds": 10,
- "retry_count": 3,
- "history_days": 7
- },
- "data_path": "./data"
-}
diff --git a/mengyaping-backend/data/groups.json b/mengyaping-backend/data/groups.json
deleted file mode 100644
index 43108ab..0000000
--- a/mengyaping-backend/data/groups.json
+++ /dev/null
@@ -1,18 +0,0 @@
-[
- {
- "id": "self-made",
- "name": "自制网站"
- },
- {
- "id": "self-deploy",
- "name": "自部署网站"
- },
- {
- "id": "admin",
- "name": "管理员网站"
- },
- {
- "id": "api",
- "name": "API网站"
- }
-]
\ No newline at end of file
diff --git a/mengyaping-backend/data/records.json b/mengyaping-backend/data/records.json
deleted file mode 100644
index 089d94d..0000000
--- a/mengyaping-backend/data/records.json
+++ /dev/null
@@ -1,9735 +0,0 @@
-{
- "188cb48c619bd5d896bff546_d19b0a475334": [
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 213,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.3518219+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 60,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.4190076+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 107,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.4668528+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 53,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.0861888+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 59,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.0121422+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 54,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.0762431+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 68,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.0535498+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 69,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.1878862+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 76,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.0282947+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 91,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.0427496+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 85,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:25.3437809+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 197,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:36.1247216+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 67,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:36.0051672+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 82,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:36.013936+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:35.9928867+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 68,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:48.2096529+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 75,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:37.5730538+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:35.9972463+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:37.6175615+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 577,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:24.7306178+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 76,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:51:41.7880262+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 87,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:56:29.785254+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 73,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:01:29.7749925+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:06:29.7613995+08:00"
- },
- {
- "website_id": "188cb48c619bd5d896bff546",
- "url_id": "d19b0a475334",
- "url": "https://shumengya.top",
- "status_code": 200,
- "latency": 81,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:11:29.7778361+08:00"
- }
- ],
- "188cb49298d72b78a37301a1_9d25ae024f36": [
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 176,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.3145844+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 71,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.4236596+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 191,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.5529677+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 55,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.0969356+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 164,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.1167747+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 59,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.0865817+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 61,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.012316+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 62,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.0136053+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 67,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.1667614+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 61,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.117091+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 167,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:25.4258532+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 58,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:37.3768431+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 89,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:36.0273499+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 88,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:36.0192552+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 49,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.8294284+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 69,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:36.0062434+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 67,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:37.4963488+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 59,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:36.235684+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 59,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:35.9878827+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 601,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:24.1534192+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 80,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:51:42.8726981+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 62,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:56:30.8531004+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 80,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:01:30.8566235+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 91,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:06:30.8545324+08:00"
- },
- {
- "website_id": "188cb49298d72b78a37301a1",
- "url_id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "status_code": 200,
- "latency": 63,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:11:30.8471418+08:00"
- }
- ],
- "188cb52c04cf639cfc2c8ba4_cfe6229fb86b": [
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 94,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.2343529+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.4693623+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 62,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.5369688+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 185,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.1360089+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 61,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.1242615+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 60,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.122983+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.0664754+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 63,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.1478068+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.1924443+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 65,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.1508737+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 93,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:25.3524472+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 56,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:37.4336716+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 76,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:36.0144262+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 88,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:36.0198598+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 62,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.7800465+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 66,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:36.3228889+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 72,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:37.8844494+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 63,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:35.9911733+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 69,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:35.9988544+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 65,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:25.6839804+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 60,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:51:43.942245+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 75,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:56:31.9290912+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 65,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:01:31.9227419+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 61,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:06:31.916946+08:00"
- },
- {
- "website_id": "188cb52c04cf639cfc2c8ba4",
- "url_id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "status_code": 200,
- "latency": 81,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:11:31.9293141+08:00"
- }
- ],
- "188cb53623f46b7872bf17b6_b53594e7285d": [
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 218,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.35668+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.2094343+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 81,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.6188928+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 76,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.026826+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 80,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.1576909+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 69,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.1340808+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 81,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.0311078+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 168,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.1179367+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 71,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.1947148+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 87,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.185041+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 103,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:25.3623345+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:37.4991479+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 87,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:36.0251315+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 104,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:36.0351928+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 73,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:37.8692712+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 73,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:36.0108645+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 80,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:37.9647051+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 69,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:35.9978678+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:35.9987935+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 796,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:22.6029862+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 83,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:51:45.0298267+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 83,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:56:33.0129026+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 181,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:01:33.1054077+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 75,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:06:32.9932873+08:00"
- },
- {
- "website_id": "188cb53623f46b7872bf17b6",
- "url_id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "status_code": 200,
- "latency": 81,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:11:33.0152668+08:00"
- }
- ],
- "188cb54b93ddd1e487bf347e_46d822694242": [
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 401,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.5401869+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 263,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.4039563+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 387,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.7478334+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 261,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.2894545+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 268,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.3522388+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 262,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.3288223+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 267,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.3434381+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 265,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.3563323+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 254,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.4016966+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 265,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.3176474+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 425,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:25.6848829+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 275,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:37.3173115+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 273,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:36.2118334+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 292,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:36.2243852+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 278,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.2076744+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 268,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:36.5957907+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 314,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:36.2442079+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 242,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:36.1747383+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 274,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:36.3862239+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 908,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:22.7153944+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 276,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:51:46.3098858+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 290,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:56:34.3043215+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 259,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:01:34.3740852+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 286,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:06:34.2810697+08:00"
- },
- {
- "website_id": "188cb54b93ddd1e487bf347e",
- "url_id": "46d822694242",
- "url": "https://image.shumengya.top",
- "status_code": 200,
- "latency": 279,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:11:34.2972329+08:00"
- }
- ],
- "188cb5507dcd2da0559bd6dd_6d5125db9d81": [
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 220,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.3582647+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 63,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.2022436+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 148,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:59.0707769+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 51,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.0074865+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 157,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.27495+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 56,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.1315798+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 67,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.0180465+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 61,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.146403+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.237799+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 60,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.1664426+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 169,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:25.4280383+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 68,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:48.2246115+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 75,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:36.0138816+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 65,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:36.0850369+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.1319975+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 61,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:35.998855+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 72,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:36.0011437+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 68,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:35.9960971+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 61,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:36.1307335+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 100,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:25.2539084+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 86,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:51:47.3982067+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 83,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:56:35.3919529+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 71,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:01:35.4457372+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 100,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:06:35.3824803+08:00"
- },
- {
- "website_id": "188cb5507dcd2da0559bd6dd",
- "url_id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "status_code": 200,
- "latency": 78,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:11:35.3832617+08:00"
- }
- ],
- "188cb55693193b80d2383cc3_74a3b6e1f50e": [
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 202,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.3410504+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 63,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.2017319+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 79,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.9158794+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 68,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.1553447+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 67,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.1913031+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 53,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.1297449+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 63,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.0955142+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 179,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.4274524+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 50,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.2373569+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 188,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.2930692+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 53,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:25.3953208+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 63,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:48.1556313+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 65,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:36.1441675+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:36.0850369+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 65,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:35.9941188+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 58,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:35.9966+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 67,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:35.9960108+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 192,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:37.5052071+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 54,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:36.4407981+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 148,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:25.1427358+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 106,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:51:48.5087751+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 92,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:56:36.4908149+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 89,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:01:36.5423098+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 194,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:06:36.5772777+08:00"
- },
- {
- "website_id": "188cb55693193b80d2383cc3",
- "url_id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "status_code": 200,
- "latency": 67,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:11:36.4555473+08:00"
- }
- ],
- "188cb56d8df57dc8c66d42ee_e8f8fd4cf9b9": [
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 183,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.3219531+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 80,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.2191819+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 141,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:59.2126191+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 52,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.1386721+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 176,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.3229221+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 57,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.1357213+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.3288357+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 60,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.3764123+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 67,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.2604107+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.3193464+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 55,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:25.3991381+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 197,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:48.42258+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 52,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:36.1351696+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 65,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:37.0636641+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 56,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.1298393+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:37.0242441+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 80,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:36.0092883+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 72,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:37.5774464+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 59,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:37.5533295+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 77,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:25.3367397+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 76,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:51:49.5859382+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 163,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:56:37.6617602+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:01:37.6150401+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 78,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:06:37.6557552+08:00"
- },
- {
- "website_id": "188cb56d8df57dc8c66d42ee",
- "url_id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "status_code": 200,
- "latency": 71,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:11:37.5274099+08:00"
- }
- ],
- "188cb574b122f71087e53ae1_2f9ffdedd860": [
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 151,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.3868735+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 49,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.3471695+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 168,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:10:59.2399023+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 50,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.1473997+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 56,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.2069431+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 49,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.0652905+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 50,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.0007479+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 134,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.0845016+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 54,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.249977+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 76,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.0273731+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 41,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:13:37.5653881+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 39,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:21:48.2465005+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 42,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:26:48.3318822+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 44,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:31:48.1706242+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 43,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:36:48.3965601+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 40,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:41:48.1408271+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 43,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:46:48.5671551+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 46,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:51:49.7916386+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 39,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:56:48.1087922+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 42,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T12:49:35.0070849+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 58,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T12:52:13.9042824+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 44,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T12:56:50.8682468+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 37,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T13:01:50.8240397+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 78,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T13:06:50.8919213+08:00"
- },
- {
- "website_id": "188cb574b122f71087e53ae1",
- "url_id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "status_code": 502,
- "latency": 42,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T13:11:50.7436019+08:00"
- }
- ],
- "188cb5a19b836e80d93df86a_8a4ebcb7eb03": [
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 186,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.4838945+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 50,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.3516696+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 209,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.1587354+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 63,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.2002149+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 193,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.2099257+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 50,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.2389192+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 75,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.0261897+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 72,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.0897618+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.3014967+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 88,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.039384+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:25.4167746+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 71,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:38.4794688+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 69,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:36.20857+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:37.3264248+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:35.9928867+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 59,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:36.056479+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 75,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:36.0027837+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 71,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:37.3122906+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 65,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:36.4378324+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 59,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:26.4368015+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 60,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:52:14.9653754+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 56,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:56:51.9306606+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 60,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:01:51.8845781+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 75,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:06:51.9673672+08:00"
- },
- {
- "website_id": "188cb5a19b836e80d93df86a",
- "url_id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "status_code": 200,
- "latency": 63,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:11:51.807611+08:00"
- }
- ],
- "188cb6da20586d34df88b086_e7e250eb8985": [
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 181,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.4962871+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 52,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.3225062+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 197,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.1470186+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 66,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.2049811+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 71,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.2633083+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 53,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.2671177+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 162,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.1747423+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 63,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.0845016+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 170,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.1218393+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 65,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.2166006+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 72,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:25.434538+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 66,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:38.5465937+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 164,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:36.3086549+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 60,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:37.261235+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 60,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.18989+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 59,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:36.0575461+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:36.0579512+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 65,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:38.7680572+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 59,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:36.366661+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 62,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:26.4993218+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 65,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:52:16.0318489+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 75,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:56:53.0149034+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 62,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:01:52.95535+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 80,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:06:53.0483776+08:00"
- },
- {
- "website_id": "188cb6da20586d34df88b086",
- "url_id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "status_code": 200,
- "latency": 82,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:11:52.8981237+08:00"
- }
- ],
- "188cb6ff716e2590408704ee_7bf1e5ddd890": null,
- "188cb6ff716e2590408704ee_85620784f1a3": [
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 1057,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:31.4309547+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 935,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:31.3944416+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 984,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:59.2015574+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 934,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:59.1395067+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 889,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:59.1395019+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 893,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:59.4205596+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 795,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.8590597+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 877,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.9582784+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 1895,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:59.8984226+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 753,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:59.0855824+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 744,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:26.1464952+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 766,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:39.3201729+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 771,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:36.9848466+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 1008,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:49.1286652+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 868,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.9889776+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 957,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:36.9600621+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 917,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:36.9215451+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 970,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:38.701653+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 768,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:37.2141041+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 793,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:27.295939+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 793,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:52:17.8409257+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 824,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:53:59.5761674+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 3552,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:56:58.1972327+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 908,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:01:54.8688611+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 898,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:06:55.274691+08:00"
- },
- {
- "website_id": "188cb6ff716e2590408704ee",
- "url_id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "status_code": 200,
- "latency": 869,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:11:55.0292809+08:00"
- }
- ],
- "188cb708e8cf52a49a436570_4d9ec8c9ed04": null,
- "188cb708e8cf52a49a436570_dcc07e30a25a": [
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 102,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:01:30.4248443+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 95,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:06:30.4931186+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 26,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:10:58.610474+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 19,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:15:58.1757636+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 10,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:20:58.2122057+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 6,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:25:58.2454282+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 23,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:30:58.0493386+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 49,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:35:58.1180827+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 27,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:40:58.35469+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 10,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:45:58.1770443+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 73,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:13:37.5424503+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 28,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:21:51.4120639+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 33,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:26:48.3330248+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 46,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:31:48.1156444+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 18,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:36:50.4066682+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 66,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:41:48.1104391+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 53,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:46:48.1641784+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 37,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:52:00.6622626+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 28,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:56:49.3937433+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 74,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T12:49:39.4233602+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 29,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T12:52:31.210864+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 30,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T12:57:11.2884299+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 29,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T13:02:07.9738561+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 56,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T13:07:08.7970095+08:00"
- },
- {
- "website_id": "188cb708e8cf52a49a436570",
- "url_id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "status_code": 0,
- "latency": 39,
- "is_up": false,
- "error": "Get \"https://mind-map.smyhub.com\": dial tcp: lookup mind-map.smyhub.com: no such host",
- "checked_at": "2026-03-06T13:12:08.2059615+08:00"
- }
- ],
- "188cb71029ad43105a3dc6c0_3e0bf25fb3ae": null,
- "188cb71029ad43105a3dc6c0_9148d3eb9835": null,
- "188cb71029ad43105a3dc6c0_f278e65dd498": [
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 861,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:31.2022304+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 267,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.6869854+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 872,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:59.4840706+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 267,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.3372038+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 262,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.4226525+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 266,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.4108321+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 269,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.2834228+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 265,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.2813095+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 270,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.6038038+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 267,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.3857454+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 892,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:26.3106692+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 907,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:38.4066527+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 788,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:36.8676305+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 977,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:36.9970355+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 698,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:49.0510742+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 780,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:36.7937312+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 792,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:36.7998946+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 851,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:36.7806946+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 699,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:36.6279652+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 692,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:26.3770737+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 859,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:52:33.0717708+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 818,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:57:14.9364778+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 1994,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:02:10.9757271+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 2282,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:07:12.0801858+08:00"
- },
- {
- "website_id": "188cb71029ad43105a3dc6c0",
- "url_id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "status_code": 200,
- "latency": 799,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:12:10.006806+08:00"
- }
- ],
- "188cb71029ad43105a3dc6c0_f5e2bfc4a2e5": null,
- "188cb71b527c48bc3c344acc_13cdc2afab17": [
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 839,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:31.200581+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 757,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.904799+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 906,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:59.5332534+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 865,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:59.1294065+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 773,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:59.0554158+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 688,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.9405457+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 883,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:59.2215312+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 693,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.946968+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 804,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:59.1315622+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 782,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:59.0843522+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 923,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:26.3501491+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 802,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:49.1549298+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 791,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:37.6592742+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 875,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:36.9044689+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 788,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.7170444+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 701,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:36.7103277+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 767,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:36.7701423+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 883,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:37.7283078+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 788,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:36.7180393+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 878,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:35.765435+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 812,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:52:34.8931519+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 1032,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:57:16.9695414+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 892,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:02:12.8720785+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 822,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:07:15.4564067+08:00"
- },
- {
- "website_id": "188cb71b527c48bc3c344acc",
- "url_id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "status_code": 200,
- "latency": 1134,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:12:12.4023543+08:00"
- }
- ],
- "188cb71b527c48bc3c344acc_377c1524ef52": null,
- "188cb72555e8d5c4f0d7aa98_421fe08ece5e": [
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 183,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.540952+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 40,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.1919034+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 30,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.5839813+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 45,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.3271348+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 169,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.4341402+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 36,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.2790673+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 188,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.4725522+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 40,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.2471157+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 186,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.5382443+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 43,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.2983982+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 179,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:25.6083855+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 56,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:48.4571738+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 44,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:37.0324895+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 50,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:36.0853928+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 50,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.2473503+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 50,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:36.0616968+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 61,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:36.0721291+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 55,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:36.836845+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 50,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:36.0495987+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 49,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:34.9134661+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:52:35.9581338+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 42,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:57:18.0193997+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 60,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:02:13.9352761+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 44,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:07:16.5082229+08:00"
- },
- {
- "website_id": "188cb72555e8d5c4f0d7aa98",
- "url_id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 57,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:12:13.4609472+08:00"
- }
- ],
- "188cb73272be1c9c5a5d6812_cba98c3c329b": [
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 199,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.5580101+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 50,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.2428329+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 73,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.8361017+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 62,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.3524185+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 59,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.4133314+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 58,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.3383679+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 64,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.4175497+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 67,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.3151915+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 113,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.4834691+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 67,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.3656722+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 53,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:13:37.7593983+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 77,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:22:00.5398513+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 61,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:26:49.2783978+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 65,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:31:48.2806053+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 51,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:36:48.1672136+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 61,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:41:48.3337965+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 71,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:46:48.3278351+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 58,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:52:00.6952371+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 55,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:56:48.2161897+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 78,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T12:49:47.1756539+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 84,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T12:52:49.2920098+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 69,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T12:57:31.2968053+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 84,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T13:02:27.2298866+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 76,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T13:07:29.7921189+08:00"
- },
- {
- "website_id": "188cb73272be1c9c5a5d6812",
- "url_id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "status_code": 404,
- "latency": 80,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T13:12:26.7457987+08:00"
- }
- ],
- "188cb7372655f3841e82a210_299e19afc16d": null,
- "188cb7372655f3841e82a210_ed4c7dcd0565": [
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 108,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:01:30.4956272+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 14,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:06:30.206507+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 12,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:10:58.7604802+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 32,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:15:58.2745643+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 11,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:20:58.3796926+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 9,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:25:58.3378201+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 8,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:30:58.352429+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 140,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:35:58.4053196+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 18,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:40:57.9705039+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 15,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:45:58.3338156+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 26,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:13:37.7006283+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 252,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:22:00.7475304+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 49,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:26:48.5370842+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 39,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:31:49.1346109+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 268,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:36:48.3520905+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 34,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:41:48.3307222+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 41,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:46:48.1641784+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 414,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:51:48.4432568+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 23,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:56:48.146813+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 58,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T12:49:47.1991401+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 45,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T12:53:02.4411535+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 39,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T12:57:44.4640751+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 31,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T13:02:40.5461907+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 43,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T13:07:43.2325422+08:00"
- },
- {
- "website_id": "188cb7372655f3841e82a210",
- "url_id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "status_code": 0,
- "latency": 199,
- "is_up": false,
- "error": "Get \"https://cube.smyhub.com\": dial tcp: lookup cube.smyhub.com: no such host",
- "checked_at": "2026-03-06T13:12:40.095624+08:00"
- }
- ],
- "188cb764a98dbb2453c14b8f_2f0596587997": [
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 181,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.3197729+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 63,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.2562873+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 178,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:59.2296056+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 62,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.4494586+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 62,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.0127576+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 69,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.0219684+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 62,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.0118098+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 67,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.0176916+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 67,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.3176506+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 91,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.0406602+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 82,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:25.3409878+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 188,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:36.1150949+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 56,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:48.383325+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 60,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:36.9651118+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.1962412+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 61,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:35.9983026+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 219,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:36.1463128+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:37.120725+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 73,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:36.0007121+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 768,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:22.5223405+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 84,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:53:03.5304788+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 61,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:57:45.5360117+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 82,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:02:41.6345678+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 65,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:07:44.2985458+08:00"
- },
- {
- "website_id": "188cb764a98dbb2453c14b8f",
- "url_id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "status_code": 200,
- "latency": 73,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:12:41.1694231+08:00"
- }
- ],
- "188cb77f231fe68c73e24b29_c182709178d9": [
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.5487661+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 66,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.2689303+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 86,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.0360248+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 66,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.4193768+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 199,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.150532+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 68,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.0783968+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 122,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.0738107+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.021041+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 198,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.4363569+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 100,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.0512019+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 216,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:26.5667596+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 85,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:36.0129781+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 69,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:48.3954791+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 67,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:37.2005214+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 81,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.0103328+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 75,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:36.2563376+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 74,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:36.0011437+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 90,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:37.0497252+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:35.9988544+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 923,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:22.8225435+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 77,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:53:04.6132278+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 68,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:57:46.6061253+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:02:42.7051969+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 73,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:07:45.3727266+08:00"
- },
- {
- "website_id": "188cb77f231fe68c73e24b29",
- "url_id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "status_code": 200,
- "latency": 103,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:12:42.2737616+08:00"
- }
- ],
- "188cb789a76896788f139a96_13bbbc879aa6": null,
- "188cb789a76896788f139a96_2b42ed612dd3": [
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 230,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.7279386+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 93,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.2964764+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 242,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.1919073+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 113,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.5332649+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 107,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.0628846+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 111,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.0643811+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 111,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.2288562+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 116,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.2644698+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 116,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.4717617+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 110,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.1504604+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 172,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:26.5539105+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 131,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:36.0590636+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 126,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:48.5144311+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 129,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:37.4557189+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 124,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.0534254+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 118,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:36.1807883+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 126,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:37.7759208+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 118,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:37.2404091+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 119,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:36.1182048+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 115,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:25.5321526+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 120,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:53:05.7409363+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 112,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:57:47.7195649+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 121,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:02:43.8342375+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 129,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:07:46.5027347+08:00"
- },
- {
- "website_id": "188cb789a76896788f139a96",
- "url_id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "status_code": 200,
- "latency": 109,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:12:43.3849332+08:00"
- }
- ],
- "188cb7934d5d413890dea61f_bebd3848b644": null,
- "188cb7934d5d413890dea61f_d841646c7b41": [
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 180,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.6772133+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 57,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.2642712+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 219,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.1692978+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 76,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.0263155+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.0167654+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 61,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.0620642+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 69,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.1995911+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 56,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.2453498+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 192,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.1452851+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 60,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.1014934+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 189,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:26.7330356+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:35.9983941+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 79,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:36.0178597+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 87,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:36.0192552+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.3138919+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 144,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:37.1690783+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 65,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:37.7446949+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 65,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:48.5099247+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 67,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:36.0682418+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 79,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:25.4163929+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 59,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:53:06.8010801+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 69,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:57:48.7900122+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 68,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:02:44.903351+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 68,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:07:47.572619+08:00"
- },
- {
- "website_id": "188cb7934d5d413890dea61f",
- "url_id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "status_code": 200,
- "latency": 72,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:12:44.4573778+08:00"
- }
- ],
- "188cb79ed2aeb85cabcf6e66_7c8ff0e48be4": [
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 159,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.6998268+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 54,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.1924139+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 218,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.1685108+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 60,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.04085+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 65,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.0773066+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 61,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.0744634+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.2121164+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 57,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.2474699+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.029498+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 62,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.1059332+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 188,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:26.7426589+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:35.9983941+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:36.0789775+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 66,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:36.15177+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 60,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.3343775+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 63,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:48.1745676+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 67,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:37.8123637+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 66,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:35.9936441+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 58,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:36.1110109+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 85,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:25.6187041+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 76,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:53:07.8780829+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 79,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:57:49.8722454+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 85,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:02:45.9962574+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 83,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:07:48.656311+08:00"
- },
- {
- "website_id": "188cb79ed2aeb85cabcf6e66",
- "url_id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "status_code": 200,
- "latency": 91,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:12:45.5549051+08:00"
- }
- ],
- "188cb7b7b154ddbc1dc4b14d_ef0443476dd8": [
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 187,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.7285846+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 45,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.3015358+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 219,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.1692978+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 60,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.0692121+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 187,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.2000162+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 56,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.0095669+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 116,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.2123859+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 59,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.2063489+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 215,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.1862345+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 57,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.0972452+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 69,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:26.3799124+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 171,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:36.0990553+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 71,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:36.0773031+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 62,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:36.1488853+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 59,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.373118+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 61,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:35.998855+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 71,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:37.6448066+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 62,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:35.9911733+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 58,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:36.0568957+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 852,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:22.7519626+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 58,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:53:08.9372622+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:57:50.9424798+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 71,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:02:47.0746974+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 65,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:07:49.7249765+08:00"
- },
- {
- "website_id": "188cb7b7b154ddbc1dc4b14d",
- "url_id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "status_code": 200,
- "latency": 62,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:12:46.6198048+08:00"
- }
- ],
- "188cb7c8586dd2c4dcf4bd1e_432740a25595": [
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 197,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.7464116+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 55,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.2982425+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 94,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.0442056+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 72,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.0863885+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.0818807+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 74,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.0266973+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.263104+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 69,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.351494+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 112,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.0646163+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 68,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.2543601+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:27.6682422+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 210,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:36.1383343+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 72,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:36.3811642+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 77,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:36.2273867+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.2731434+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 69,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:36.0060409+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 82,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:48.1445319+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 73,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:36.0648486+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 79,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:37.2937533+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 720,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:22.6196686+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 63,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:53:10.0089992+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 76,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:57:52.0238192+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 86,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:02:48.1703743+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 76,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:07:50.8018139+08:00"
- },
- {
- "website_id": "188cb7c8586dd2c4dcf4bd1e",
- "url_id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "status_code": 200,
- "latency": 77,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:12:47.7026518+08:00"
- }
- ],
- "188cf6ed769b75e497cd2a4a_23ba1b4ea7db": null,
- "188cf6ed769b75e497cd2a4a_a3e3ff7839f1": [
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10002,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:01:40.5606259+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:06:40.2650118+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:11:07.9960581+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:16:07.9504714+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:21:08.4140593+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:26:08.1236262+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10003,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:31:08.1791585+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10003,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:36:08.2744981+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:41:08.402227+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:46:08.1778069+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10005,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:14:18.8051009+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:22:28.0100853+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:27:27.952505+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:32:28.1236435+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:37:29.0114839+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:42:28.8672833+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10002,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:47:29.9814463+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10008,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:52:28.0188469+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10006,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:57:29.2213981+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T12:50:13.9026203+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T12:54:03.0220505+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T12:58:45.0472983+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T13:03:41.1764874+08:00"
- },
- {
- "website_id": "188cf6ed769b75e497cd2a4a",
- "url_id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T13:08:43.8163999+08:00"
- }
- ],
- "188cf6f322f76b90c35c3484_397f5ededede": null,
- "188cf6f322f76b90c35c3484_76b6f9fe4f04": [
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:01:40.6795729+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10004,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:06:40.1434301+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10006,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:11:08.0422156+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:16:07.9504714+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10002,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:21:08.3665506+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:26:08.0866511+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:31:08.2299461+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10002,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:36:08.3036422+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10002,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:41:08.4391333+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:46:08.2375927+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10005,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:14:19.6847059+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:22:28.0092059+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:27:28.0337123+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10001,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:32:40.1326651+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:37:28.8493808+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:42:28.8216032+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:47:40.163012+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10008,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:52:28.0187936+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10010,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:57:40.0748003+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T12:50:16.2655756+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T12:54:56.0404083+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10007,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T12:59:38.0666251+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T13:04:34.1927657+08:00"
- },
- {
- "website_id": "188cf6f322f76b90c35c3484",
- "url_id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:19132/smy\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T13:09:36.8300814+08:00"
- }
- ],
- "188cf7019e56e618827f4927_093d47789bb5": [
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:01:40.7006769+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10006,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:06:40.2255874+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:11:08.0444398+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:16:07.9504714+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10004,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:21:08.3847769+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:26:08.1301227+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10001,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:31:08.2791726+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10004,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:36:08.3562871+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:41:07.9522989+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:46:08.2936102+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:14:29.5558267+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10006,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:22:28.0303322+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:27:28.0333848+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:32:29.8746448+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:37:40.370772+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10003,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:42:40.1928092+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:47:40.1922672+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10008,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:52:28.0186137+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:57:40.1233094+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T12:50:16.763396+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10008,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T12:55:49.0575201+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T13:00:31.0837335+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10008,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T13:05:27.2224784+08:00"
- },
- {
- "website_id": "188cf7019e56e618827f4927",
- "url_id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.233:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T13:10:29.8496296+08:00"
- }
- ],
- "188cf7019e56e618827f4927_56250450a6bf": null,
- "188cf70700922fa4041f6470_777c292c7696": [
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10004,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:01:40.4301734+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:06:40.2101134+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10005,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:11:08.1521525+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:16:07.9504714+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10001,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:21:07.9519276+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:26:07.9525122+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10006,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:31:07.9568038+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:36:07.9497683+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:41:07.9529112+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10006,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T10:46:07.9556634+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10006,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:14:17.2821345+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:22:28.0735007+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:27:29.686492+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10004,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:32:40.1905386+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10001,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:37:27.9403521+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10009,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:42:27.9558966+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10001,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:47:27.9477972+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10008,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:52:28.0188469+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10001,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T11:57:27.9539136+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T12:50:13.9028825+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T12:56:42.0763178+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T13:01:24.1074538+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10000,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T13:06:20.2333278+08:00"
- },
- {
- "website_id": "188cf70700922fa4041f6470",
- "url_id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "status_code": 0,
- "latency": 10005,
- "is_up": false,
- "error": "Get \"http://10.0.0.100:8484/\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)",
- "checked_at": "2026-03-06T13:11:22.8676568+08:00"
- }
- ],
- "188cf70700922fa4041f6470_791643dbecab": null,
- "188cf728ed2992f06a8f9e52_0a0a59069228": [
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 57,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.7881685+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 185,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.609613+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 55,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.2179881+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 62,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.0137853+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 194,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.1460864+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 78,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.2136575+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 196,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.1475443+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 78,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.0290719+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 66,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.3270898+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 104,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.0549829+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 73,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:26.7000878+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 62,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:36.1636689+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 76,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:36.0149594+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 96,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:36.0276805+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 79,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.0730123+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:36.7330859+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 57,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:35.9860997+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:36.129555+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 83,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:36.2170485+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 339,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:22.8624484+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 68,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:56:43.1471902+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 100,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:01:25.2162719+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 79,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:06:21.3143458+08:00"
- },
- {
- "website_id": "188cf728ed2992f06a8f9e52",
- "url_id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "status_code": 200,
- "latency": 91,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:11:23.963916+08:00"
- }
- ],
- "188cf72edea71c4cb2284c93_170fab2239ad": [
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 200,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.9469074+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 51,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.1919034+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 189,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.358679+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 55,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.2560943+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 196,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.2012624+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 54,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.1879181+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 59,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.1151722+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 74,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.0687316+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 66,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.3689868+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 63,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.2932774+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 59,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:26.6262311+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:36.1792766+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 56,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:36.0822304+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 62,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:36.2827382+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 55,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.0500321+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:36.7755212+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 68,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:36.2842698+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 59,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:36.1895051+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 61,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:36.2444953+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 807,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:23.550941+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 65,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:56:44.2148032+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 67,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:01:26.2895414+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:06:22.3920123+08:00"
- },
- {
- "website_id": "188cf72edea71c4cb2284c93",
- "url_id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "status_code": 200,
- "latency": 67,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:11:25.0358364+08:00"
- }
- ],
- "188cf746b16a83dc4d5e3d13_822329e621c2": [
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 138,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T10:01:30.9263024+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 25,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T10:06:30.3478768+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 10,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T10:10:58.179906+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 34,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T10:15:58.2392592+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 26,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T10:20:58.0051352+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 7,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T10:25:58.1435372+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 8,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T10:30:58.075461+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 20,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T10:35:57.9921885+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 7,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T10:40:57.9590639+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 12,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T10:45:58.2295509+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 178,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T11:13:38.9758485+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 42,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T11:21:48.3512242+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 148,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T11:26:48.325657+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 17,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T11:31:48.3341323+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 285,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T11:36:48.3520905+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 32,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T11:41:48.8480551+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 20,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T11:46:48.3437233+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 333,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T11:51:48.4432568+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 31,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T11:56:48.3357056+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 30,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T12:49:34.8863658+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 30,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T12:56:57.4485457+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 25,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T13:01:39.3818967+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 65,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T13:06:35.8325982+08:00"
- },
- {
- "website_id": "188cf746b16a83dc4d5e3d13",
- "url_id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "status_code": 0,
- "latency": 112,
- "is_up": false,
- "error": "Get \"https://repo.docker.shumengya.top\": dial tcp: lookup repo.docker.shumengya.top: no such host",
- "checked_at": "2026-03-06T13:11:38.237086+08:00"
- }
- ],
- "188cf74b2fa5da7c8e2b588e_2f580f90f979": [
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 188,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:31.0773606+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 49,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.3976749+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 57,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.2268534+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 66,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.3065638+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 160,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.3678545+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 60,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.3282352+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 56,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.1301053+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 70,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.1884945+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 86,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.0728626+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 62,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.3816908+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 59,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:26.7933593+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 56,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:36.1959082+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 61,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:36.1391958+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 57,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:36.2851606+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 59,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.1109068+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 68,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:36.8439537+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 68,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:36.3530811+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 60,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:36.296586+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 60,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:36.3073882+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 747,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:23.5499358+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 80,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:56:58.5331107+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 80,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:01:40.4661759+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 61,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:06:36.8996853+08:00"
- },
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "status_code": 200,
- "latency": 66,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:11:39.3046808+08:00"
- }
- ],
- "188cf74b2fa5da7c8e2b588e_65c5e5f59ef6": [
- {
- "website_id": "188cf74b2fa5da7c8e2b588e",
- "url_id": "65c5e5f59ef6",
- "url": "http://monitor.shumengya.top",
- "status_code": 200,
- "latency": 180,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.3612917+08:00"
- }
- ],
- "188d00db054cf7860dff3440_ac85b166ccc4": [
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 153,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:30.8836501+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 53,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.4017999+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 166,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.358679+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 65,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.2418594+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 59,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.0111047+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 62,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.0151534+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 145,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.1955467+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 56,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.006384+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 93,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.1218393+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 89,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.039384+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 84,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:25.343647+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 66,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:36.2307789+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 60,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:36.0781404+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 67,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:36.2193011+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 68,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.0611486+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 67,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:36.6629836+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 68,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:36.2156466+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 67,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:36.3655273+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 64,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:36.1831495+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 626,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:23.4369702+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 57,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:56:59.5973382+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 78,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:01:41.5504432+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 73,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:06:37.9736161+08:00"
- },
- {
- "website_id": "188d00db054cf7860dff3440",
- "url_id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "status_code": 200,
- "latency": 81,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:11:40.3873018+08:00"
- }
- ],
- "188d00edf571226f42ec8b20_0bf0fe1bb9cc": [
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 204,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:01:31.1528534+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 57,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.3588872+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 55,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:10:58.273834+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 59,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.3871016+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 151,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.3641271+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 60,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.0129928+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 63,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.2772517+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 59,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.0107753+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 65,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.0958937+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 57,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.0853517+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 51,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:13:38.3694905+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 48,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:21:48.4006815+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 71,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:27:00.6074678+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 59,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:31:48.5340924+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 53,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:36:48.6295341+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 53,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:41:50.0731159+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 52,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:46:49.0508201+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 54,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:51:48.6138888+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 46,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T11:56:48.8645376+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 54,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T12:49:35.7371329+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 55,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T12:57:12.8532476+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 69,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T13:01:54.8337618+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 52,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T13:06:51.2395225+08:00"
- },
- {
- "website_id": "188d00edf571226f42ec8b20",
- "url_id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "status_code": 404,
- "latency": 76,
- "is_up": false,
- "error": "",
- "checked_at": "2026-03-06T13:11:53.6624053+08:00"
- }
- ],
- "188e7f1a40cdc7bc3bba1817_9af024b3d387": [
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 974,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:32.0557451+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 225,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.7255993+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 837,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:59.0707769+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 280,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.6014934+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 286,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.6202369+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 277,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.2413215+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 280,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.4928934+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 283,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.3005104+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 280,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.3511761+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 280,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.2370752+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 857,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:26.543312+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 758,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:36.955048+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 761,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:49.0941182+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 842,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:37.1335058+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 662,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:36.9972056+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 659,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:37.8285255+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 658,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:37.4285252+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 768,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:36.9587124+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 748,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:37.1902037+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 1397,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:24.2604395+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 2752,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:57:16.6112109+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 703,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:01:56.5386706+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 8240,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:07:00.912106+08:00"
- },
- {
- "website_id": "188e7f1a40cdc7bc3bba1817",
- "url_id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "status_code": 200,
- "latency": 2529,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:11:58.8926642+08:00"
- }
- ],
- "188e7f27a909fe247a2fcd15_b897ef0def67": [
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 909,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:01:31.8361517+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 268,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:06:30.7386385+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 775,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:10:59.0506247+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 374,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:15:58.7117093+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 258,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:20:58.4709832+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 263,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:25:58.2181145+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 259,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:30:58.474972+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 262,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:35:58.2711774+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 256,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:40:58.3321555+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 260,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T10:45:58.2544344+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 852,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:13:27.5955457+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 809,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:21:37.0412795+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 798,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:24:05.365268+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 843,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:26:49.2404181+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 790,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:31:37.8550234+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 796,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:36:37.7951793+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 895,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:41:49.0061678+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 756,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:46:37.6782404+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 772,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:51:48.847248+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 769,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T11:56:37.487114+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 1499,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:49:24.9643486+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 902,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T12:57:18.5183821+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 765,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:01:58.3069549+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 2109,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:07:04.0301051+08:00"
- },
- {
- "website_id": "188e7f27a909fe247a2fcd15",
- "url_id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "status_code": 200,
- "latency": 793,
- "is_up": true,
- "error": "",
- "checked_at": "2026-03-06T13:12:01.6812289+08:00"
- }
- ],
- "188e7f33f087667c29da05f2_75a0cb223c2d": [
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 0,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:01:31.1533812+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 0,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:06:30.610074+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 0,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:10:58.3592783+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 0,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:15:58.3529717+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 0,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:20:58.3526923+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 0,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:25:58.1362589+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 0,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:30:58.2293624+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 0,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:35:58.014182+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 0,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:40:58.0965098+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 0,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:45:58.254972+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 147,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:13:49.7240624+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 0,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:21:48.9630317+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 23,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:27:00.5729713+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 0,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:31:49.4699542+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 93,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:37:00.5173573+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 39,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:42:00.305662+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 0,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:46:49.8119253+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 0,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:51:50.8290435+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 0,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:56:49.6557761+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 0,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T12:49:35.5870644+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 40,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T12:57:31.6484632+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 60,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T13:02:11.4448246+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 206,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T13:07:17.3892239+08:00"
- },
- {
- "website_id": "188e7f33f087667c29da05f2",
- "url_id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 178,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T13:12:15.0969822+08:00"
- }
- ],
- "188e7f4cdd13a3bc80c68184_9f11daaedba4": [
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 159,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:01:30.2977632+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 12,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:06:30.1506206+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 45,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:10:57.9948055+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 29,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:15:57.9793634+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 28,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:20:57.9790697+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 47,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:25:57.9998716+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 35,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:30:57.9847992+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 22,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:35:57.9720902+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 33,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:40:57.9849618+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 40,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T10:45:57.9900091+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 124,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:13:37.4870994+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 72,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:21:48.0911005+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 148,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:26:48.325657+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 45,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:31:48.1156444+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 286,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:36:48.3520905+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 65,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:41:48.1101991+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 49,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:46:48.0622693+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 80,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:51:48.0693242+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 39,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T11:56:48.045534+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 16,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T12:49:34.8643449+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 35,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T12:57:44.7503187+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 30,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T13:02:24.5141131+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 119,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T13:07:30.7785204+08:00"
- },
- {
- "website_id": "188e7f4cdd13a3bc80c68184",
- "url_id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "status_code": 0,
- "latency": 306,
- "is_up": false,
- "error": "Get \"https://floppy-bird.smyhub.com/\": dial tcp: lookup floppy-bird.smyhub.com: no such host",
- "checked_at": "2026-03-06T13:12:28.4734949+08:00"
- }
- ]
-}
\ No newline at end of file
diff --git a/mengyaping-backend/data/websites.json b/mengyaping-backend/data/websites.json
deleted file mode 100644
index 35b713a..0000000
--- a/mengyaping-backend/data/websites.json
+++ /dev/null
@@ -1,821 +0,0 @@
-[
- {
- "id": "188cb48c619bd5d896bff546",
- "name": "萌芽主页",
- "groups": [
- "self-made"
- ],
- "urls": [
- {
- "id": "d19b0a475334",
- "url": "https://shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://shumengya.top/favicon.ico",
- "title": "萌芽主页",
- "created_at": "2026-01-21T17:21:08.6757862+08:00",
- "updated_at": "2026-03-06T13:12:33.6663492+08:00"
- },
- {
- "id": "188cb49298d72b78a37301a1",
- "name": "萌芽备忘录",
- "groups": [
- "self-deploy"
- ],
- "urls": [
- {
- "id": "9d25ae024f36",
- "url": "https://memos.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://memos.shumengya.top/logo.webp",
- "title": "Memos",
- "created_at": "2026-01-21T17:21:35.3722254+08:00",
- "updated_at": "2026-03-06T13:12:34.4657931+08:00"
- },
- {
- "id": "188cb52c04cf639cfc2c8ba4",
- "name": "萌芽盘",
- "groups": [
- "self-deploy"
- ],
- "urls": [
- {
- "id": "cfe6229fb86b",
- "url": "https://pan.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://img.shumengya.top/i/2026/01/04/695a660870959.png",
- "title": "萌芽盘",
- "created_at": "2026-01-21T17:32:34.3136511+08:00",
- "updated_at": "2026-03-06T13:12:35.6184204+08:00"
- },
- {
- "id": "188cb53623f46b7872bf17b6",
- "name": "萌芽Git仓库",
- "groups": [
- "self-deploy"
- ],
- "urls": [
- {
- "id": "b53594e7285d",
- "url": "https://git.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://git.shumengya.top/assets/img/favicon.svg",
- "title": "萌芽Git仓库",
- "created_at": "2026-01-21T17:33:17.7858446+08:00",
- "updated_at": "2026-03-06T13:12:36.4115003+08:00"
- },
- {
- "id": "188cb54b93ddd1e487bf347e",
- "name": "萌芽图床",
- "groups": [
- "self-deploy"
- ],
- "urls": [
- {
- "id": "46d822694242",
- "url": "https://image.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://image.shumengya.top/favicon.ico",
- "title": "萌芽图床",
- "created_at": "2026-01-21T17:34:49.8577249+08:00",
- "updated_at": "2026-03-06T13:12:38.40321+08:00"
- },
- {
- "id": "188cb5507dcd2da0559bd6dd",
- "name": "萌芽笔记",
- "groups": [
- "self-made"
- ],
- "urls": [
- {
- "id": "6d5125db9d81",
- "url": "https://note.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://note.shumengya.top/logo.png",
- "title": "萌芽笔记",
- "created_at": "2026-01-21T17:35:10.962372+08:00",
- "updated_at": "2026-03-06T13:12:40.1738642+08:00"
- },
- {
- "id": "188cb55693193b80d2383cc3",
- "name": "萌芽作品集",
- "groups": [
- "self-made"
- ],
- "urls": [
- {
- "id": "74a3b6e1f50e",
- "url": "https://work.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://work.shumengya.top/favicon.ico",
- "title": "502 Bad Gateway",
- "created_at": "2026-01-21T17:35:37.0894816+08:00",
- "updated_at": "2026-03-06T13:12:40.976149+08:00"
- },
- {
- "id": "188cb56d8df57dc8c66d42ee",
- "name": "万象口袋",
- "groups": [
- "self-made"
- ],
- "urls": [
- {
- "id": "e8f8fd4cf9b9",
- "url": "https://infogenie.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://infogenie.shumengya.top/assets/logo.png",
- "title": "万象口袋",
- "created_at": "2026-01-21T17:37:15.787501+08:00",
- "updated_at": "2026-03-06T13:12:42.7325255+08:00"
- },
- {
- "id": "188cb574b122f71087e53ae1",
- "name": "萌芽问卷",
- "groups": [
- "self-deploy"
- ],
- "urls": [
- {
- "id": "2f9ffdedd860",
- "url": "https://survey.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://survey.shumengya.top/favicon.ico",
- "title": "502 Bad Gateway",
- "created_at": "2026-01-21T17:37:46.4424548+08:00",
- "updated_at": "2026-03-06T13:12:44.9725726+08:00"
- },
- {
- "id": "188cb5a19b836e80d93df86a",
- "name": "萌芽短链",
- "groups": [
- "self-made"
- ],
- "urls": [
- {
- "id": "8a4ebcb7eb03",
- "url": "https://short.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://short.shumengya.top/logo.png",
- "title": "萌芽短链",
- "created_at": "2026-01-21T17:40:59.3532064+08:00",
- "updated_at": "2026-03-06T13:12:45.7693627+08:00"
- },
- {
- "id": "188cb6da20586d34df88b086",
- "name": "萌芽漂流瓶",
- "groups": [
- "self-made"
- ],
- "urls": [
- {
- "id": "e7e250eb8985",
- "url": "https://bottle.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://bottle.shumengya.top/logo.png",
- "title": "萌芽漂流瓶(´,,•ω•,,)♡",
- "created_at": "2026-01-21T18:03:21.6115541+08:00",
- "updated_at": "2026-03-06T13:12:46.5656927+08:00"
- },
- {
- "id": "188cb6ff716e2590408704ee",
- "name": "编程速查表[CloudFlare]",
- "groups": [
- "self-deploy"
- ],
- "urls": [
- {
- "id": "85620784f1a3",
- "url": "https://reference.smyhub.com",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "188.114.96.0",
- "188.114.97.0",
- "2a06:98c1:3121::",
- "2a06:98c1:3120::"
- ],
- "favicon": "https://reference.smyhub.com/icons/favicon.svg",
- "title": "Quick Reference\n \u0026#x26; Quick Reference",
- "created_at": "2026-01-21T18:06:01.885722+08:00",
- "updated_at": "2026-03-06T13:12:48.1727895+08:00"
- },
- {
- "id": "188cb708e8cf52a49a436570",
- "name": "思绪思维导图[CloudFlare]",
- "groups": [
- "self-deploy"
- ],
- "urls": [
- {
- "id": "dcc07e30a25a",
- "url": "https://mind-map.smyhub.com",
- "remark": ""
- }
- ],
- "favicon": "https://mind-map.smyhub.com/dist/logo.ico",
- "title": "思绪思维导图",
- "created_at": "2026-01-21T18:06:42.5432849+08:00",
- "updated_at": "2026-01-27T13:10:46.0879149+08:00"
- },
- {
- "id": "188cb71029ad43105a3dc6c0",
- "name": "it-tools工具集[CloudFlare]",
- "groups": [
- "self-deploy"
- ],
- "urls": [
- {
- "id": "f278e65dd498",
- "url": "https://it-tools.smyhub.com",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "188.114.97.0",
- "188.114.96.0",
- "2a06:98c1:3121::",
- "2a06:98c1:3120::"
- ],
- "favicon": "https://it-tools.smyhub.com/favicon.ico",
- "title": "IT Tools - Handy online tools for developers",
- "created_at": "2026-01-21T18:07:13.6963428+08:00",
- "updated_at": "2026-03-06T13:12:49.7591315+08:00"
- },
- {
- "id": "188cb71b527c48bc3c344acc",
- "name": "xtools工具集[CloudFlare]",
- "groups": [
- "self-deploy"
- ],
- "urls": [
- {
- "id": "13cdc2afab17",
- "url": "https://xtools.smyhub.com",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "188.114.96.0",
- "188.114.97.0",
- "2a06:98c1:3121::",
- "2a06:98c1:3120::"
- ],
- "favicon": "https://xtools.smyhub.com/favicon.ico",
- "title": "百川云常用工具",
- "created_at": "2026-01-21T18:08:01.6256391+08:00",
- "updated_at": "2026-03-06T13:12:52.8447254+08:00"
- },
- {
- "id": "188cb72555e8d5c4f0d7aa98",
- "name": "萌芽监控面板",
- "groups": [
- "admin"
- ],
- "urls": [
- {
- "id": "421fe08ece5e",
- "url": "http://monitor.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "http://monitor.shumengya.top/logo.png",
- "title": "萌芽监控面板",
- "created_at": "2026-01-21T18:08:44.6327577+08:00",
- "updated_at": "2026-03-06T13:12:53.6453208+08:00"
- },
- {
- "id": "188cb73272be1c9c5a5d6812",
- "name": "在线office",
- "groups": [
- "self-deploy"
- ],
- "urls": [
- {
- "id": "cba98c3c329b",
- "url": "https://office.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://office.shumengya.top/favicon.ico",
- "title": "404 Not Found",
- "created_at": "2026-01-21T18:09:40.9510719+08:00",
- "updated_at": "2026-03-06T13:12:54.436477+08:00"
- },
- {
- "id": "188cb7372655f3841e82a210",
- "name": "网页魔方[CloudFlare]",
- "groups": [
- "self-deploy"
- ],
- "urls": [
- {
- "id": "ed4c7dcd0565",
- "url": "https://cube.smyhub.com",
- "remark": ""
- }
- ],
- "favicon": "https://cube.smyhub.com/favicon.ico",
- "title": "HTML5 3D魔方小游戏",
- "created_at": "2026-01-21T18:10:01.1440137+08:00",
- "updated_at": "2026-01-27T13:12:55.4496439+08:00"
- },
- {
- "id": "188cb764a98dbb2453c14b8f",
- "name": "60sAPI集合",
- "groups": [
- "api"
- ],
- "urls": [
- {
- "id": "2f0596587997",
- "url": "https://60s.api.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://60s.api.shumengya.top/favicon.ico",
- "title": "502 Bad Gateway",
- "created_at": "2026-01-21T18:13:16.6194034+08:00",
- "updated_at": "2026-03-06T13:12:56.3727134+08:00"
- },
- {
- "id": "188cb77f231fe68c73e24b29",
- "name": "萌芽主页后端API",
- "groups": [
- "api"
- ],
- "urls": [
- {
- "id": "c182709178d9",
- "url": "https://nav.api.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://nav.api.shumengya.top/favicon.ico",
- "title": "502 Bad Gateway",
- "created_at": "2026-01-21T18:15:10.3277851+08:00",
- "updated_at": "2026-03-06T13:12:57.5163074+08:00"
- },
- {
- "id": "188cb789a76896788f139a96",
- "name": "萌芽笔记后端API",
- "groups": [
- "api"
- ],
- "urls": [
- {
- "id": "2b42ed612dd3",
- "url": "https://note.api.shumengya.top/api/tree",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://note.api.shumengya.top/favicon.ico",
- "title": "502 Bad Gateway",
- "created_at": "2026-01-21T18:15:55.4968142+08:00",
- "updated_at": "2026-03-06T13:12:58.307067+08:00"
- },
- {
- "id": "188cb7934d5d413890dea61f",
- "name": "萌芽作品集后端API",
- "groups": [
- "api"
- ],
- "urls": [
- {
- "id": "d841646c7b41",
- "url": "https://work.api.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://work.api.shumengya.top/favicon.ico",
- "title": "502 Bad Gateway",
- "created_at": "2026-01-21T18:16:36.935795+08:00",
- "updated_at": "2026-03-06T13:12:59.0980222+08:00"
- },
- {
- "id": "188cb79ed2aeb85cabcf6e66",
- "name": "万象口袋后端API",
- "groups": [
- "api"
- ],
- "urls": [
- {
- "id": "7c8ff0e48be4",
- "url": "https://infogenie.api.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://infogenie.api.shumengya.top/favicon.ico",
- "title": "502 Bad Gateway",
- "created_at": "2026-01-21T18:17:26.4171439+08:00",
- "updated_at": "2026-03-06T13:12:59.8921428+08:00"
- },
- {
- "id": "188cb7b7b154ddbc1dc4b14d",
- "name": "萌芽短链后端API",
- "groups": [
- "api"
- ],
- "urls": [
- {
- "id": "ef0443476dd8",
- "url": "https://short.api.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://short.api.shumengya.top/favicon.ico",
- "title": "502 Bad Gateway",
- "created_at": "2026-01-21T18:19:13.2317895+08:00",
- "updated_at": "2026-03-06T13:13:02.3005616+08:00"
- },
- {
- "id": "188cb7c8586dd2c4dcf4bd1e",
- "name": "萌芽漂流瓶后端API",
- "groups": [
- "api"
- ],
- "urls": [
- {
- "id": "432740a25595",
- "url": "https://bottle.api.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://bottle.api.shumengya.top/favicon.ico",
- "title": "502 Bad Gateway",
- "created_at": "2026-01-21T18:20:24.7546969+08:00",
- "updated_at": "2026-03-06T13:13:03.0940218+08:00"
- },
- {
- "id": "188cf6ed769b75e497cd2a4a",
- "name": "大萌芽1Panel面板[WG]",
- "groups": [
- "admin"
- ],
- "urls": [
- {
- "id": "a3e3ff7839f1",
- "url": "http://10.0.0.233:19132/smy",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "10.0.0.233"
- ],
- "favicon": "http://10.0.0.233:19132/favicon.ico",
- "title": "loading...",
- "created_at": "2026-01-22T13:37:33.4073441+08:00",
- "updated_at": "2026-03-06T13:13:03.5972427+08:00"
- },
- {
- "id": "188cf6f322f76b90c35c3484",
- "name": "小萌芽1Panel面板[WG]",
- "groups": [
- "admin"
- ],
- "urls": [
- {
- "id": "76b6f9fe4f04",
- "url": "http://10.0.0.100:19132/smy",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "10.0.0.100"
- ],
- "favicon": "http://10.0.0.100:19132/favicon.ico",
- "title": "loading...",
- "created_at": "2026-01-22T13:37:57.7738884+08:00",
- "updated_at": "2026-03-06T13:13:04.1047503+08:00"
- },
- {
- "id": "188cf7019e56e618827f4927",
- "name": "大萌芽Portaintor面板[WG]",
- "groups": [
- "admin"
- ],
- "urls": [
- {
- "id": "093d47789bb5",
- "url": "http://10.0.0.233:8484/",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "10.0.0.233"
- ],
- "favicon": "http://10.0.0.233:8484/dd5d4c0b208895c5a7de.png",
- "title": "Portainer",
- "created_at": "2026-01-22T13:38:59.9732854+08:00",
- "updated_at": "2026-03-06T13:13:04.6105552+08:00"
- },
- {
- "id": "188cf70700922fa4041f6470",
- "name": "小萌芽Portaintor面板[WG]",
- "groups": [
- "admin"
- ],
- "urls": [
- {
- "id": "777c292c7696",
- "url": "http://10.0.0.100:8484/",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "10.0.0.100"
- ],
- "favicon": "http://10.0.0.100:8484/dd5d4c0b208895c5a7de.png",
- "title": "Portainer",
- "created_at": "2026-01-22T13:39:23.0961745+08:00",
- "updated_at": "2026-03-06T13:13:05.112894+08:00"
- },
- {
- "id": "188cf728ed2992f06a8f9e52",
- "name": "easytier面板",
- "groups": [
- "admin"
- ],
- "urls": [
- {
- "id": "0a0a59069228",
- "url": "http://easytier.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "http://easytier.shumengya.top/easytier.png",
- "title": "EasyTier Dashboard",
- "created_at": "2026-01-22T13:41:48.7994396+08:00",
- "updated_at": "2026-03-06T13:13:06.2605727+08:00"
- },
- {
- "id": "188cf72edea71c4cb2284c93",
- "name": "wireguard面板",
- "groups": [
- "admin"
- ],
- "urls": [
- {
- "id": "170fab2239ad",
- "url": "https://wireguard.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://wireguard.shumengya.top/favicon.ico",
- "title": "502 Bad Gateway",
- "created_at": "2026-01-22T13:42:14.3258123+08:00",
- "updated_at": "2026-03-06T13:13:07.8283939+08:00"
- },
- {
- "id": "188cf746b16a83dc4d5e3d13",
- "name": "萌芽Docker镜像仓库",
- "groups": [
- "admin"
- ],
- "urls": [
- {
- "id": "822329e621c2",
- "url": "https://repo.docker.shumengya.top",
- "remark": ""
- }
- ],
- "favicon": "https://repo.docker.shumengya.top/favicon.ico",
- "title": "502 Bad Gateway",
- "created_at": "2026-01-22T13:43:56.6460815+08:00",
- "updated_at": "2026-01-26T11:56:40.972109897+08:00"
- },
- {
- "id": "188cf74b2fa5da7c8e2b588e",
- "name": "萌芽通知",
- "groups": [
- "admin"
- ],
- "urls": [
- {
- "id": "2f580f90f979",
- "url": "https://notice.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://notice.shumengya.top/favicon.ico",
- "title": "萌芽监控面板",
- "created_at": "2026-01-22T13:44:15.9437687+08:00",
- "updated_at": "2026-03-06T13:13:09.4168617+08:00"
- },
- {
- "id": "188d00db054cf7860dff3440",
- "name": "萌芽Ping",
- "groups": [
- "admin"
- ],
- "urls": [
- {
- "id": "ac85b166ccc4",
- "url": "https://ping.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://ping.shumengya.top/favicon.ico",
- "title": "萌芽Ping - 网站监控面板",
- "created_at": "2026-01-22T16:39:29.31324815+08:00",
- "updated_at": "2026-03-06T13:13:10.213788+08:00"
- },
- {
- "id": "188d00edf571226f42ec8b20",
- "name": "萌芽Ping后端API",
- "groups": [
- "api"
- ],
- "urls": [
- {
- "id": "0bf0fe1bb9cc",
- "url": "https://ping.api.shumengya.top",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "47.108.228.23"
- ],
- "favicon": "https://ping.api.shumengya.top/favicon.ico",
- "title": "萌芽Git仓库",
- "created_at": "2026-01-22T16:40:50.651561641+08:00",
- "updated_at": "2026-03-06T13:13:11.3565622+08:00"
- },
- {
- "id": "188e7f1a40cdc7bc3bba1817",
- "name": "DNS查询[CloudFlare]",
- "groups": [
- "self-deploy"
- ],
- "urls": [
- {
- "id": "9af024b3d387",
- "url": "https://cf-dns.smyhub.com/",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "188.114.97.0",
- "188.114.96.0",
- "2a06:98c1:3121::",
- "2a06:98c1:3120::"
- ],
- "favicon": "https://cf-assets.www.cloudflare.com/dzlvafdwdttg/6TaQ8Q7BDmdAFRoHpDCb82/8d9bc52a2ac5af100de3a9adcf99ffaa/security-shield-protection-2.svg",
- "title": "DNS-over-HTTPS Resolver",
- "created_at": "2026-01-27T13:24:14.3362887+08:00",
- "updated_at": "2026-03-06T13:13:12.1501803+08:00"
- },
- {
- "id": "188e7f27a909fe247a2fcd15",
- "name": "Github文件加速[CloudFlare]",
- "groups": [
- "self-deploy"
- ],
- "urls": [
- {
- "id": "b897ef0def67",
- "url": "https://gh-proxy.smyhub.com/",
- "remark": ""
- }
- ],
- "ip_addresses": [
- "188.114.97.0",
- "188.114.96.0",
- "2a06:98c1:3121::",
- "2a06:98c1:3120::"
- ],
- "favicon": "https://gh-proxy.smyhub.com/favicon.ico",
- "title": "GitHub 文件加速",
- "created_at": "2026-01-27T13:25:11.9196401+08:00",
- "updated_at": "2026-03-06T13:13:12.9476294+08:00"
- },
- {
- "id": "188e7f33f087667c29da05f2",
- "name": "FloppyBird[CloudFlare]",
- "groups": [
- "self-deploy"
- ],
- "urls": [
- {
- "id": "75a0cb223c2d",
- "url": "https://floppy-bird.smyhub.com/",
- "remark": ""
- }
- ],
- "favicon": "https://floppy-bird.smyhub.com/favicon.ico",
- "title": "Floppy Bird",
- "created_at": "2026-01-27T13:26:04.6586487+08:00",
- "updated_at": "2026-01-27T13:26:05.4749231+08:00"
- },
- {
- "id": "188e7f4cdd13a3bc80c68184",
- "name": "别踩白方块[CloudFlare]",
- "groups": [
- "self-deploy"
- ],
- "urls": [
- {
- "id": "9f11daaedba4",
- "url": "https://floppy-bird.smyhub.com/",
- "remark": ""
- }
- ],
- "favicon": "https://floppy-bird.smyhub.com/favicon.ico",
- "title": "Floppy Bird",
- "created_at": "2026-01-27T13:27:51.7064775+08:00",
- "updated_at": "2026-01-27T13:27:51.9331276+08:00"
- }
-]
\ No newline at end of file
diff --git a/mengyaping-backend/docker-compose.yml b/mengyaping-backend/docker-compose.yml
index b64fe0b..6f6e83f 100644
--- a/mengyaping-backend/docker-compose.yml
+++ b/mengyaping-backend/docker-compose.yml
@@ -1,3 +1,5 @@
+# 生产:先在 Windows 运行 build-linux-amd64.bat 生成 dist/mengyaping-backend,再 docker compose build(镜像内不再编译 Go)
+# 若需在服务器上用源码构建镜像:docker build -f Dockerfile.source -t mengyaping-backend:source .
version: '3.8'
services:
@@ -16,11 +18,13 @@ services:
# 服务器配置
- SERVER_PORT=8080
- SERVER_HOST=0.0.0.0
- # 监控配置
- - MONITOR_INTERVAL=5m
+ # 监控默认值(首次写入 MySQL monitor_kv;周期也可在管理后台改,须为 10/20/30/60/180/360 分钟之一)
+ - MONITOR_INTERVAL=30m
- MONITOR_TIMEOUT=10s
- MONITOR_RETRY_COUNT=3
- MONITOR_HISTORY_DAYS=7
+ # 若设置则覆盖数据库 monitor_kv 中的 admin_token(部署密文推荐用环境变量)
+ - ADMIN_TOKEN=shumengya520
networks:
- mengyaping-network
healthcheck:
diff --git a/mengyaping-backend/go.mod b/mengyaping-backend/go.mod
index 5fbb0aa..052e8a7 100644
--- a/mengyaping-backend/go.mod
+++ b/mengyaping-backend/go.mod
@@ -5,9 +5,13 @@ go 1.25.0
require (
github.com/gin-contrib/cors v1.7.6
github.com/gin-gonic/gin v1.11.0
+ gorm.io/datatypes v1.2.4
+ gorm.io/driver/mysql v1.5.7
+ gorm.io/gorm v1.25.12
)
require (
+ filippo.io/edwards25519 v1.1.0 // indirect
github.com/bytedance/sonic v1.14.0 // indirect
github.com/bytedance/sonic/loader v0.3.0 // indirect
github.com/cloudwego/base64x v0.1.6 // indirect
@@ -16,8 +20,12 @@ require (
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.27.0 // indirect
+ github.com/go-sql-driver/mysql v1.8.1 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/goccy/go-yaml v1.18.0 // indirect
+ github.com/google/uuid v1.3.0 // indirect
+ github.com/jinzhu/inflection v1.0.0 // indirect
+ github.com/jinzhu/now v1.1.5 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
diff --git a/mengyaping-backend/go.sum b/mengyaping-backend/go.sum
index 7539074..286fadd 100644
--- a/mengyaping-backend/go.sum
+++ b/mengyaping-backend/go.sum
@@ -1,3 +1,5 @@
+filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
+filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ=
github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA=
github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA=
@@ -23,13 +25,34 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4=
github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
+github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
+github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
+github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
+github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
+github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
+github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
+github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
+github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
+github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA=
+github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
+github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
+github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
+github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
+github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
+github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
+github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
+github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
+github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
@@ -38,6 +61,10 @@ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
+github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
+github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE=
+github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -89,3 +116,16 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gorm.io/datatypes v1.2.4 h1:uZmGAcK/QZ0uyfCuVg0VQY1ZmV9h1fuG0tMwKByO1z4=
+gorm.io/datatypes v1.2.4/go.mod h1:f4BsLcFAX67szSv8svwLRjklArSHAvHLeE3pXAS5DZI=
+gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
+gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
+gorm.io/driver/postgres v1.5.0 h1:u2FXTy14l45qc3UeCJ7QaAXZmZfDDv0YrthvmRq1l0U=
+gorm.io/driver/postgres v1.5.0/go.mod h1:FUZXzO+5Uqg5zzwzv4KK49R8lvGIyscBOqYrtI1Ce9A=
+gorm.io/driver/sqlite v1.4.3 h1:HBBcZSDnWi5BW3B3rwvVTc510KGkBkexlOg0QrmLUuU=
+gorm.io/driver/sqlite v1.4.3/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI=
+gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0=
+gorm.io/driver/sqlserver v1.4.1/go.mod h1:DJ4P+MeZbc5rvY58PnmN1Lnyvb5gw5NPzGshHDnJLig=
+gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
+gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
+gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
diff --git a/mengyaping-backend/handlers/settings.go b/mengyaping-backend/handlers/settings.go
new file mode 100644
index 0000000..e63b9fd
--- /dev/null
+++ b/mengyaping-backend/handlers/settings.go
@@ -0,0 +1,87 @@
+package handlers
+
+import (
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+
+ "mengyaping-backend/config"
+ "mengyaping-backend/models"
+ "mengyaping-backend/services"
+ "mengyaping-backend/storage"
+)
+
+// SettingsHandler 监控与系统配置(公开可读、管理端可写)
+type SettingsHandler struct {
+ monitor *services.MonitorService
+}
+
+// NewSettingsHandler 创建配置处理器
+func NewSettingsHandler() *SettingsHandler {
+ return &SettingsHandler{
+ monitor: services.GetMonitorService(),
+ }
+}
+
+// GetPublicMonitorSettings 公开:当前全局检测周期与可选值
+func (h *SettingsHandler) GetPublicMonitorSettings(c *gin.Context) {
+ cfg := config.GetConfig()
+ c.JSON(http.StatusOK, models.APIResponse{
+ Code: 0,
+ Message: "success",
+ Data: gin.H{
+ "interval_minutes": int(cfg.Monitor.Interval.Minutes()),
+ "allowed_interval_minutes": config.AllowedMonitorIntervalMinutes,
+ },
+ })
+}
+
+// GetAdminConfig 管理端:监控相关配置(只读字段供面板展示)
+func (h *SettingsHandler) GetAdminConfig(c *gin.Context) {
+ cfg := config.GetConfig()
+ c.JSON(http.StatusOK, models.APIResponse{
+ Code: 0,
+ Message: "success",
+ Data: gin.H{
+ "interval_minutes": int(cfg.Monitor.Interval.Minutes()),
+ "allowed_interval_minutes": config.AllowedMonitorIntervalMinutes,
+ "timeout_seconds": int(cfg.Monitor.Timeout.Seconds()),
+ "retry_count": cfg.Monitor.RetryCount,
+ "history_days": cfg.Monitor.HistoryDays,
+ },
+ })
+}
+
+type putAdminMonitorConfigRequest struct {
+ IntervalMinutes int `json:"interval_minutes" binding:"required"`
+}
+
+// PutAdminMonitorConfig 更新全局检测周期并持久化、应用新调度
+func (h *SettingsHandler) PutAdminMonitorConfig(c *gin.Context) {
+ var req putAdminMonitorConfigRequest
+ if err := c.ShouldBindJSON(&req); err != nil {
+ c.JSON(http.StatusBadRequest, models.APIResponse{
+ Code: 400,
+ Message: "参数错误: " + err.Error(),
+ })
+ return
+ }
+
+ if err := storage.GetStorage().SetMonitorIntervalMinutes(req.IntervalMinutes); err != nil {
+ c.JSON(http.StatusBadRequest, models.APIResponse{
+ Code: 400,
+ Message: err.Error(),
+ })
+ return
+ }
+
+ h.monitor.Reschedule()
+
+ c.JSON(http.StatusOK, models.APIResponse{
+ Code: 0,
+ Message: "已更新检测周期",
+ Data: gin.H{
+ "interval_minutes": req.IntervalMinutes,
+ },
+ })
+}
diff --git a/mengyaping-backend/handlers/website.go b/mengyaping-backend/handlers/website.go
index 258eb9e..5dc8cff 100644
--- a/mengyaping-backend/handlers/website.go
+++ b/mengyaping-backend/handlers/website.go
@@ -1,199 +1,267 @@
-package handlers
-
-import (
- "net/http"
-
- "github.com/gin-gonic/gin"
-
- "mengyaping-backend/models"
- "mengyaping-backend/services"
-)
-
-// WebsiteHandler 网站处理器
-type WebsiteHandler struct {
- websiteService *services.WebsiteService
- monitorService *services.MonitorService
-}
-
-// NewWebsiteHandler 创建网站处理器
-func NewWebsiteHandler() *WebsiteHandler {
- return &WebsiteHandler{
- websiteService: services.NewWebsiteService(),
- monitorService: services.GetMonitorService(),
- }
-}
-
-// GetWebsites 获取所有网站状态
-func (h *WebsiteHandler) GetWebsites(c *gin.Context) {
- statuses := h.monitorService.GetAllWebsiteStatuses()
-
- c.JSON(http.StatusOK, models.APIResponse{
- Code: 0,
- Message: "success",
- Data: statuses,
- })
-}
-
-// GetWebsite 获取单个网站状态
-func (h *WebsiteHandler) GetWebsite(c *gin.Context) {
- id := c.Param("id")
-
- status := h.monitorService.GetWebsiteStatus(id)
- if status == nil {
- c.JSON(http.StatusNotFound, models.APIResponse{
- Code: 404,
- Message: "网站不存在",
- })
- return
- }
-
- c.JSON(http.StatusOK, models.APIResponse{
- Code: 0,
- Message: "success",
- Data: status,
- })
-}
-
-// CreateWebsite 创建网站
-func (h *WebsiteHandler) CreateWebsite(c *gin.Context) {
- var req models.CreateWebsiteRequest
- if err := c.ShouldBindJSON(&req); err != nil {
- c.JSON(http.StatusBadRequest, models.APIResponse{
- Code: 400,
- Message: "参数错误: " + err.Error(),
- })
- return
- }
-
- website, err := h.websiteService.CreateWebsite(req)
- if err != nil {
- c.JSON(http.StatusInternalServerError, models.APIResponse{
- Code: 500,
- Message: "创建失败: " + err.Error(),
- })
- return
- }
-
- c.JSON(http.StatusOK, models.APIResponse{
- Code: 0,
- Message: "创建成功",
- Data: website,
- })
-}
-
-// UpdateWebsite 更新网站
-func (h *WebsiteHandler) UpdateWebsite(c *gin.Context) {
- id := c.Param("id")
-
- var req models.UpdateWebsiteRequest
- if err := c.ShouldBindJSON(&req); err != nil {
- c.JSON(http.StatusBadRequest, models.APIResponse{
- Code: 400,
- Message: "参数错误: " + err.Error(),
- })
- return
- }
-
- website, err := h.websiteService.UpdateWebsite(id, req)
- if err != nil {
- c.JSON(http.StatusInternalServerError, models.APIResponse{
- Code: 500,
- Message: "更新失败: " + err.Error(),
- })
- return
- }
-
- if website == nil {
- c.JSON(http.StatusNotFound, models.APIResponse{
- Code: 404,
- Message: "网站不存在",
- })
- return
- }
-
- c.JSON(http.StatusOK, models.APIResponse{
- Code: 0,
- Message: "更新成功",
- Data: website,
- })
-}
-
-// DeleteWebsite 删除网站
-func (h *WebsiteHandler) DeleteWebsite(c *gin.Context) {
- id := c.Param("id")
-
- if err := h.websiteService.DeleteWebsite(id); err != nil {
- c.JSON(http.StatusInternalServerError, models.APIResponse{
- Code: 500,
- Message: "删除失败: " + err.Error(),
- })
- return
- }
-
- c.JSON(http.StatusOK, models.APIResponse{
- Code: 0,
- Message: "删除成功",
- })
-}
-
-// CheckWebsiteNow 立即检测网站
-func (h *WebsiteHandler) CheckWebsiteNow(c *gin.Context) {
- id := c.Param("id")
-
- website := h.websiteService.GetWebsite(id)
- if website == nil {
- c.JSON(http.StatusNotFound, models.APIResponse{
- Code: 404,
- Message: "网站不存在",
- })
- return
- }
-
- h.monitorService.CheckWebsiteNow(id)
-
- c.JSON(http.StatusOK, models.APIResponse{
- Code: 0,
- Message: "检测任务已提交",
- })
-}
-
-// GetGroups 获取所有分组
-func (h *WebsiteHandler) GetGroups(c *gin.Context) {
- groups := h.websiteService.GetGroups()
-
- c.JSON(http.StatusOK, models.APIResponse{
- Code: 0,
- Message: "success",
- Data: groups,
- })
-}
-
-// AddGroup 添加分组
-func (h *WebsiteHandler) AddGroup(c *gin.Context) {
- var req struct {
- Name string `json:"name" binding:"required"`
- }
-
- if err := c.ShouldBindJSON(&req); err != nil {
- c.JSON(http.StatusBadRequest, models.APIResponse{
- Code: 400,
- Message: "参数错误: " + err.Error(),
- })
- return
- }
-
- group, err := h.websiteService.AddGroup(req.Name)
- if err != nil {
- c.JSON(http.StatusInternalServerError, models.APIResponse{
- Code: 500,
- Message: "添加失败: " + err.Error(),
- })
- return
- }
-
- c.JSON(http.StatusOK, models.APIResponse{
- Code: 0,
- Message: "添加成功",
- Data: group,
- })
-}
+package handlers
+
+import (
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+
+ "mengyaping-backend/models"
+ "mengyaping-backend/services"
+)
+
+// WebsiteHandler 网站处理器
+type WebsiteHandler struct {
+ websiteService *services.WebsiteService
+ monitorService *services.MonitorService
+}
+
+// NewWebsiteHandler 创建网站处理器
+func NewWebsiteHandler() *WebsiteHandler {
+ return &WebsiteHandler{
+ websiteService: services.NewWebsiteService(),
+ monitorService: services.GetMonitorService(),
+ }
+}
+
+// GetWebsites 获取所有网站状态
+func (h *WebsiteHandler) GetWebsites(c *gin.Context) {
+ statuses := h.monitorService.GetAllWebsiteStatuses()
+
+ c.JSON(http.StatusOK, models.APIResponse{
+ Code: 0,
+ Message: "success",
+ Data: statuses,
+ })
+}
+
+// GetWebsite 获取单个网站状态
+func (h *WebsiteHandler) GetWebsite(c *gin.Context) {
+ id := c.Param("id")
+
+ status := h.monitorService.GetWebsiteStatus(id)
+ if status == nil {
+ c.JSON(http.StatusNotFound, models.APIResponse{
+ Code: 404,
+ Message: "网站不存在",
+ })
+ return
+ }
+
+ c.JSON(http.StatusOK, models.APIResponse{
+ Code: 0,
+ Message: "success",
+ Data: status,
+ })
+}
+
+// CreateWebsite 创建网站
+func (h *WebsiteHandler) CreateWebsite(c *gin.Context) {
+ var req models.CreateWebsiteRequest
+ if err := c.ShouldBindJSON(&req); err != nil {
+ c.JSON(http.StatusBadRequest, models.APIResponse{
+ Code: 400,
+ Message: "参数错误: " + err.Error(),
+ })
+ return
+ }
+
+ website, err := h.websiteService.CreateWebsite(req)
+ if err != nil {
+ c.JSON(http.StatusInternalServerError, models.APIResponse{
+ Code: 500,
+ Message: "创建失败: " + err.Error(),
+ })
+ return
+ }
+
+ c.JSON(http.StatusOK, models.APIResponse{
+ Code: 0,
+ Message: "创建成功",
+ Data: website,
+ })
+}
+
+// UpdateWebsite 更新网站
+func (h *WebsiteHandler) UpdateWebsite(c *gin.Context) {
+ id := c.Param("id")
+
+ var req models.UpdateWebsiteRequest
+ if err := c.ShouldBindJSON(&req); err != nil {
+ c.JSON(http.StatusBadRequest, models.APIResponse{
+ Code: 400,
+ Message: "参数错误: " + err.Error(),
+ })
+ return
+ }
+
+ website, err := h.websiteService.UpdateWebsite(id, req)
+ if err != nil {
+ c.JSON(http.StatusInternalServerError, models.APIResponse{
+ Code: 500,
+ Message: "更新失败: " + err.Error(),
+ })
+ return
+ }
+
+ if website == nil {
+ c.JSON(http.StatusNotFound, models.APIResponse{
+ Code: 404,
+ Message: "网站不存在",
+ })
+ return
+ }
+
+ c.JSON(http.StatusOK, models.APIResponse{
+ Code: 0,
+ Message: "更新成功",
+ Data: website,
+ })
+}
+
+// DeleteWebsite 删除网站
+func (h *WebsiteHandler) DeleteWebsite(c *gin.Context) {
+ id := c.Param("id")
+
+ if err := h.websiteService.DeleteWebsite(id); err != nil {
+ c.JSON(http.StatusInternalServerError, models.APIResponse{
+ Code: 500,
+ Message: "删除失败: " + err.Error(),
+ })
+ return
+ }
+
+ c.JSON(http.StatusOK, models.APIResponse{
+ Code: 0,
+ Message: "删除成功",
+ })
+}
+
+// CheckWebsiteNow 立即检测网站
+func (h *WebsiteHandler) CheckWebsiteNow(c *gin.Context) {
+ id := c.Param("id")
+
+ website := h.websiteService.GetWebsite(id)
+ if website == nil {
+ c.JSON(http.StatusNotFound, models.APIResponse{
+ Code: 404,
+ Message: "网站不存在",
+ })
+ return
+ }
+
+ h.monitorService.CheckWebsiteNow(id)
+
+ c.JSON(http.StatusOK, models.APIResponse{
+ Code: 0,
+ Message: "检测任务已提交",
+ })
+}
+
+// GetGroups 获取所有分组
+func (h *WebsiteHandler) GetGroups(c *gin.Context) {
+ groups := h.websiteService.GetGroups()
+
+ c.JSON(http.StatusOK, models.APIResponse{
+ Code: 0,
+ Message: "success",
+ Data: groups,
+ })
+}
+
+// GetGroup 获取单个分组
+func (h *WebsiteHandler) GetGroup(c *gin.Context) {
+ id := c.Param("id")
+ g := h.websiteService.GetGroup(id)
+ if g == nil {
+ c.JSON(http.StatusNotFound, models.APIResponse{
+ Code: 404,
+ Message: "分类不存在",
+ })
+ return
+ }
+
+ c.JSON(http.StatusOK, models.APIResponse{
+ Code: 0,
+ Message: "success",
+ Data: g,
+ })
+}
+
+// UpdateGroup 更新分组
+func (h *WebsiteHandler) UpdateGroup(c *gin.Context) {
+ id := c.Param("id")
+
+ var req struct {
+ Name string `json:"name" binding:"required"`
+ }
+ if err := c.ShouldBindJSON(&req); err != nil {
+ c.JSON(http.StatusBadRequest, models.APIResponse{
+ Code: 400,
+ Message: "参数错误: " + err.Error(),
+ })
+ return
+ }
+
+ group, err := h.websiteService.UpdateGroup(id, req.Name)
+ if err != nil {
+ c.JSON(http.StatusBadRequest, models.APIResponse{
+ Code: 400,
+ Message: err.Error(),
+ })
+ return
+ }
+
+ c.JSON(http.StatusOK, models.APIResponse{
+ Code: 0,
+ Message: "更新成功",
+ Data: group,
+ })
+}
+
+// DeleteGroup 删除分组
+func (h *WebsiteHandler) DeleteGroup(c *gin.Context) {
+ id := c.Param("id")
+
+ if err := h.websiteService.DeleteGroup(id); err != nil {
+ c.JSON(http.StatusBadRequest, models.APIResponse{
+ Code: 400,
+ Message: err.Error(),
+ })
+ return
+ }
+
+ c.JSON(http.StatusOK, models.APIResponse{
+ Code: 0,
+ Message: "删除成功",
+ })
+}
+
+// AddGroup 添加分组
+func (h *WebsiteHandler) AddGroup(c *gin.Context) {
+ var req struct {
+ Name string `json:"name" binding:"required"`
+ }
+
+ if err := c.ShouldBindJSON(&req); err != nil {
+ c.JSON(http.StatusBadRequest, models.APIResponse{
+ Code: 400,
+ Message: "参数错误: " + err.Error(),
+ })
+ return
+ }
+
+ group, err := h.websiteService.AddGroup(req.Name)
+ if err != nil {
+ c.JSON(http.StatusInternalServerError, models.APIResponse{
+ Code: 500,
+ Message: "添加失败: " + err.Error(),
+ })
+ return
+ }
+
+ c.JSON(http.StatusOK, models.APIResponse{
+ Code: 0,
+ Message: "添加成功",
+ Data: group,
+ })
+}
diff --git a/mengyaping-backend/main.go b/mengyaping-backend/main.go
index 3286ce9..cb1b66d 100644
--- a/mengyaping-backend/main.go
+++ b/mengyaping-backend/main.go
@@ -1,47 +1,50 @@
-package main
-
-import (
- "fmt"
- "log"
- "os"
- "os/signal"
- "syscall"
-
- "mengyaping-backend/config"
- "mengyaping-backend/router"
- "mengyaping-backend/services"
-)
-
-func main() {
- // 获取配置
- cfg := config.GetConfig()
-
- // 确保数据目录存在
- os.MkdirAll(cfg.DataPath, 0755)
-
- // 启动监控服务
- monitorService := services.GetMonitorService()
- go monitorService.Start()
-
- // 设置路由
- r := router.SetupRouter()
-
- // 优雅关闭
- go func() {
- sigCh := make(chan os.Signal, 1)
- signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
- <-sigCh
-
- log.Println("正在关闭服务...")
- monitorService.Stop()
- os.Exit(0)
- }()
-
- // 启动服务器
- addr := fmt.Sprintf("%s:%s", cfg.Server.Host, cfg.Server.Port)
- log.Printf("🌱 萌芽Ping 监控服务已启动,监听地址: %s\n", addr)
-
- if err := r.Run(addr); err != nil {
- log.Fatalf("服务器启动失败: %v", err)
- }
-}
+package main
+
+import (
+ "fmt"
+ "log"
+ "os"
+ "os/signal"
+ "syscall"
+
+ "mengyaping-backend/config"
+ "mengyaping-backend/router"
+ "mengyaping-backend/services"
+ "mengyaping-backend/storage"
+)
+
+func main() {
+ config.GetConfig()
+ // 连接 MySQL 并从 monitor_kv 加载应用配置(须在监听与监控协程使用配置之前)
+ storage.GetStorage()
+ cfg := config.GetConfig()
+ if err := os.MkdirAll(cfg.DataPath, 0755); err != nil {
+ log.Printf("创建数据目录 %s: %v", cfg.DataPath, err)
+ }
+
+ // 启动监控服务
+ monitorService := services.GetMonitorService()
+ go monitorService.Start()
+
+ // 设置路由
+ r := router.SetupRouter()
+
+ // 优雅关闭
+ go func() {
+ sigCh := make(chan os.Signal, 1)
+ signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
+ <-sigCh
+
+ log.Println("正在关闭服务...")
+ monitorService.Stop()
+ os.Exit(0)
+ }()
+
+ // 启动服务器
+ addr := fmt.Sprintf("%s:%s", cfg.Server.Host, cfg.Server.Port)
+ log.Printf("🌱 萌芽Ping 监控服务已启动,监听地址: %s\n", addr)
+
+ if err := r.Run(addr); err != nil {
+ log.Fatalf("服务器启动失败: %v", err)
+ }
+}
diff --git a/mengyaping-backend/middleware/admin.go b/mengyaping-backend/middleware/admin.go
new file mode 100644
index 0000000..94bfc0c
--- /dev/null
+++ b/mengyaping-backend/middleware/admin.go
@@ -0,0 +1,43 @@
+package middleware
+
+import (
+ "net/http"
+ "strings"
+
+ "github.com/gin-gonic/gin"
+
+ "mengyaping-backend/models"
+ "mengyaping-backend/storage"
+)
+
+// AdminAuth 校验管理员令牌:环境变量 ADMIN_TOKEN 优先,否则使用 MySQL monitor_kv 中的 admin_token(请求头 X-Admin-Token 或 Authorization: Bearer)
+func AdminAuth() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ expected := storage.GetStorage().EffectiveAdminToken()
+ if expected == "" {
+ c.AbortWithStatusJSON(http.StatusServiceUnavailable, models.APIResponse{
+ Code: 503,
+ Message: "未配置管理员令牌:请在数据库 monitor_kv 写入 admin_token,或设置环境变量 ADMIN_TOKEN",
+ })
+ return
+ }
+
+ got := strings.TrimSpace(c.GetHeader("X-Admin-Token"))
+ if got == "" {
+ auth := c.GetHeader("Authorization")
+ const prefix = "Bearer "
+ if len(auth) >= len(prefix) && strings.EqualFold(auth[:len(prefix)], prefix) {
+ got = strings.TrimSpace(auth[len(prefix):])
+ }
+ }
+
+ if got == "" || got != expected {
+ c.AbortWithStatusJSON(http.StatusUnauthorized, models.APIResponse{
+ Code: 401,
+ Message: "无效的管理员令牌",
+ })
+ return
+ }
+ c.Next()
+ }
+}
diff --git a/mengyaping-backend/models/website.go b/mengyaping-backend/models/website.go
index e3a281a..a5ce356 100644
--- a/mengyaping-backend/models/website.go
+++ b/mengyaping-backend/models/website.go
@@ -1,113 +1,117 @@
-package models
-
-import (
- "time"
-)
-
-// Website 网站信息
-type Website struct {
- ID string `json:"id"`
- Name string `json:"name"` // 网站名称
- Groups []string `json:"groups"` // 所属分组列表(支持多分组)
- Group string `json:"group,omitempty"` // 已废弃,仅用于旧数据兼容
- URLs []URLInfo `json:"urls"` // 网站访问地址列表
- IPAddresses []string `json:"ip_addresses,omitempty"` // 域名解析的IP地址
- Favicon string `json:"favicon"` // 网站图标URL
- Title string `json:"title"` // 网站标题
- CreatedAt time.Time `json:"created_at"` // 创建时间
- UpdatedAt time.Time `json:"updated_at"` // 更新时间
-}
-
-// URLInfo 单个URL的信息
-type URLInfo struct {
- ID string `json:"id"`
- URL string `json:"url"` // 访问地址
- Remark string `json:"remark"` // 备注说明
-}
-
-// MonitorRecord 监控记录
-type MonitorRecord struct {
- WebsiteID string `json:"website_id"`
- URLID string `json:"url_id"`
- URL string `json:"url"`
- StatusCode int `json:"status_code"` // HTTP状态码
- Latency int64 `json:"latency"` // 延迟(毫秒)
- IsUp bool `json:"is_up"` // 是否可访问
- Error string `json:"error"` // 错误信息
- CheckedAt time.Time `json:"checked_at"` // 检测时间
-}
-
-// WebsiteStatus 网站状态(用于前端展示)
-type WebsiteStatus struct {
- Website Website `json:"website"`
- URLStatuses []URLStatus `json:"url_statuses"`
- DailyHistory []DailyStats `json:"daily_history"` // 90天逐日统计
- Uptime24h float64 `json:"uptime_24h"` // 24小时可用率
- Uptime7d float64 `json:"uptime_7d"` // 7天可用率
- Uptime90d float64 `json:"uptime_90d"` // 90天可用率
- LastChecked time.Time `json:"last_checked"` // 最后检测时间
-}
-
-// URLStatus 单个URL的状态
-type URLStatus struct {
- URLInfo URLInfo `json:"url_info"`
- CurrentState MonitorRecord `json:"current_state"` // 当前状态
- History24h []MonitorRecord `json:"history_24h"` // 24小时历史
- History7d []HourlyStats `json:"history_7d"` // 7天按小时统计
- Uptime24h float64 `json:"uptime_24h"` // 24小时可用率
- Uptime7d float64 `json:"uptime_7d"` // 7天可用率
- AvgLatency int64 `json:"avg_latency"` // 平均延迟
-}
-
-// HourlyStats 每小时统计
-type HourlyStats struct {
- Hour time.Time `json:"hour"`
- TotalCount int `json:"total_count"`
- UpCount int `json:"up_count"`
- AvgLatency int64 `json:"avg_latency"`
- Uptime float64 `json:"uptime"`
-}
-
-// DailyStats 每日统计
-type DailyStats struct {
- Date time.Time `json:"date"`
- TotalCount int `json:"total_count"`
- UpCount int `json:"up_count"`
- AvgLatency int64 `json:"avg_latency"`
- Uptime float64 `json:"uptime"`
-}
-
-// Group 分组
-type Group struct {
- ID string `json:"id"`
- Name string `json:"name"`
-}
-
-// DefaultGroups 默认分组
-var DefaultGroups = []Group{
- {ID: "normal", Name: "普通网站"},
- {ID: "admin", Name: "管理员网站"},
-}
-
-// CreateWebsiteRequest 创建网站请求
-type CreateWebsiteRequest struct {
- Name string `json:"name" binding:"required"`
- Groups []string `json:"groups" binding:"required,min=1"`
- Group string `json:"group"`
- URLs []string `json:"urls" binding:"required,min=1"`
-}
-
-// UpdateWebsiteRequest 更新网站请求
-type UpdateWebsiteRequest struct {
- Name string `json:"name"`
- Groups []string `json:"groups"`
- Group string `json:"group"`
- URLs []string `json:"urls"`
-}
-
-// APIResponse API响应
-type APIResponse struct {
- Code int `json:"code"`
- Message string `json:"message"`
- Data interface{} `json:"data,omitempty"`
-}
+package models
+
+import (
+ "time"
+)
+
+// Website 网站信息
+type Website struct {
+ ID string `json:"id"`
+ Name string `json:"name"` // 网站名称
+ Groups []string `json:"groups"` // 所属分组列表(支持多分组)
+ Group string `json:"group,omitempty"` // 已废弃,仅用于旧数据兼容
+ URLs []URLInfo `json:"urls"` // 网站访问地址列表
+ IPAddresses []string `json:"ip_addresses,omitempty"` // 域名解析的IP地址
+ Favicon string `json:"favicon"` // 网站图标URL
+ Title string `json:"title"` // 网站标题
+ CreatedAt time.Time `json:"created_at"` // 创建时间
+ UpdatedAt time.Time `json:"updated_at"` // 更新时间
+}
+
+// URLInfo 单个URL的信息
+type URLInfo struct {
+ ID string `json:"id"`
+ URL string `json:"url"` // 访问地址
+ Remark string `json:"remark"` // 备注说明
+}
+
+// MonitorRecord 监控记录
+type MonitorRecord struct {
+ WebsiteID string `json:"website_id"`
+ URLID string `json:"url_id"`
+ URL string `json:"url"`
+ StatusCode int `json:"status_code"` // HTTP状态码
+ Latency int64 `json:"latency"` // 延迟(毫秒)
+ IsUp bool `json:"is_up"` // 是否可访问
+ Error string `json:"error"` // 错误信息
+ CheckedAt time.Time `json:"checked_at"` // 检测时间
+}
+
+// WebsiteStatus 网站状态(用于前端展示)
+type WebsiteStatus struct {
+ Website Website `json:"website"`
+ IsIntranet bool `json:"is_intranet"` // 主 URL 为内网 IP:不解析公网 DNS、不展示解析 IP,用内网图标
+ URLStatuses []URLStatus `json:"url_statuses"`
+ DailyHistory []DailyStats `json:"daily_history"` // 90天逐日统计
+ Uptime24h float64 `json:"uptime_24h"` // 24小时可用率
+ Uptime7d float64 `json:"uptime_7d"` // 7天可用率
+ Uptime90d float64 `json:"uptime_90d"` // 90天可用率
+ LastChecked time.Time `json:"last_checked"` // 最后检测时间
+}
+
+// URLStatus 单个URL的状态
+type URLStatus struct {
+ URLInfo URLInfo `json:"url_info"`
+ CurrentState MonitorRecord `json:"current_state"` // 当前状态
+ History24h []MonitorRecord `json:"history_24h"` // 24小时历史
+ History7d []HourlyStats `json:"history_7d"` // 7天按小时统计
+ Uptime24h float64 `json:"uptime_24h"` // 24小时可用率
+ Uptime7d float64 `json:"uptime_7d"` // 7天可用率
+ AvgLatency int64 `json:"avg_latency"` // 平均延迟
+}
+
+// HourlyStats 每小时统计
+type HourlyStats struct {
+ Hour time.Time `json:"hour"`
+ TotalCount int `json:"total_count"`
+ UpCount int `json:"up_count"`
+ AvgLatency int64 `json:"avg_latency"`
+ Uptime float64 `json:"uptime"`
+}
+
+// DailyStats 每日统计
+type DailyStats struct {
+ Date time.Time `json:"date"`
+ TotalCount int `json:"total_count"`
+ UpCount int `json:"up_count"`
+ AvgLatency int64 `json:"avg_latency"`
+ Uptime float64 `json:"uptime"`
+}
+
+// Group 分组
+type Group struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+}
+
+// DefaultGroups 默认分组
+var DefaultGroups = []Group{
+ {ID: "normal", Name: "普通网站"},
+ {ID: "admin", Name: "管理员网站"},
+}
+
+// DefaultIntranetFavicon 直填内网站点的列表图标(静态 SVG,不依赖公网 favicon 抓取)
+const DefaultIntranetFavicon = "https://api.iconify.design/mdi/lan-connect.svg?color=%23059669"
+
+// CreateWebsiteRequest 创建网站请求
+type CreateWebsiteRequest struct {
+ Name string `json:"name" binding:"required"`
+ Groups []string `json:"groups" binding:"required,min=1"`
+ Group string `json:"group"`
+ URLs []string `json:"urls" binding:"required,min=1"`
+}
+
+// UpdateWebsiteRequest 更新网站请求
+type UpdateWebsiteRequest struct {
+ Name string `json:"name"`
+ Groups []string `json:"groups"`
+ Group string `json:"group"`
+ URLs []string `json:"urls"`
+}
+
+// APIResponse API响应
+type APIResponse struct {
+ Code int `json:"code"`
+ Message string `json:"message"`
+ Data interface{} `json:"data,omitempty"`
+}
diff --git a/mengyaping-backend/router/router.go b/mengyaping-backend/router/router.go
index e6177d8..657e2e0 100644
--- a/mengyaping-backend/router/router.go
+++ b/mengyaping-backend/router/router.go
@@ -1,51 +1,66 @@
-package router
-
-import (
- "github.com/gin-contrib/cors"
- "github.com/gin-gonic/gin"
-
- "mengyaping-backend/handlers"
-)
-
-// SetupRouter 设置路由
-func SetupRouter() *gin.Engine {
- r := gin.Default()
-
- // CORS配置
- r.Use(cors.New(cors.Config{
- AllowOrigins: []string{"*"},
- AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
- AllowHeaders: []string{"Origin", "Content-Type", "Accept", "Authorization"},
- ExposeHeaders: []string{"Content-Length"},
- AllowCredentials: true,
- }))
-
- // 创建处理器
- websiteHandler := handlers.NewWebsiteHandler()
-
- // API路由组
- api := r.Group("/api")
- {
- // 健康检查
- api.GET("/health", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "status": "ok",
- "message": "服务运行正常",
- })
- })
-
- // 网站相关
- api.GET("/websites", websiteHandler.GetWebsites)
- api.GET("/websites/:id", websiteHandler.GetWebsite)
- api.POST("/websites", websiteHandler.CreateWebsite)
- api.PUT("/websites/:id", websiteHandler.UpdateWebsite)
- api.DELETE("/websites/:id", websiteHandler.DeleteWebsite)
- api.POST("/websites/:id/check", websiteHandler.CheckWebsiteNow)
-
- // 分组相关
- api.GET("/groups", websiteHandler.GetGroups)
- api.POST("/groups", websiteHandler.AddGroup)
- }
-
- return r
-}
+package router
+
+import (
+ "github.com/gin-contrib/cors"
+ "github.com/gin-gonic/gin"
+
+ "mengyaping-backend/handlers"
+ "mengyaping-backend/middleware"
+)
+
+// SetupRouter 设置路由
+func SetupRouter() *gin.Engine {
+ r := gin.Default()
+
+ // CORS配置
+ r.Use(cors.New(cors.Config{
+ AllowOrigins: []string{"*"},
+ AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
+ AllowHeaders: []string{"Origin", "Content-Type", "Accept", "Authorization", "X-Admin-Token"},
+ ExposeHeaders: []string{"Content-Length"},
+ AllowCredentials: true,
+ }))
+
+ // 创建处理器
+ websiteHandler := handlers.NewWebsiteHandler()
+ settingsHandler := handlers.NewSettingsHandler()
+
+ // API路由组
+ api := r.Group("/api")
+ {
+ // 健康检查
+ api.GET("/health", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "status": "ok",
+ "message": "服务运行正常",
+ })
+ })
+
+ // 公开:监控调度信息(仅展示)
+ api.GET("/monitor/settings", settingsHandler.GetPublicMonitorSettings)
+
+ // 网站 / 分组 — 读操作公开
+ api.GET("/websites", websiteHandler.GetWebsites)
+ api.GET("/websites/:id", websiteHandler.GetWebsite)
+ api.GET("/groups", websiteHandler.GetGroups)
+ api.GET("/groups/:id", websiteHandler.GetGroup)
+
+ // 管理:写操作需 ADMIN_TOKEN
+ admin := api.Group("")
+ admin.Use(middleware.AdminAuth())
+ {
+ admin.POST("/websites", websiteHandler.CreateWebsite)
+ admin.PUT("/websites/:id", websiteHandler.UpdateWebsite)
+ admin.DELETE("/websites/:id", websiteHandler.DeleteWebsite)
+ admin.POST("/websites/:id/check", websiteHandler.CheckWebsiteNow)
+ admin.POST("/groups", websiteHandler.AddGroup)
+ admin.PUT("/groups/:id", websiteHandler.UpdateGroup)
+ admin.DELETE("/groups/:id", websiteHandler.DeleteGroup)
+
+ admin.GET("/admin/config", settingsHandler.GetAdminConfig)
+ admin.PUT("/admin/config", settingsHandler.PutAdminMonitorConfig)
+ }
+ }
+
+ return r
+}
diff --git a/mengyaping-backend/schema/mysql.sql b/mengyaping-backend/schema/mysql.sql
new file mode 100644
index 0000000..33139e8
--- /dev/null
+++ b/mengyaping-backend/schema/mysql.sql
@@ -0,0 +1,19 @@
+-- 萌芽 Ping — MySQL 8+ 表结构说明(应用启动时 GORM AutoMigrate 会自动建表;本文件便于 DBA 审阅或手工执行)
+-- 字符集务必 utf8mb4
+
+CREATE DATABASE IF NOT EXISTS mengyaping
+ DEFAULT CHARACTER SET utf8mb4
+ COLLATE utf8mb4_unicode_ci;
+
+USE mengyaping;
+
+-- monitor_groups 网站分类
+-- monitor_websites 监控站点主档(ip_addresses 为 JSON 数组)
+-- monitor_website_urls 每个站点下多监控 URL
+-- monitor_website_groups 站点与分类多对多
+-- monitor_checks HTTP 探活历史(按保留天数定期清理)
+
+-- monitor_kv 键值配置:admin_token;cfg_server / cfg_monitor / cfg_data_path / cfg_database(JSON)
+-- 与下列 GORM 模型一致:
+-- MonitorGroup, MonitorWebsite, MonitorWebsiteURL, MonitorWebsiteGroup,
+-- MonitorProbeLatest, MonitorProbeHour, MonitorProbeDay, MonitorKV
diff --git a/mengyaping-backend/services/monitor.go b/mengyaping-backend/services/monitor.go
index 757ceb5..dbe89fc 100644
--- a/mengyaping-backend/services/monitor.go
+++ b/mengyaping-backend/services/monitor.go
@@ -1,418 +1,488 @@
-package services
-
-import (
- "log"
- "sort"
- "sync"
- "time"
-
- "mengyaping-backend/config"
- "mengyaping-backend/models"
- "mengyaping-backend/storage"
- "mengyaping-backend/utils"
-)
-
-// MonitorService 监控服务
-type MonitorService struct {
- httpClient *utils.HTTPClient
- storage *storage.Storage
- stopCh chan struct{}
- running bool
- mu sync.Mutex
-}
-
-var (
- monitorService *MonitorService
- monitorOnce sync.Once
-)
-
-// GetMonitorService 获取监控服务单例
-func GetMonitorService() *MonitorService {
- monitorOnce.Do(func() {
- cfg := config.GetConfig()
- monitorService = &MonitorService{
- httpClient: utils.NewHTTPClient(cfg.Monitor.Timeout),
- storage: storage.GetStorage(),
- stopCh: make(chan struct{}),
- }
- })
- return monitorService
-}
-
-// Start 启动监控服务
-func (s *MonitorService) Start() {
- s.mu.Lock()
- if s.running {
- s.mu.Unlock()
- return
- }
- s.running = true
- s.mu.Unlock()
-
- log.Println("监控服务已启动")
-
- // 立即执行一次检测
- go s.checkAll()
-
- // 定时检测
- cfg := config.GetConfig()
- ticker := time.NewTicker(cfg.Monitor.Interval)
- defer ticker.Stop()
-
- for {
- select {
- case <-ticker.C:
- go s.checkAll()
- case <-s.stopCh:
- log.Println("监控服务已停止")
- return
- }
- }
-}
-
-// Stop 停止监控服务
-func (s *MonitorService) Stop() {
- s.mu.Lock()
- defer s.mu.Unlock()
-
- if s.running {
- close(s.stopCh)
- s.running = false
- }
-}
-
-// checkAll 检查所有网站(错峰执行,避免并发暴涨)
-func (s *MonitorService) checkAll() {
- websites := s.storage.GetWebsites()
- semaphore := make(chan struct{}, 3) // 最多 3 个并发检测
-
- for i, website := range websites {
- // 每个网站之间间隔 1 秒,把检测分散开
- if i > 0 {
- time.Sleep(1 * time.Second)
- }
-
- var wg sync.WaitGroup
- for _, urlInfo := range website.URLs {
- wg.Add(1)
- go func(w models.Website, u models.URLInfo) {
- defer wg.Done()
- semaphore <- struct{}{}
- defer func() { <-semaphore }()
- s.checkURL(w, u)
- }(website, urlInfo)
- }
- wg.Wait()
- }
-
- // 检测完毕后,逐个解析 DNS
- s.resolveAllWebsiteIPs(websites)
-
- // 保存记录
- s.storage.SaveAll()
- log.Printf("本轮检测完成,共 %d 个网站", len(websites))
-}
-
-// resolveAllWebsiteIPs 逐个解析所有网站域名 IP(每次都刷新)
-func (s *MonitorService) resolveAllWebsiteIPs(websites []models.Website) {
- for i, website := range websites {
- if len(website.URLs) == 0 {
- continue
- }
- if i > 0 {
- time.Sleep(500 * time.Millisecond)
- }
- s.resolveWebsiteIP(website)
- }
-}
-
-// resolveWebsiteIP 解析单个网站的域名 IP
-func (s *MonitorService) resolveWebsiteIP(website models.Website) {
- if len(website.URLs) == 0 {
- return
- }
-
- ips, err := utils.ResolveDomainIPs(website.URLs[0].URL)
- if err != nil {
- log.Printf("DNS解析失败 [%s]: %v", website.Name, err)
- return
- }
-
- if len(ips) == 0 {
- return
- }
-
- w := s.storage.GetWebsite(website.ID)
- if w == nil {
- return
- }
-
- w.IPAddresses = ips
- w.UpdatedAt = time.Now()
- s.storage.UpdateWebsite(*w)
- log.Printf("DNS解析 [%s] → %v", website.Name, ips)
-}
-
-// checkURL 检查单个URL(带重试)
-func (s *MonitorService) checkURL(website models.Website, urlInfo models.URLInfo) {
- cfg := config.GetConfig()
- maxRetries := cfg.Monitor.RetryCount
-
- var result utils.CheckResult
-
- for attempt := 0; attempt <= maxRetries; attempt++ {
- if attempt > 0 {
- time.Sleep(time.Duration(attempt) * 2 * time.Second)
- log.Printf("重试 [%s] %s - 第 %d 次重试", website.Name, urlInfo.URL, attempt)
- }
-
- result = s.httpClient.CheckWebsiteStatus(urlInfo.URL)
- if result.Error == nil && utils.IsSuccessStatus(result.StatusCode) {
- break
- }
- }
-
- record := models.MonitorRecord{
- WebsiteID: website.ID,
- URLID: urlInfo.ID,
- URL: urlInfo.URL,
- StatusCode: result.StatusCode,
- Latency: result.Latency.Milliseconds(),
- IsUp: result.Error == nil && utils.IsSuccessStatus(result.StatusCode),
- CheckedAt: time.Now(),
- }
-
- if result.Error != nil {
- record.Error = result.Error.Error()
- }
-
- s.storage.AddRecord(record)
-
- // 仅当网站无标题时才做完整检测来获取元数据
- if record.IsUp && website.Title == "" {
- fullResult := s.httpClient.CheckWebsite(urlInfo.URL)
- if fullResult.Title != "" {
- w := s.storage.GetWebsite(website.ID)
- if w != nil {
- w.Title = fullResult.Title
- w.UpdatedAt = time.Now()
- s.storage.UpdateWebsite(*w)
- }
- }
- }
-
- log.Printf("检测 [%s] %s - 状态码: %d, 延迟: %dms, 可用: %v",
- website.Name, urlInfo.URL, result.StatusCode, result.Latency.Milliseconds(), record.IsUp)
-}
-
-// CheckWebsiteNow 立即检查指定网站(状态 + DNS,等待完成后保存)
-func (s *MonitorService) CheckWebsiteNow(websiteID string) {
- website := s.storage.GetWebsite(websiteID)
- if website == nil {
- return
- }
-
- // 逐个检测该网站的所有 URL
- for _, urlInfo := range website.URLs {
- s.checkURL(*website, urlInfo)
- }
-
- // 刷新 DNS
- s.resolveWebsiteIP(*website)
-
- s.storage.SaveAll()
-}
-
-// GetWebsiteStatus 获取网站状态
-func (s *MonitorService) GetWebsiteStatus(websiteID string) *models.WebsiteStatus {
- website := s.storage.GetWebsite(websiteID)
- if website == nil {
- return nil
- }
-
- status := &models.WebsiteStatus{
- Website: *website,
- URLStatuses: []models.URLStatus{},
- }
-
- now := time.Now()
- since24h := now.Add(-24 * time.Hour)
- since7d := now.Add(-7 * 24 * time.Hour)
- since90d := now.Add(-90 * 24 * time.Hour)
-
- var totalUptime24h, totalUptime7d float64
- var urlCount int
- var allRecords90d []models.MonitorRecord
-
- for _, urlInfo := range website.URLs {
- urlStatus := s.getURLStatus(website.ID, urlInfo, since24h, since7d)
- status.URLStatuses = append(status.URLStatuses, urlStatus)
-
- totalUptime24h += urlStatus.Uptime24h
- totalUptime7d += urlStatus.Uptime7d
- urlCount++
-
- records90d := s.storage.GetRecords(website.ID, urlInfo.ID, since90d)
- allRecords90d = append(allRecords90d, records90d...)
- }
-
- if urlCount > 0 {
- status.Uptime24h = totalUptime24h / float64(urlCount)
- status.Uptime7d = totalUptime7d / float64(urlCount)
- }
-
- // 90 天逐日统计
- status.DailyHistory = s.aggregateByDay(allRecords90d)
- if len(allRecords90d) > 0 {
- upCount := 0
- for _, r := range allRecords90d {
- if r.IsUp {
- upCount++
- }
- }
- status.Uptime90d = float64(upCount) / float64(len(allRecords90d)) * 100
- }
-
- // 获取最后检测时间
- for _, urlStatus := range status.URLStatuses {
- if urlStatus.CurrentState.CheckedAt.After(status.LastChecked) {
- status.LastChecked = urlStatus.CurrentState.CheckedAt
- }
- }
-
- return status
-}
-
-// getURLStatus 获取URL状态
-func (s *MonitorService) getURLStatus(websiteID string, urlInfo models.URLInfo, since24h, since7d time.Time) models.URLStatus {
- urlStatus := models.URLStatus{
- URLInfo: urlInfo,
- }
-
- // 获取最新记录
- latest := s.storage.GetLatestRecord(websiteID, urlInfo.ID)
- if latest != nil {
- urlStatus.CurrentState = *latest
- }
-
- // 获取24小时记录
- records24h := s.storage.GetRecords(websiteID, urlInfo.ID, since24h)
- urlStatus.History24h = records24h
-
- // 计算24小时可用率
- if len(records24h) > 0 {
- upCount := 0
- var totalLatency int64
- for _, r := range records24h {
- if r.IsUp {
- upCount++
- }
- totalLatency += r.Latency
- }
- urlStatus.Uptime24h = float64(upCount) / float64(len(records24h)) * 100
- urlStatus.AvgLatency = totalLatency / int64(len(records24h))
- }
-
- // 获取7天记录并按小时统计
- records7d := s.storage.GetRecords(websiteID, urlInfo.ID, since7d)
- urlStatus.History7d = s.aggregateByHour(records7d)
-
- // 计算7天可用率
- if len(records7d) > 0 {
- upCount := 0
- for _, r := range records7d {
- if r.IsUp {
- upCount++
- }
- }
- urlStatus.Uptime7d = float64(upCount) / float64(len(records7d)) * 100
- }
-
- return urlStatus
-}
-
-// aggregateByHour 按小时聚合记录
-func (s *MonitorService) aggregateByHour(records []models.MonitorRecord) []models.HourlyStats {
- hourlyMap := make(map[string]*models.HourlyStats)
-
- for _, r := range records {
- hourKey := r.CheckedAt.Truncate(time.Hour).Format(time.RFC3339)
-
- if _, exists := hourlyMap[hourKey]; !exists {
- hourlyMap[hourKey] = &models.HourlyStats{
- Hour: r.CheckedAt.Truncate(time.Hour),
- }
- }
-
- stats := hourlyMap[hourKey]
- stats.TotalCount++
- if r.IsUp {
- stats.UpCount++
- }
- stats.AvgLatency += r.Latency
- }
-
- var result []models.HourlyStats
- for _, stats := range hourlyMap {
- if stats.TotalCount > 0 {
- stats.AvgLatency /= int64(stats.TotalCount)
- stats.Uptime = float64(stats.UpCount) / float64(stats.TotalCount) * 100
- }
- result = append(result, *stats)
- }
-
- return result
-}
-
-// aggregateByDay 按天聚合记录
-func (s *MonitorService) aggregateByDay(records []models.MonitorRecord) []models.DailyStats {
- dayMap := make(map[string]*models.DailyStats)
-
- for _, r := range records {
- dayTime := time.Date(r.CheckedAt.Year(), r.CheckedAt.Month(), r.CheckedAt.Day(), 0, 0, 0, 0, r.CheckedAt.Location())
- dayKey := dayTime.Format("2006-01-02")
-
- if _, exists := dayMap[dayKey]; !exists {
- dayMap[dayKey] = &models.DailyStats{
- Date: dayTime,
- }
- }
-
- stats := dayMap[dayKey]
- stats.TotalCount++
- if r.IsUp {
- stats.UpCount++
- }
- stats.AvgLatency += r.Latency
- }
-
- result := make([]models.DailyStats, 0, len(dayMap))
- for _, stats := range dayMap {
- if stats.TotalCount > 0 {
- stats.AvgLatency /= int64(stats.TotalCount)
- stats.Uptime = float64(stats.UpCount) / float64(stats.TotalCount) * 100
- }
- result = append(result, *stats)
- }
-
- sort.Slice(result, func(i, j int) bool {
- return result[i].Date.Before(result[j].Date)
- })
-
- return result
-}
-
-// GetAllWebsiteStatuses 获取所有网站状态
-func (s *MonitorService) GetAllWebsiteStatuses() []models.WebsiteStatus {
- websites := s.storage.GetWebsites()
- var statuses []models.WebsiteStatus
-
- for _, website := range websites {
- status := s.GetWebsiteStatus(website.ID)
- if status != nil {
- statuses = append(statuses, *status)
- }
- }
-
- return statuses
-}
+package services
+
+import (
+ "log"
+ "sync"
+ "time"
+
+ "mengyaping-backend/config"
+ "mengyaping-backend/models"
+ "mengyaping-backend/storage"
+ "mengyaping-backend/utils"
+)
+
+// MonitorService 监控服务
+type MonitorService struct {
+ httpClient *utils.HTTPClient
+ storage *storage.Storage
+ stopCh chan struct{}
+ rescheduleCh chan struct{}
+ running bool
+ mu sync.Mutex
+}
+
+var (
+ monitorService *MonitorService
+ monitorOnce sync.Once
+)
+
+// GetMonitorService 获取监控服务单例
+func GetMonitorService() *MonitorService {
+ monitorOnce.Do(func() {
+ st := storage.GetStorage()
+ cfg := config.GetConfig()
+ monitorService = &MonitorService{
+ httpClient: utils.NewHTTPClient(cfg.Monitor.Timeout),
+ storage: st,
+ stopCh: make(chan struct{}),
+ rescheduleCh: make(chan struct{}, 1),
+ }
+ })
+ return monitorService
+}
+
+// Start 启动监控服务
+func (s *MonitorService) Start() {
+ s.mu.Lock()
+ if s.running {
+ s.mu.Unlock()
+ return
+ }
+ s.running = true
+ s.mu.Unlock()
+
+ log.Println("监控服务已启动")
+ go s.runLoop()
+}
+
+// Reschedule 在检测间隔配置变更后唤醒主循环以使用新周期(非阻塞)
+func (s *MonitorService) Reschedule() {
+ select {
+ case s.rescheduleCh <- struct{}{}:
+ default:
+ }
+}
+
+func (s *MonitorService) runLoop() {
+ go s.checkAll()
+
+ d := config.GetConfig().Monitor.Interval
+ if d <= 0 {
+ d = 30 * time.Minute
+ }
+ timer := time.NewTimer(d)
+ defer timer.Stop()
+
+ for {
+ select {
+ case <-s.stopCh:
+ if !timer.Stop() {
+ select {
+ case <-timer.C:
+ default:
+ }
+ }
+ log.Println("监控服务已停止")
+ return
+ case <-s.rescheduleCh:
+ if !timer.Stop() {
+ select {
+ case <-timer.C:
+ default:
+ }
+ }
+ d = config.GetConfig().Monitor.Interval
+ if d <= 0 {
+ d = 30 * time.Minute
+ }
+ timer.Reset(d)
+ case <-timer.C:
+ go s.checkAll()
+ d = config.GetConfig().Monitor.Interval
+ if d <= 0 {
+ d = 30 * time.Minute
+ }
+ timer.Reset(d)
+ }
+ }
+}
+
+// Stop 停止监控服务
+func (s *MonitorService) Stop() {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+
+ if s.running {
+ close(s.stopCh)
+ s.running = false
+ }
+}
+
+// checkAll 检查所有网站(错峰执行,避免并发暴涨)
+func (s *MonitorService) checkAll() {
+ websites := s.storage.GetWebsites()
+ semaphore := make(chan struct{}, 3) // 最多 3 个并发检测
+
+ for i, website := range websites {
+ // 每个网站之间间隔 1 秒,把检测分散开
+ if i > 0 {
+ time.Sleep(1 * time.Second)
+ }
+
+ var wg sync.WaitGroup
+ for _, urlInfo := range website.URLs {
+ wg.Add(1)
+ go func(w models.Website, u models.URLInfo) {
+ defer wg.Done()
+ semaphore <- struct{}{}
+ defer func() { <-semaphore }()
+ s.checkURL(w, u)
+ }(website, urlInfo)
+ }
+ wg.Wait()
+ }
+
+ // 检测完毕后,逐个解析 DNS
+ s.resolveAllWebsiteIPs(websites)
+
+ // 保存记录
+ s.storage.SaveAll()
+ log.Printf("本轮检测完成,共 %d 个网站", len(websites))
+}
+
+// resolveAllWebsiteIPs 逐个解析所有网站域名 IP(每次都刷新)
+func (s *MonitorService) resolveAllWebsiteIPs(websites []models.Website) {
+ for i, website := range websites {
+ if len(website.URLs) == 0 {
+ continue
+ }
+ if i > 0 {
+ time.Sleep(500 * time.Millisecond)
+ }
+ s.resolveWebsiteIP(website)
+ }
+}
+
+// resolveWebsiteIP 解析单个网站的域名 IP
+func (s *MonitorService) resolveWebsiteIP(website models.Website) {
+ if len(website.URLs) == 0 {
+ return
+ }
+
+ if utils.IsIntranetURL(website.URLs[0].URL) {
+ w := s.storage.GetWebsite(website.ID)
+ if w != nil && len(w.IPAddresses) > 0 {
+ w.IPAddresses = nil
+ w.UpdatedAt = time.Now()
+ s.storage.UpdateWebsite(*w)
+ }
+ return
+ }
+
+ ips, err := utils.ResolveDomainIPs(website.URLs[0].URL)
+ if err != nil {
+ log.Printf("DNS解析失败 [%s]: %v", website.Name, err)
+ return
+ }
+
+ if len(ips) == 0 {
+ return
+ }
+
+ w := s.storage.GetWebsite(website.ID)
+ if w == nil {
+ return
+ }
+
+ w.IPAddresses = ips
+ w.UpdatedAt = time.Now()
+ s.storage.UpdateWebsite(*w)
+ log.Printf("DNS解析 [%s] → %v", website.Name, ips)
+}
+
+// checkURL 检查单个URL(带重试)
+func (s *MonitorService) checkURL(website models.Website, urlInfo models.URLInfo) {
+ cfg := config.GetConfig()
+ maxRetries := cfg.Monitor.RetryCount
+
+ var result utils.CheckResult
+
+ for attempt := 0; attempt <= maxRetries; attempt++ {
+ if attempt > 0 {
+ time.Sleep(time.Duration(attempt) * 2 * time.Second)
+ log.Printf("重试 [%s] %s - 第 %d 次重试", website.Name, urlInfo.URL, attempt)
+ }
+
+ result = s.httpClient.CheckWebsiteStatus(urlInfo.URL)
+ if result.Error == nil && utils.IsSuccessStatus(result.StatusCode) {
+ break
+ }
+ }
+
+ record := models.MonitorRecord{
+ WebsiteID: website.ID,
+ URLID: urlInfo.ID,
+ URL: urlInfo.URL,
+ StatusCode: result.StatusCode,
+ Latency: result.Latency.Milliseconds(),
+ IsUp: result.Error == nil && utils.IsSuccessStatus(result.StatusCode),
+ CheckedAt: time.Now(),
+ }
+
+ if result.Error != nil {
+ record.Error = result.Error.Error()
+ }
+
+ s.storage.AddRecord(record)
+
+ // 仅当网站无标题时才做完整检测来获取元数据
+ if record.IsUp && website.Title == "" {
+ fullResult := s.httpClient.CheckWebsite(urlInfo.URL)
+ if fullResult.Title != "" {
+ w := s.storage.GetWebsite(website.ID)
+ if w != nil {
+ w.Title = fullResult.Title
+ w.UpdatedAt = time.Now()
+ s.storage.UpdateWebsite(*w)
+ }
+ }
+ }
+
+ log.Printf("检测 [%s] %s - 状态码: %d, 延迟: %dms, 可用: %v",
+ website.Name, urlInfo.URL, result.StatusCode, result.Latency.Milliseconds(), record.IsUp)
+}
+
+// CheckWebsiteNow 立即检查指定网站(状态 + DNS,等待完成后保存)
+func (s *MonitorService) CheckWebsiteNow(websiteID string) {
+ website := s.storage.GetWebsite(websiteID)
+ if website == nil {
+ return
+ }
+
+ // 逐个检测该网站的所有 URL
+ for _, urlInfo := range website.URLs {
+ s.checkURL(*website, urlInfo)
+ }
+
+ // 刷新 DNS
+ s.resolveWebsiteIP(*website)
+
+ s.storage.SaveAll()
+}
+
+// GetWebsiteStatus 获取网站状态
+func (s *MonitorService) GetWebsiteStatus(websiteID string) *models.WebsiteStatus {
+ website := s.storage.GetWebsite(websiteID)
+ if website == nil {
+ return nil
+ }
+
+ isIntranet := len(website.URLs) > 0 && utils.IsIntranetURL(website.URLs[0].URL)
+ status := &models.WebsiteStatus{
+ Website: *website,
+ IsIntranet: isIntranet,
+ URLStatuses: []models.URLStatus{},
+ }
+
+ now := time.Now()
+ since24h := now.Add(-24 * time.Hour)
+ since7d := now.Add(-7 * 24 * time.Hour)
+ since90d := now.Add(-90 * 24 * time.Hour)
+
+ var totalUptime24h, totalUptime7d float64
+ var urlCount int
+
+ for _, urlInfo := range website.URLs {
+ urlStatus := s.getURLStatus(website.ID, urlInfo, since24h, since7d)
+ status.URLStatuses = append(status.URLStatuses, urlStatus)
+
+ totalUptime24h += urlStatus.Uptime24h
+ totalUptime7d += urlStatus.Uptime7d
+ urlCount++
+ }
+
+ if urlCount > 0 {
+ status.Uptime24h = totalUptime24h / float64(urlCount)
+ status.Uptime7d = totalUptime7d / float64(urlCount)
+ }
+
+ status.DailyHistory = s.storage.GetWebsiteDailyAggregates(website.ID, since90d)
+ if pt, ut := s.storage.GetWebsiteDayProbeTotals(website.ID, since90d); pt > 0 {
+ status.Uptime90d = float64(ut) / float64(pt) * 100
+ }
+
+ // 获取最后检测时间
+ for _, urlStatus := range status.URLStatuses {
+ if urlStatus.CurrentState.CheckedAt.After(status.LastChecked) {
+ status.LastChecked = urlStatus.CurrentState.CheckedAt
+ }
+ }
+
+ return status
+}
+
+// getURLStatus 获取URL状态:每个 URL 仅 1 次读小时表 + 1 次读 latest(在内存拆 24h/7d)
+func (s *MonitorService) getURLStatus(websiteID string, urlInfo models.URLInfo, since24h, since7d time.Time) models.URLStatus {
+ var latest *models.MonitorRecord
+ if rec := s.storage.GetLatestRecord(websiteID, urlInfo.ID); rec != nil {
+ latest = rec
+ }
+ hRows := s.storage.GetProbeHourRowsForURL(websiteID, urlInfo.ID, since7d)
+ return s.buildURLStatusFromHours(websiteID, urlInfo, since24h, since7d, latest, hRows)
+}
+
+func hourlyStatFromProbeRow(h storage.MonitorProbeHour) models.HourlyStats {
+ st := models.HourlyStats{
+ Hour: h.HourAt,
+ TotalCount: h.ProbeCount,
+ UpCount: h.UpCount,
+ }
+ if h.ProbeCount > 0 {
+ st.AvgLatency = h.LatencySum / int64(h.ProbeCount)
+ st.Uptime = float64(h.UpCount) / float64(h.ProbeCount) * 100
+ }
+ return st
+}
+
+func hourWindowsFromRows(rows []storage.MonitorProbeHour, since24h, since7d time.Time) (
+ stats24h []models.HourlyStats,
+ stats7d []models.HourlyStats,
+ t24, u24, l24, t7, u7 int64,
+) {
+ for _, h := range rows {
+ if !h.HourAt.Before(since7d) {
+ t7 += int64(h.ProbeCount)
+ u7 += int64(h.UpCount)
+ stats7d = append(stats7d, hourlyStatFromProbeRow(h))
+ }
+ if !h.HourAt.Before(since24h) {
+ t24 += int64(h.ProbeCount)
+ u24 += int64(h.UpCount)
+ l24 += h.LatencySum
+ stats24h = append(stats24h, hourlyStatFromProbeRow(h))
+ }
+ }
+ return stats24h, stats7d, t24, u24, l24, t7, u7
+}
+
+func (s *MonitorService) buildURLStatusFromHours(
+ websiteID string,
+ urlInfo models.URLInfo,
+ since24h, since7d time.Time,
+ latest *models.MonitorRecord,
+ hRows []storage.MonitorProbeHour,
+) models.URLStatus {
+ urlStatus := models.URLStatus{URLInfo: urlInfo}
+ if latest != nil {
+ urlStatus.CurrentState = *latest
+ }
+ s24, s7, t24, u24, l24, t7, u7 := hourWindowsFromRows(hRows, since24h, since7d)
+ urlStatus.History24h = hourlyStatsToMonitorRecords(websiteID, urlInfo.ID, s24)
+ if t24 > 0 {
+ urlStatus.Uptime24h = float64(u24) / float64(t24) * 100
+ urlStatus.AvgLatency = l24 / t24
+ }
+ urlStatus.History7d = s7
+ if t7 > 0 {
+ urlStatus.Uptime7d = float64(u7) / float64(t7) * 100
+ }
+ return urlStatus
+}
+
+func hourlyStatsToMonitorRecords(websiteID, urlID string, stats []models.HourlyStats) []models.MonitorRecord {
+ out := make([]models.MonitorRecord, 0, len(stats))
+ for _, h := range stats {
+ isUp := h.TotalCount > 0 && h.UpCount*2 >= h.TotalCount
+ out = append(out, models.MonitorRecord{
+ WebsiteID: websiteID,
+ URLID: urlID,
+ Latency: h.AvgLatency,
+ IsUp: isUp,
+ CheckedAt: h.Hour,
+ })
+ }
+ return out
+}
+
+// GetAllWebsiteStatuses 获取所有网站状态(批量查 probe 表,避免每个站点/URL 多次 SQL)
+func (s *MonitorService) GetAllWebsiteStatuses() []models.WebsiteStatus {
+ websites := s.storage.GetWebsites()
+ if len(websites) == 0 {
+ return nil
+ }
+
+ now := time.Now()
+ since24h := now.Add(-24 * time.Hour)
+ since7d := now.Add(-7 * 24 * time.Hour)
+ since90d := now.Add(-90 * 24 * time.Hour)
+ since90dDay := time.Date(since90d.Year(), since90d.Month(), since90d.Day(), 0, 0, 0, 0, since90d.Location())
+
+ latestMap := s.storage.GetProbeLatestKeyMap()
+ hourMap := s.storage.GroupProbeHoursSince(since7d)
+ dailyBySite, uptime90dBySite := s.storage.LoadAllWebsiteDayRollups(since90dDay)
+
+ statuses := make([]models.WebsiteStatus, 0, len(websites))
+ for _, w := range websites {
+ daily := dailyBySite[w.ID]
+ u90 := uptime90dBySite[w.ID]
+ st := s.buildWebsiteStatusBulk(w, since24h, since7d, latestMap, hourMap, daily, u90)
+ if st != nil {
+ statuses = append(statuses, *st)
+ }
+ }
+ return statuses
+}
+
+func (s *MonitorService) buildWebsiteStatusBulk(
+ w models.Website,
+ since24h, since7d time.Time,
+ latestMap map[string]models.MonitorRecord,
+ hourMap map[string]map[string][]storage.MonitorProbeHour,
+ daily []models.DailyStats,
+ uptime90d float64,
+) *models.WebsiteStatus {
+ isIntranet := len(w.URLs) > 0 && utils.IsIntranetURL(w.URLs[0].URL)
+ status := &models.WebsiteStatus{
+ Website: w,
+ IsIntranet: isIntranet,
+ URLStatuses: []models.URLStatus{},
+ }
+
+ siteHours := hourMap[w.ID]
+ if siteHours == nil {
+ siteHours = map[string][]storage.MonitorProbeHour{}
+ }
+
+ var totalUptime24h, totalUptime7d float64
+ urlCount := 0
+ for _, urlInfo := range w.URLs {
+ key := w.ID + "\x00" + urlInfo.ID
+ var latest *models.MonitorRecord
+ if rec, ok := latestMap[key]; ok {
+ r := rec
+ latest = &r
+ }
+ hRows := siteHours[urlInfo.ID]
+ urlSt := s.buildURLStatusFromHours(w.ID, urlInfo, since24h, since7d, latest, hRows)
+ status.URLStatuses = append(status.URLStatuses, urlSt)
+ totalUptime24h += urlSt.Uptime24h
+ totalUptime7d += urlSt.Uptime7d
+ urlCount++
+ }
+ if urlCount > 0 {
+ status.Uptime24h = totalUptime24h / float64(urlCount)
+ status.Uptime7d = totalUptime7d / float64(urlCount)
+ }
+ if daily != nil {
+ status.DailyHistory = daily
+ } else {
+ status.DailyHistory = []models.DailyStats{}
+ }
+ status.Uptime90d = uptime90d
+ for _, urlSt := range status.URLStatuses {
+ if urlSt.CurrentState.CheckedAt.After(status.LastChecked) {
+ status.LastChecked = urlSt.CurrentState.CheckedAt
+ }
+ }
+ return status
+}
diff --git a/mengyaping-backend/services/website.go b/mengyaping-backend/services/website.go
index 4ae914d..55cefab 100644
--- a/mengyaping-backend/services/website.go
+++ b/mengyaping-backend/services/website.go
@@ -1,142 +1,177 @@
-package services
-
-import (
- "time"
-
- "mengyaping-backend/models"
- "mengyaping-backend/storage"
- "mengyaping-backend/utils"
-)
-
-// WebsiteService 网站服务
-type WebsiteService struct {
- storage *storage.Storage
-}
-
-// NewWebsiteService 创建网站服务
-func NewWebsiteService() *WebsiteService {
- return &WebsiteService{
- storage: storage.GetStorage(),
- }
-}
-
-// CreateWebsite 创建网站
-func (s *WebsiteService) CreateWebsite(req models.CreateWebsiteRequest) (*models.Website, error) {
- groups := req.Groups
- if len(groups) == 0 && req.Group != "" {
- groups = []string{req.Group}
- }
-
- website := models.Website{
- ID: utils.GenerateID(),
- Name: req.Name,
- Groups: groups,
- URLs: make([]models.URLInfo, 0),
- CreatedAt: time.Now(),
- UpdatedAt: time.Now(),
- }
-
- for _, url := range req.URLs {
- urlInfo := models.URLInfo{
- ID: utils.GenerateShortID(),
- URL: url,
- }
- website.URLs = append(website.URLs, urlInfo)
- }
-
- // 创建前先解析域名 IP
- if len(req.URLs) > 0 {
- if ips, err := utils.ResolveDomainIPs(req.URLs[0]); err == nil {
- website.IPAddresses = ips
- }
- }
-
- if err := s.storage.AddWebsite(website); err != nil {
- return nil, err
- }
-
- // 立即检测该网站
- go GetMonitorService().CheckWebsiteNow(website.ID)
-
- return &website, nil
-}
-
-// GetWebsite 获取网站
-func (s *WebsiteService) GetWebsite(id string) *models.Website {
- return s.storage.GetWebsite(id)
-}
-
-// GetAllWebsites 获取所有网站
-func (s *WebsiteService) GetAllWebsites() []models.Website {
- return s.storage.GetWebsites()
-}
-
-// UpdateWebsite 更新网站
-func (s *WebsiteService) UpdateWebsite(id string, req models.UpdateWebsiteRequest) (*models.Website, error) {
- website := s.storage.GetWebsite(id)
- if website == nil {
- return nil, nil
- }
-
- if req.Name != "" {
- website.Name = req.Name
- }
- if len(req.Groups) > 0 {
- website.Groups = req.Groups
- } else if req.Group != "" {
- website.Groups = []string{req.Group}
- }
- if len(req.URLs) > 0 {
- // 保留已有URL的ID,添加新URL
- existingURLs := make(map[string]models.URLInfo)
- for _, u := range website.URLs {
- existingURLs[u.URL] = u
- }
-
- newURLs := make([]models.URLInfo, 0)
- for _, url := range req.URLs {
- if existing, ok := existingURLs[url]; ok {
- newURLs = append(newURLs, existing)
- } else {
- newURLs = append(newURLs, models.URLInfo{
- ID: utils.GenerateShortID(),
- URL: url,
- })
- }
- }
- website.URLs = newURLs
- website.IPAddresses = nil // URL 变更后清空 IP,等下次检测重新解析
- }
-
- website.UpdatedAt = time.Now()
-
- if err := s.storage.UpdateWebsite(*website); err != nil {
- return nil, err
- }
-
- return website, nil
-}
-
-// DeleteWebsite 删除网站
-func (s *WebsiteService) DeleteWebsite(id string) error {
- return s.storage.DeleteWebsite(id)
-}
-
-// GetGroups 获取所有分组
-func (s *WebsiteService) GetGroups() []models.Group {
- return s.storage.GetGroups()
-}
-
-// AddGroup 添加分组
-func (s *WebsiteService) AddGroup(name string) (*models.Group, error) {
- group := models.Group{
- ID: utils.GenerateShortID(),
- Name: name,
- }
-
- if err := s.storage.AddGroup(group); err != nil {
- return nil, err
- }
-
- return &group, nil
-}
+package services
+
+import (
+ "fmt"
+ "strings"
+ "time"
+
+ "mengyaping-backend/models"
+ "mengyaping-backend/storage"
+ "mengyaping-backend/utils"
+)
+
+// WebsiteService 网站服务
+type WebsiteService struct {
+ storage *storage.Storage
+}
+
+// NewWebsiteService 创建网站服务
+func NewWebsiteService() *WebsiteService {
+ return &WebsiteService{
+ storage: storage.GetStorage(),
+ }
+}
+
+// CreateWebsite 创建网站
+func (s *WebsiteService) CreateWebsite(req models.CreateWebsiteRequest) (*models.Website, error) {
+ groups := req.Groups
+ if len(groups) == 0 && req.Group != "" {
+ groups = []string{req.Group}
+ }
+
+ website := models.Website{
+ ID: utils.GenerateID(),
+ Name: req.Name,
+ Groups: groups,
+ URLs: make([]models.URLInfo, 0),
+ CreatedAt: time.Now(),
+ UpdatedAt: time.Now(),
+ }
+
+ for _, url := range req.URLs {
+ urlInfo := models.URLInfo{
+ ID: utils.GenerateShortID(),
+ URL: url,
+ }
+ website.URLs = append(website.URLs, urlInfo)
+ }
+
+ if len(req.URLs) > 0 {
+ if utils.IsIntranetURL(req.URLs[0]) {
+ website.Favicon = models.DefaultIntranetFavicon
+ website.IPAddresses = nil
+ } else {
+ if ips, err := utils.ResolveDomainIPs(req.URLs[0]); err == nil {
+ website.IPAddresses = ips
+ }
+ }
+ }
+
+ if err := s.storage.AddWebsite(website); err != nil {
+ return nil, err
+ }
+
+ // 立即检测该网站
+ go GetMonitorService().CheckWebsiteNow(website.ID)
+
+ return &website, nil
+}
+
+// GetWebsite 获取网站
+func (s *WebsiteService) GetWebsite(id string) *models.Website {
+ return s.storage.GetWebsite(id)
+}
+
+// GetAllWebsites 获取所有网站
+func (s *WebsiteService) GetAllWebsites() []models.Website {
+ return s.storage.GetWebsites()
+}
+
+// UpdateWebsite 更新网站
+func (s *WebsiteService) UpdateWebsite(id string, req models.UpdateWebsiteRequest) (*models.Website, error) {
+ website := s.storage.GetWebsite(id)
+ if website == nil {
+ return nil, nil
+ }
+
+ if req.Name != "" {
+ website.Name = req.Name
+ }
+ if len(req.Groups) > 0 {
+ website.Groups = req.Groups
+ } else if req.Group != "" {
+ website.Groups = []string{req.Group}
+ }
+ if len(req.URLs) > 0 {
+ // 保留已有URL的ID,添加新URL
+ existingURLs := make(map[string]models.URLInfo)
+ for _, u := range website.URLs {
+ existingURLs[u.URL] = u
+ }
+
+ newURLs := make([]models.URLInfo, 0)
+ for _, url := range req.URLs {
+ if existing, ok := existingURLs[url]; ok {
+ newURLs = append(newURLs, existing)
+ } else {
+ newURLs = append(newURLs, models.URLInfo{
+ ID: utils.GenerateShortID(),
+ URL: url,
+ })
+ }
+ }
+ website.URLs = newURLs
+ website.IPAddresses = nil // URL 变更后清空 IP,等下次检测重新解析
+
+ if len(req.URLs) > 0 && utils.IsIntranetURL(req.URLs[0]) {
+ website.Favicon = models.DefaultIntranetFavicon
+ website.IPAddresses = nil
+ }
+ }
+
+ website.UpdatedAt = time.Now()
+
+ if err := s.storage.UpdateWebsite(*website); err != nil {
+ return nil, err
+ }
+
+ return website, nil
+}
+
+// DeleteWebsite 删除网站
+func (s *WebsiteService) DeleteWebsite(id string) error {
+ return s.storage.DeleteWebsite(id)
+}
+
+// GetGroups 获取所有分组
+func (s *WebsiteService) GetGroups() []models.Group {
+ return s.storage.GetGroups()
+}
+
+// AddGroup 添加分组
+func (s *WebsiteService) AddGroup(name string) (*models.Group, error) {
+ name = strings.TrimSpace(name)
+ if name == "" {
+ return nil, fmt.Errorf("分类名称不能为空")
+ }
+
+ group := models.Group{
+ ID: utils.GenerateShortID(),
+ Name: name,
+ }
+
+ if err := s.storage.AddGroup(group); err != nil {
+ return nil, err
+ }
+
+ return &group, nil
+}
+
+// GetGroup 获取单个分组
+func (s *WebsiteService) GetGroup(id string) *models.Group {
+ return s.storage.GetGroupByID(id)
+}
+
+// UpdateGroup 更新分类名称
+func (s *WebsiteService) UpdateGroup(id string, name string) (*models.Group, error) {
+ if err := s.storage.UpdateGroup(id, name); err != nil {
+ return nil, err
+ }
+ g := s.storage.GetGroupByID(id)
+ return g, nil
+}
+
+// DeleteGroup 删除分类
+func (s *WebsiteService) DeleteGroup(id string) error {
+ return s.storage.DeleteGroup(id)
+}
diff --git a/mengyaping-backend/storage/app_config.go b/mengyaping-backend/storage/app_config.go
new file mode 100644
index 0000000..cba8398
--- /dev/null
+++ b/mengyaping-backend/storage/app_config.go
@@ -0,0 +1,161 @@
+package storage
+
+import (
+ "encoding/json"
+ "fmt"
+ "log"
+ "time"
+
+ "mengyaping-backend/config"
+)
+
+const (
+ kvKeyServer = "cfg_server"
+ kvKeyMonitor = "cfg_monitor"
+ kvKeyDataPath = "cfg_data_path"
+ kvKeyDatabase = "cfg_database"
+)
+
+type monitorKVPayload struct {
+ IntervalMinutes int `json:"interval_minutes"`
+ TimeoutSeconds int `json:"timeout_seconds"`
+ RetryCount int `json:"retry_count"`
+ HistoryDays int `json:"history_days"`
+}
+
+func (s *Storage) getKVRaw(key string) string {
+ var row MonitorKV
+ s.db.Where("cfg_key = ?", key).Limit(1).Find(&row)
+ if row.CfgKey == "" {
+ return ""
+ }
+ return row.CfgValue
+}
+
+func (s *Storage) setKVRaw(key, val string) error {
+ var row MonitorKV
+ s.db.Where("cfg_key = ?", key).Limit(1).Find(&row)
+ if row.CfgKey == "" {
+ return s.db.Create(&MonitorKV{CfgKey: key, CfgValue: val}).Error
+ }
+ row.CfgValue = val
+ return s.db.Save(&row).Error
+}
+
+// loadAndSyncAppConfig 从 monitor_kv 覆盖内存配置,再写回全量(补全缺省键、统一格式)
+func (s *Storage) loadAndSyncAppConfig() {
+ cfg := config.GetConfig()
+
+ if v := s.getKVRaw(kvKeyServer); v != "" {
+ var sc config.ServerConfig
+ if err := json.Unmarshal([]byte(v), &sc); err != nil {
+ log.Printf("解析 %s: %v", kvKeyServer, err)
+ } else {
+ if sc.Port != "" {
+ cfg.Server.Port = sc.Port
+ }
+ if sc.Host != "" {
+ cfg.Server.Host = sc.Host
+ }
+ }
+ }
+
+ if v := s.getKVRaw(kvKeyMonitor); v != "" {
+ var m monitorKVPayload
+ if err := json.Unmarshal([]byte(v), &m); err != nil {
+ log.Printf("解析 %s: %v", kvKeyMonitor, err)
+ } else {
+ if m.IntervalMinutes > 0 {
+ snapped := config.SnapMonitorIntervalMinutes(m.IntervalMinutes)
+ cfg.Monitor.Interval = time.Duration(snapped) * time.Minute
+ }
+ if m.TimeoutSeconds > 0 {
+ cfg.Monitor.Timeout = time.Duration(m.TimeoutSeconds) * time.Second
+ }
+ if m.RetryCount > 0 {
+ cfg.Monitor.RetryCount = m.RetryCount
+ }
+ if m.HistoryDays > 0 {
+ cfg.Monitor.HistoryDays = m.HistoryDays
+ }
+ }
+ }
+
+ if v := s.getKVRaw(kvKeyDataPath); v != "" {
+ cfg.DataPath = v
+ }
+
+ if v := s.getKVRaw(kvKeyDatabase); v != "" {
+ var dc config.DatabaseConfig
+ if err := json.Unmarshal([]byte(v), &dc); err != nil {
+ log.Printf("解析 %s: %v", kvKeyDatabase, err)
+ } else {
+ if dc.Host != "" {
+ cfg.Database.Host = dc.Host
+ }
+ if dc.Port != "" {
+ cfg.Database.Port = dc.Port
+ }
+ if dc.User != "" {
+ cfg.Database.User = dc.User
+ }
+ if dc.Password != "" {
+ cfg.Database.Password = dc.Password
+ }
+ if dc.Database != "" {
+ cfg.Database.Database = dc.Database
+ }
+ }
+ }
+
+ if err := s.PersistAppConfig(); err != nil {
+ log.Printf("同步应用配置到 monitor_kv: %v", err)
+ }
+}
+
+// PersistAppConfig 将当前内存中的 server/monitor/data_path/database 写入 monitor_kv
+func (s *Storage) PersistAppConfig() error {
+ cfg := config.GetConfig()
+
+ b, err := json.Marshal(cfg.Server)
+ if err != nil {
+ return err
+ }
+ if err := s.setKVRaw(kvKeyServer, string(b)); err != nil {
+ return err
+ }
+
+ m := monitorKVPayload{
+ IntervalMinutes: config.SnapMonitorIntervalMinutes(int(cfg.Monitor.Interval / time.Minute)),
+ TimeoutSeconds: int(cfg.Monitor.Timeout.Seconds()),
+ RetryCount: cfg.Monitor.RetryCount,
+ HistoryDays: cfg.Monitor.HistoryDays,
+ }
+ b, err = json.Marshal(m)
+ if err != nil {
+ return err
+ }
+ if err := s.setKVRaw(kvKeyMonitor, string(b)); err != nil {
+ return err
+ }
+
+ if err := s.setKVRaw(kvKeyDataPath, cfg.DataPath); err != nil {
+ return err
+ }
+
+ b, err = json.Marshal(cfg.Database)
+ if err != nil {
+ return err
+ }
+ return s.setKVRaw(kvKeyDatabase, string(b))
+}
+
+// SetMonitorIntervalMinutes 更新检测周期并写入 monitor_kv
+func (s *Storage) SetMonitorIntervalMinutes(minutes int) error {
+ if !config.IsAllowedMonitorInterval(minutes) {
+ return fmt.Errorf("interval_minutes 必须是预设值之一: %v", config.AllowedMonitorIntervalMinutes)
+ }
+ cfg := config.GetConfig()
+ cfg.Monitor.Interval = time.Duration(minutes) * time.Minute
+ return s.PersistAppConfig()
+}
diff --git a/mengyaping-backend/storage/db_kv.go b/mengyaping-backend/storage/db_kv.go
new file mode 100644
index 0000000..c737575
--- /dev/null
+++ b/mengyaping-backend/storage/db_kv.go
@@ -0,0 +1,14 @@
+package storage
+
+import "time"
+
+// MonitorKV 键值配置(管理员令牌等),列名避开 MySQL 保留字 key/value
+type MonitorKV struct {
+ CfgKey string `gorm:"primaryKey;size:128;column:cfg_key"`
+ CfgValue string `gorm:"type:text;column:cfg_value"`
+ UpdatedAt time.Time `gorm:"autoUpdateTime"`
+}
+
+func (MonitorKV) TableName() string { return "monitor_kv" }
+
+const kvKeyAdminToken = "admin_token"
diff --git a/mengyaping-backend/storage/db_models.go b/mengyaping-backend/storage/db_models.go
new file mode 100644
index 0000000..1e19400
--- /dev/null
+++ b/mengyaping-backend/storage/db_models.go
@@ -0,0 +1,93 @@
+package storage
+
+import (
+ "time"
+
+ "gorm.io/datatypes"
+)
+
+// MonitorGroup 网站分类(避免使用 MySQL 保留字 group)
+type MonitorGroup struct {
+ ID string `gorm:"primaryKey;size:64"`
+ Name string `gorm:"size:255;not null"`
+ SortOrder int `gorm:"default:0;index"`
+ CreatedAt time.Time `gorm:"autoCreateTime"`
+ UpdatedAt time.Time `gorm:"autoUpdateTime"`
+}
+
+func (MonitorGroup) TableName() string { return "monitor_groups" }
+
+// MonitorWebsite 监控站点主表
+type MonitorWebsite struct {
+ ID string `gorm:"primaryKey;size:128"`
+ Name string `gorm:"size:255;not null;index"`
+ LegacyGroup string `gorm:"size:64;column:legacy_group"` // 旧版单分组,仅兼容
+ Favicon string `gorm:"type:text"`
+ Title string `gorm:"size:512"`
+ IPAddresses datatypes.JSON `gorm:"type:json"` // []string
+ CreatedAt time.Time `gorm:"autoCreateTime"`
+ UpdatedAt time.Time `gorm:"autoUpdateTime"`
+
+ URLs []MonitorWebsiteURL `gorm:"foreignKey:WebsiteID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
+ GroupLinks []MonitorWebsiteGroup `gorm:"foreignKey:WebsiteID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
+}
+
+func (MonitorWebsite) TableName() string { return "monitor_websites" }
+
+// MonitorWebsiteURL 站点监控 URL(一对多)
+type MonitorWebsiteURL struct {
+ ID uint64 `gorm:"primaryKey;autoIncrement"`
+ WebsiteID string `gorm:"size:128;not null;index:idx_url_site,priority:1"`
+ URLID string `gorm:"size:64;not null;index:idx_url_site,priority:2"`
+ URL string `gorm:"type:text;not null"`
+ Remark string `gorm:"size:512"`
+ SortOrder int `gorm:"default:0"`
+}
+
+func (MonitorWebsiteURL) TableName() string { return "monitor_website_urls" }
+
+// MonitorWebsiteGroup 站点与分类多对多
+type MonitorWebsiteGroup struct {
+ WebsiteID string `gorm:"primaryKey;size:128"`
+ GroupID string `gorm:"primaryKey;size:64"`
+}
+
+func (MonitorWebsiteGroup) TableName() string { return "monitor_website_groups" }
+
+// MonitorProbeLatest 每个 URL 最新一次探测结果(不逐条存历史)
+type MonitorProbeLatest struct {
+ WebsiteID string `gorm:"primaryKey;size:128"`
+ URLID string `gorm:"primaryKey;size:64"`
+ URL string `gorm:"type:text"`
+ StatusCode int `gorm:"column:status_code"`
+ LatencyMs int64 `gorm:"column:latency_ms"`
+ IsUp bool `gorm:"column:is_up"`
+ ErrorText string `gorm:"type:text;column:error_text"`
+ CheckedAt time.Time `gorm:"index"`
+}
+
+func (MonitorProbeLatest) TableName() string { return "monitor_probe_latest" }
+
+// MonitorProbeHour 按小时汇总(用于 24h / 7d 统计与图表),行数 ≈ URL 数 × 小时数
+type MonitorProbeHour struct {
+ WebsiteID string `gorm:"primaryKey;size:128"`
+ URLID string `gorm:"primaryKey;size:64"`
+ HourAt time.Time `gorm:"primaryKey;type:datetime"` // 整点
+ ProbeCount int `gorm:"default:0"`
+ UpCount int `gorm:"default:0"`
+ LatencySum int64 `gorm:"default:0"` // 总延迟 ms,均值为 sum/count
+}
+
+func (MonitorProbeHour) TableName() string { return "monitor_probe_hour" }
+
+// MonitorProbeDay 按自然日汇总(用于 90 天柱状图),行数 ≈ URL 数 × 天数
+type MonitorProbeDay struct {
+ WebsiteID string `gorm:"primaryKey;size:128"`
+ URLID string `gorm:"primaryKey;size:64"`
+ StatDate time.Time `gorm:"primaryKey;type:date"`
+ ProbeCount int `gorm:"default:0"`
+ UpCount int `gorm:"default:0"`
+ LatencySum int64 `gorm:"default:0"`
+}
+
+func (MonitorProbeDay) TableName() string { return "monitor_probe_day" }
diff --git a/mengyaping-backend/storage/kv.go b/mengyaping-backend/storage/kv.go
new file mode 100644
index 0000000..76c52aa
--- /dev/null
+++ b/mengyaping-backend/storage/kv.go
@@ -0,0 +1,62 @@
+package storage
+
+import (
+ "errors"
+ "log"
+ "os"
+ "strings"
+)
+
+var errEmptyAdminToken = errors.New("admin_token 不能为空")
+
+// EffectiveAdminToken 管理员令牌:环境变量 ADMIN_TOKEN 优先,否则读 MySQL monitor_kv
+func (s *Storage) EffectiveAdminToken() string {
+ if v := strings.TrimSpace(os.Getenv("ADMIN_TOKEN")); v != "" {
+ return v
+ }
+ return strings.TrimSpace(s.adminTokenFromDB())
+}
+
+func (s *Storage) adminTokenFromDB() string {
+ var row MonitorKV
+ if err := s.db.Where("cfg_key = ?", kvKeyAdminToken).Limit(1).Find(&row).Error; err != nil {
+ return ""
+ }
+ if row.CfgKey == "" {
+ return ""
+ }
+ return row.CfgValue
+}
+
+// SetAdminToken 更新数据库中的管理员令牌(需已能通过 AdminAuth)
+func (s *Storage) SetAdminToken(token string) error {
+ token = strings.TrimSpace(token)
+ if token == "" {
+ return errEmptyAdminToken
+ }
+ var row MonitorKV
+ s.db.Where("cfg_key = ?", kvKeyAdminToken).Limit(1).Find(&row)
+ if row.CfgKey == "" {
+ return s.db.Create(&MonitorKV{CfgKey: kvKeyAdminToken, CfgValue: token}).Error
+ }
+ row.CfgValue = token
+ return s.db.Save(&row).Error
+}
+
+func (s *Storage) seedAdminTokenKV() {
+ var n int64
+ s.db.Model(&MonitorKV{}).Where("cfg_key = ?", kvKeyAdminToken).Count(&n)
+ if n > 0 {
+ return
+ }
+ val := strings.TrimSpace(os.Getenv("ADMIN_TOKEN"))
+ if val == "" {
+ log.Println("提示: 数据库 monitor_kv 中尚无 admin_token。可设置环境变量 ADMIN_TOKEN 后重启以自动写入,或对 monitor_kv 执行 INSERT。")
+ return
+ }
+ if err := s.db.Create(&MonitorKV{CfgKey: kvKeyAdminToken, CfgValue: val}).Error; err != nil {
+ log.Printf("写入初始 admin_token 失败: %v", err)
+ return
+ }
+ log.Println("已从环境变量 ADMIN_TOKEN 写入数据库 monitor_kv(后续可去掉该环境变量,改用库中令牌)。")
+}
diff --git a/mengyaping-backend/storage/probe.go b/mengyaping-backend/storage/probe.go
new file mode 100644
index 0000000..f6a2867
--- /dev/null
+++ b/mengyaping-backend/storage/probe.go
@@ -0,0 +1,295 @@
+package storage
+
+import (
+ "log"
+ "time"
+
+ "gorm.io/gorm"
+
+ "mengyaping-backend/config"
+ "mengyaping-backend/models"
+)
+
+func latestToRecord(p *MonitorProbeLatest) models.MonitorRecord {
+ return models.MonitorRecord{
+ WebsiteID: p.WebsiteID,
+ URLID: p.URLID,
+ URL: p.URL,
+ StatusCode: p.StatusCode,
+ Latency: p.LatencyMs,
+ IsUp: p.IsUp,
+ Error: p.ErrorText,
+ CheckedAt: p.CheckedAt,
+ }
+}
+
+// AddRecord 写入最新探测 + 按小时/按天汇总(不插逐条历史)
+func (s *Storage) AddRecord(record models.MonitorRecord) error {
+ hourAt := record.CheckedAt.Truncate(time.Hour)
+ statDate := time.Date(record.CheckedAt.Year(), record.CheckedAt.Month(), record.CheckedAt.Day(),
+ 0, 0, 0, 0, record.CheckedAt.Location())
+ upDelta := 0
+ if record.IsUp {
+ upDelta = 1
+ }
+
+ return s.db.Transaction(func(tx *gorm.DB) error {
+ lp := MonitorProbeLatest{
+ WebsiteID: record.WebsiteID,
+ URLID: record.URLID,
+ URL: record.URL,
+ StatusCode: record.StatusCode,
+ LatencyMs: record.Latency,
+ IsUp: record.IsUp,
+ ErrorText: record.Error,
+ CheckedAt: record.CheckedAt,
+ }
+ if err := tx.Save(&lp).Error; err != nil {
+ return err
+ }
+ if err := tx.Exec(`
+INSERT INTO monitor_probe_hour (website_id, url_id, hour_at, probe_count, up_count, latency_sum)
+VALUES (?, ?, ?, 1, ?, ?)
+ON DUPLICATE KEY UPDATE
+ probe_count = probe_count + 1,
+ up_count = up_count + VALUES(up_count),
+ latency_sum = latency_sum + VALUES(latency_sum)
+`, record.WebsiteID, record.URLID, hourAt, upDelta, record.Latency).Error; err != nil {
+ return err
+ }
+ return tx.Exec(`
+INSERT INTO monitor_probe_day (website_id, url_id, stat_date, probe_count, up_count, latency_sum)
+VALUES (?, ?, ?, 1, ?, ?)
+ON DUPLICATE KEY UPDATE
+ probe_count = probe_count + 1,
+ up_count = up_count + VALUES(up_count),
+ latency_sum = latency_sum + VALUES(latency_sum)
+`, record.WebsiteID, record.URLID, statDate.Format("2006-01-02"), upDelta, record.Latency).Error
+ })
+}
+
+// GetLatestRecord 最新一条(无记录时返回 nil;用 Find 而非 First,避免 GORM 将「未找到」打成 record not found 日志)
+func (s *Storage) GetLatestRecord(websiteID, urlID string) *models.MonitorRecord {
+ var p MonitorProbeLatest
+ if err := s.db.Where("website_id = ? AND url_id = ?", websiteID, urlID).Limit(1).Find(&p).Error; err != nil {
+ return nil
+ }
+ if p.WebsiteID == "" {
+ return nil
+ }
+ m := latestToRecord(&p)
+ return &m
+}
+
+// GetRecords 兼容旧接口:按小时聚合展开为「代表点」(每探测窗口 1 条),仅用于仍依赖 slice 的逻辑;新逻辑请用汇总 API
+func (s *Storage) GetRecords(websiteID, urlID string, since time.Time) []models.MonitorRecord {
+ rows := s.getProbeHourRows(websiteID, urlID, since)
+ var out []models.MonitorRecord
+ for _, h := range rows {
+ if h.ProbeCount <= 0 {
+ continue
+ }
+ avgLat := h.LatencySum / int64(h.ProbeCount)
+ isUp := h.UpCount*2 >= h.ProbeCount
+ out = append(out, models.MonitorRecord{
+ WebsiteID: websiteID,
+ URLID: urlID,
+ StatusCode: 0,
+ Latency: avgLat,
+ IsUp: isUp,
+ CheckedAt: h.HourAt,
+ })
+ }
+ return out
+}
+
+func (s *Storage) getProbeHourRows(websiteID, urlID string, since time.Time) []MonitorProbeHour {
+ var rows []MonitorProbeHour
+ s.db.Where("website_id = ? AND url_id = ? AND hour_at >= ?", websiteID, urlID, since).
+ Order("hour_at ASC").Find(&rows)
+ return rows
+}
+
+// GetProbeHourRowsForURL 某 URL 自 since 起的小时汇总行(升序)
+func (s *Storage) GetProbeHourRowsForURL(websiteID, urlID string, since time.Time) []MonitorProbeHour {
+ return s.getProbeHourRows(websiteID, urlID, since)
+}
+
+// GetProbeLatestKeyMap 全表 latest(每 URL 一行),key = website_id + "\x00" + url_id
+func (s *Storage) GetProbeLatestKeyMap() map[string]models.MonitorRecord {
+ var rows []MonitorProbeLatest
+ if err := s.db.Find(&rows).Error; err != nil {
+ log.Printf("GetProbeLatestKeyMap: %v", err)
+ return map[string]models.MonitorRecord{}
+ }
+ m := make(map[string]models.MonitorRecord, len(rows))
+ for i := range rows {
+ k := rows[i].WebsiteID + "\x00" + rows[i].URLID
+ m[k] = latestToRecord(&rows[i])
+ }
+ return m
+}
+
+// GroupProbeHoursSince 近窗口内全部小时汇总,按站点、URL 分组(列表接口一次查出)
+func (s *Storage) GroupProbeHoursSince(since time.Time) map[string]map[string][]MonitorProbeHour {
+ var rows []MonitorProbeHour
+ if err := s.db.Where("hour_at >= ?", since).Order("website_id, url_id, hour_at").Find(&rows).Error; err != nil {
+ log.Printf("GroupProbeHoursSince: %v", err)
+ return map[string]map[string][]MonitorProbeHour{}
+ }
+ out := make(map[string]map[string][]MonitorProbeHour)
+ for i := range rows {
+ h := rows[i]
+ if out[h.WebsiteID] == nil {
+ out[h.WebsiteID] = make(map[string][]MonitorProbeHour)
+ }
+ out[h.WebsiteID][h.URLID] = append(out[h.WebsiteID][h.URLID], h)
+ }
+ return out
+}
+
+// LoadAllWebsiteDayRollups 自 since 日起各站每日汇总 + 90d 整体可用率(单条 SQL 聚合)
+func (s *Storage) LoadAllWebsiteDayRollups(since time.Time) (map[string][]models.DailyStats, map[string]float64) {
+ sinceDay := time.Date(since.Year(), since.Month(), since.Day(), 0, 0, 0, 0, since.Location())
+ sinceStr := sinceDay.Format("2006-01-02")
+ type aggRow struct {
+ Wid string `gorm:"column:wid"`
+ D time.Time `gorm:"column:d"`
+ Pc int64 `gorm:"column:pc"`
+ Uc int64 `gorm:"column:uc"`
+ Ls int64 `gorm:"column:ls"`
+ }
+ var agg []aggRow
+ if err := s.db.Raw(`
+SELECT website_id AS wid, stat_date AS d, SUM(probe_count) AS pc, SUM(up_count) AS uc, SUM(latency_sum) AS ls
+FROM monitor_probe_day
+WHERE stat_date >= ?
+GROUP BY website_id, stat_date
+ORDER BY website_id, stat_date
+`, sinceStr).Scan(&agg).Error; err != nil {
+ log.Printf("LoadAllWebsiteDayRollups: %v", err)
+ return map[string][]models.DailyStats{}, map[string]float64{}
+ }
+
+ daily := make(map[string][]models.DailyStats)
+ totP := make(map[string]int64)
+ totU := make(map[string]int64)
+ for _, r := range agg {
+ st := models.DailyStats{
+ Date: r.D,
+ TotalCount: int(r.Pc),
+ UpCount: int(r.Uc),
+ }
+ if r.Pc > 0 {
+ st.AvgLatency = r.Ls / r.Pc
+ st.Uptime = float64(r.Uc) / float64(r.Pc) * 100
+ }
+ daily[r.Wid] = append(daily[r.Wid], st)
+ totP[r.Wid] += r.Pc
+ totU[r.Wid] += r.Uc
+ }
+ uptime := make(map[string]float64)
+ for wid, p := range totP {
+ if p > 0 {
+ uptime[wid] = float64(totU[wid]) / float64(p) * 100
+ }
+ }
+ return daily, uptime
+}
+
+// GetProbeHourTotals 某 URL 在时间窗口内汇总(来自小时表)
+func (s *Storage) GetProbeHourTotals(websiteID, urlID string, since time.Time) (probeTotal int64, upTotal int64, latencySum int64) {
+ type row struct {
+ P int64
+ U int64
+ L int64
+ }
+ var r row
+ s.db.Model(&MonitorProbeHour{}).
+ Select("COALESCE(SUM(probe_count),0), COALESCE(SUM(up_count),0), COALESCE(SUM(latency_sum),0)").
+ Where("website_id = ? AND url_id = ? AND hour_at >= ?", websiteID, urlID, since).
+ Scan(&r)
+ return r.P, r.U, r.L
+}
+
+// GetHourlyStatsForURL 7 天折线用(已聚合)
+func (s *Storage) GetHourlyStatsForURL(websiteID, urlID string, since time.Time) []models.HourlyStats {
+ rows := s.getProbeHourRows(websiteID, urlID, since)
+ out := make([]models.HourlyStats, 0, len(rows))
+ for _, h := range rows {
+ st := models.HourlyStats{
+ Hour: h.HourAt,
+ TotalCount: h.ProbeCount,
+ UpCount: h.UpCount,
+ }
+ if h.ProbeCount > 0 {
+ st.AvgLatency = h.LatencySum / int64(h.ProbeCount)
+ st.Uptime = float64(h.UpCount) / float64(h.ProbeCount) * 100
+ }
+ out = append(out, st)
+ }
+ return out
+}
+
+// GetWebsiteDailyAggregates 站点维度按日合并(多 URL 汇总到同一天)
+func (s *Storage) GetWebsiteDailyAggregates(websiteID string, since time.Time) []models.DailyStats {
+ type aggRow struct {
+ D time.Time `gorm:"column:d"`
+ Pc int64 `gorm:"column:pc"`
+ Uc int64 `gorm:"column:uc"`
+ Ls int64 `gorm:"column:ls"`
+ }
+ var rows []aggRow
+ sinceDay := time.Date(since.Year(), since.Month(), since.Day(), 0, 0, 0, 0, since.Location())
+ s.db.Raw(`
+SELECT stat_date AS d, SUM(probe_count) AS pc, SUM(up_count) AS uc, SUM(latency_sum) AS ls
+FROM monitor_probe_day
+WHERE website_id = ? AND stat_date >= ?
+GROUP BY stat_date
+ORDER BY stat_date ASC
+`, websiteID, sinceDay.Format("2006-01-02")).Scan(&rows)
+
+ out := make([]models.DailyStats, 0, len(rows))
+ for _, r := range rows {
+ st := models.DailyStats{
+ Date: r.D,
+ TotalCount: int(r.Pc),
+ UpCount: int(r.Uc),
+ }
+ if r.Pc > 0 {
+ st.AvgLatency = r.Ls / r.Pc
+ st.Uptime = float64(r.Uc) / float64(r.Pc) * 100
+ }
+ out = append(out, st)
+ }
+ return out
+}
+
+// GetWebsiteDayProbeTotals 整站在日期范围内探测次数汇总(用于 90 天可用率)
+func (s *Storage) GetWebsiteDayProbeTotals(websiteID string, since time.Time) (probeTotal int64, upTotal int64) {
+ sinceDay := time.Date(since.Year(), since.Month(), since.Day(), 0, 0, 0, 0, since.Location())
+ type row struct {
+ P int64
+ U int64
+ }
+ var r row
+ s.db.Model(&MonitorProbeDay{}).
+ Select("COALESCE(SUM(probe_count),0), COALESCE(SUM(up_count),0)").
+ Where("website_id = ? AND stat_date >= ?", websiteID, sinceDay.Format("2006-01-02")).
+ Scan(&r)
+ return r.P, r.U
+}
+
+func (s *Storage) purgeProbeRollups() {
+ cfg := config.GetConfig()
+ now := time.Now()
+ dayCutoff := now.AddDate(0, 0, -cfg.Monitor.HistoryDays).Truncate(24 * time.Hour)
+ if err := s.db.Where("stat_date < ?", dayCutoff.Format("2006-01-02")).Delete(&MonitorProbeDay{}).Error; err != nil {
+ log.Printf("清理 monitor_probe_day: %v", err)
+ }
+ // 小时图保留约 10 天(覆盖 7 天曲线 + 余量)
+ hourCutoff := now.Add(-10 * 24 * time.Hour).Truncate(time.Hour)
+ if err := s.db.Where("hour_at < ?", hourCutoff).Delete(&MonitorProbeHour{}).Error; err != nil {
+ log.Printf("清理 monitor_probe_hour: %v", err)
+ }
+}
diff --git a/mengyaping-backend/storage/storage.go b/mengyaping-backend/storage/storage.go
index d4737ac..dd4acf7 100644
--- a/mengyaping-backend/storage/storage.go
+++ b/mengyaping-backend/storage/storage.go
@@ -1,302 +1,365 @@
-package storage
-
-import (
- "encoding/json"
- "os"
- "path/filepath"
- "sync"
- "time"
-
- "mengyaping-backend/config"
- "mengyaping-backend/models"
-)
-
-// Storage 数据存储
-type Storage struct {
- dataPath string
- mu sync.RWMutex
- websites []models.Website
- records map[string][]models.MonitorRecord // key: websiteID_urlID
- groups []models.Group
-}
-
-var (
- store *Storage
- once sync.Once
-)
-
-// GetStorage 获取存储单例
-func GetStorage() *Storage {
- once.Do(func() {
- cfg := config.GetConfig()
- store = &Storage{
- dataPath: cfg.DataPath,
- websites: []models.Website{},
- records: make(map[string][]models.MonitorRecord),
- groups: models.DefaultGroups,
- }
- store.ensureDataDir()
- store.load()
- })
- return store
-}
-
-// ensureDataDir 确保数据目录存在
-func (s *Storage) ensureDataDir() {
- os.MkdirAll(s.dataPath, 0755)
-}
-
-// load 加载数据
-func (s *Storage) load() {
- s.loadWebsites()
- s.loadRecords()
- s.loadGroups()
-}
-
-// loadWebsites 加载网站数据
-func (s *Storage) loadWebsites() {
- filePath := filepath.Join(s.dataPath, "websites.json")
- data, err := os.ReadFile(filePath)
- if err != nil {
- return
- }
- json.Unmarshal(data, &s.websites)
- s.migrateWebsiteGroups()
-}
-
-// migrateWebsiteGroups 将旧的单分组字段迁移到多分组数组
-func (s *Storage) migrateWebsiteGroups() {
- migrated := false
- for i := range s.websites {
- w := &s.websites[i]
- if len(w.Groups) == 0 && w.Group != "" {
- w.Groups = []string{w.Group}
- w.Group = ""
- migrated = true
- }
- }
- if migrated {
- s.saveWebsites()
- }
-}
-
-// loadRecords 加载监控记录
-func (s *Storage) loadRecords() {
- filePath := filepath.Join(s.dataPath, "records.json")
- data, err := os.ReadFile(filePath)
- if err != nil {
- return
- }
- json.Unmarshal(data, &s.records)
-
- // 清理过期记录
- s.cleanOldRecords()
-}
-
-// loadGroups 加载分组
-func (s *Storage) loadGroups() {
- filePath := filepath.Join(s.dataPath, "groups.json")
- data, err := os.ReadFile(filePath)
- if err != nil {
- // 使用默认分组
- s.groups = models.DefaultGroups
- s.saveGroups()
- return
- }
- json.Unmarshal(data, &s.groups)
-}
-
-// saveWebsites 保存网站数据
-func (s *Storage) saveWebsites() error {
- filePath := filepath.Join(s.dataPath, "websites.json")
- data, err := json.MarshalIndent(s.websites, "", " ")
- if err != nil {
- return err
- }
- return os.WriteFile(filePath, data, 0644)
-}
-
-// saveRecords 保存监控记录
-func (s *Storage) saveRecords() error {
- filePath := filepath.Join(s.dataPath, "records.json")
- data, err := json.MarshalIndent(s.records, "", " ")
- if err != nil {
- return err
- }
- return os.WriteFile(filePath, data, 0644)
-}
-
-// saveGroups 保存分组
-func (s *Storage) saveGroups() error {
- filePath := filepath.Join(s.dataPath, "groups.json")
- data, err := json.MarshalIndent(s.groups, "", " ")
- if err != nil {
- return err
- }
- return os.WriteFile(filePath, data, 0644)
-}
-
-// cleanOldRecords 清理过期记录
-func (s *Storage) cleanOldRecords() {
- cfg := config.GetConfig()
- cutoff := time.Now().AddDate(0, 0, -cfg.Monitor.HistoryDays)
-
- for key, records := range s.records {
- var newRecords []models.MonitorRecord
- for _, r := range records {
- if r.CheckedAt.After(cutoff) {
- newRecords = append(newRecords, r)
- }
- }
- s.records[key] = newRecords
- }
-}
-
-// GetWebsites 获取所有网站
-func (s *Storage) GetWebsites() []models.Website {
- s.mu.RLock()
- defer s.mu.RUnlock()
-
- result := make([]models.Website, len(s.websites))
- copy(result, s.websites)
- return result
-}
-
-// GetWebsite 获取单个网站
-func (s *Storage) GetWebsite(id string) *models.Website {
- s.mu.RLock()
- defer s.mu.RUnlock()
-
- for _, w := range s.websites {
- if w.ID == id {
- website := w
- return &website
- }
- }
- return nil
-}
-
-// AddWebsite 添加网站
-func (s *Storage) AddWebsite(website models.Website) error {
- s.mu.Lock()
- defer s.mu.Unlock()
-
- s.websites = append(s.websites, website)
- return s.saveWebsites()
-}
-
-// UpdateWebsite 更新网站
-func (s *Storage) UpdateWebsite(website models.Website) error {
- s.mu.Lock()
- defer s.mu.Unlock()
-
- for i, w := range s.websites {
- if w.ID == website.ID {
- s.websites[i] = website
- return s.saveWebsites()
- }
- }
- return nil
-}
-
-// DeleteWebsite 删除网站
-func (s *Storage) DeleteWebsite(id string) error {
- s.mu.Lock()
- defer s.mu.Unlock()
-
- for i, w := range s.websites {
- if w.ID == id {
- s.websites = append(s.websites[:i], s.websites[i+1:]...)
- // 删除相关记录
- for key := range s.records {
- if len(key) > len(id) && key[:len(id)] == id {
- delete(s.records, key)
- }
- }
- s.saveRecords()
- return s.saveWebsites()
- }
- }
- return nil
-}
-
-// AddRecord 添加监控记录
-func (s *Storage) AddRecord(record models.MonitorRecord) error {
- s.mu.Lock()
- defer s.mu.Unlock()
-
- key := record.WebsiteID + "_" + record.URLID
- s.records[key] = append(s.records[key], record)
-
- // 每100条记录保存一次
- if len(s.records[key])%100 == 0 {
- return s.saveRecords()
- }
- return nil
-}
-
-// GetRecords 获取监控记录
-func (s *Storage) GetRecords(websiteID, urlID string, since time.Time) []models.MonitorRecord {
- s.mu.RLock()
- defer s.mu.RUnlock()
-
- key := websiteID + "_" + urlID
- records := s.records[key]
-
- var result []models.MonitorRecord
- for _, r := range records {
- if r.CheckedAt.After(since) {
- result = append(result, r)
- }
- }
- return result
-}
-
-// GetLatestRecord 获取最新记录
-func (s *Storage) GetLatestRecord(websiteID, urlID string) *models.MonitorRecord {
- s.mu.RLock()
- defer s.mu.RUnlock()
-
- key := websiteID + "_" + urlID
- records := s.records[key]
-
- if len(records) == 0 {
- return nil
- }
-
- latest := records[len(records)-1]
- return &latest
-}
-
-// GetGroups 获取所有分组
-func (s *Storage) GetGroups() []models.Group {
- s.mu.RLock()
- defer s.mu.RUnlock()
-
- result := make([]models.Group, len(s.groups))
- copy(result, s.groups)
- return result
-}
-
-// AddGroup 添加分组
-func (s *Storage) AddGroup(group models.Group) error {
- s.mu.Lock()
- defer s.mu.Unlock()
-
- s.groups = append(s.groups, group)
- return s.saveGroups()
-}
-
-// SaveAll 保存所有数据
-func (s *Storage) SaveAll() error {
- s.mu.Lock()
- defer s.mu.Unlock()
-
- if err := s.saveWebsites(); err != nil {
- return err
- }
- if err := s.saveRecords(); err != nil {
- return err
- }
- return s.saveGroups()
-}
+package storage
+
+import (
+ "encoding/json"
+ "fmt"
+ "log"
+ "os"
+ "strings"
+ "sync"
+ "time"
+
+ "gorm.io/datatypes"
+ "gorm.io/driver/mysql"
+ "gorm.io/gorm"
+ "gorm.io/gorm/logger"
+
+ "mengyaping-backend/config"
+ "mengyaping-backend/models"
+)
+
+// Storage 基于 MySQL 的持久化(站点 / 分类 / 检测记录)
+type Storage struct {
+ db *gorm.DB
+}
+
+var (
+ store *Storage
+ once sync.Once
+)
+
+// GetStorage 初始化数据库连接并迁移表结构
+func GetStorage() *Storage {
+ once.Do(func() {
+ cfg := config.GetConfig()
+ dsn := cfg.DatabaseDSN()
+
+ gormLog := logger.Default.LogMode(logger.Warn)
+ if os.Getenv("DB_DEBUG") == "1" {
+ gormLog = logger.Default.LogMode(logger.Info)
+ }
+
+ db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
+ Logger: gormLog,
+ })
+ if err != nil {
+ log.Fatalf("MySQL 连接失败: %v(请检查 DB_* / DB_DSN 环境变量)", err)
+ }
+ sqlDB, err := db.DB()
+ if err != nil {
+ log.Fatalf("MySQL sqlDB: %v", err)
+ }
+ sqlDB.SetMaxIdleConns(8)
+ sqlDB.SetMaxOpenConns(40)
+ sqlDB.SetConnMaxLifetime(time.Hour)
+
+ store = &Storage{db: db}
+ if err := store.migrate(); err != nil {
+ log.Fatalf("数据库迁移失败: %v", err)
+ }
+ store.seedAdminTokenKV()
+ store.loadAndSyncAppConfig()
+ store.seedDefaultGroups()
+ log.Println("MySQL 存储已就绪: " + cfg.Database.Database + "@" + cfg.Database.Host)
+ })
+ return store
+}
+
+func (s *Storage) migrate() error {
+ err := s.db.AutoMigrate(
+ &MonitorGroup{},
+ &MonitorWebsite{},
+ &MonitorWebsiteURL{},
+ &MonitorWebsiteGroup{},
+ &MonitorProbeLatest{},
+ &MonitorProbeHour{},
+ &MonitorProbeDay{},
+ &MonitorKV{},
+ )
+ if err != nil {
+ return err
+ }
+ // 旧版逐条 monitor_checks 表体积极大,已弃用
+ if s.db.Migrator().HasTable("monitor_checks") {
+ if err := s.db.Migrator().DropTable("monitor_checks"); err != nil {
+ log.Printf("删除旧表 monitor_checks: %v(可手工 DROP)", err)
+ } else {
+ log.Println("已删除旧表 monitor_checks")
+ }
+ }
+ return nil
+}
+
+func (s *Storage) seedDefaultGroups() {
+ var n int64
+ s.db.Model(&MonitorGroup{}).Count(&n)
+ if n > 0 {
+ return
+ }
+ order := 0
+ for _, g := range models.DefaultGroups {
+ order++
+ s.db.Create(&MonitorGroup{
+ ID: g.ID,
+ Name: g.Name,
+ SortOrder: order,
+ })
+ }
+ log.Println("已写入默认分类 monitor_groups")
+}
+
+func ipsToJSON(ips []string) []byte {
+ if ips == nil {
+ ips = []string{}
+ }
+ b, err := json.Marshal(ips)
+ if err != nil {
+ return []byte("[]")
+ }
+ return b
+}
+
+func jsonToIPs(raw []byte) []string {
+ if len(raw) == 0 {
+ return nil
+ }
+ var ips []string
+ if err := json.Unmarshal(raw, &ips); err != nil {
+ return nil
+ }
+ return ips
+}
+
+func rowToWebsite(w *MonitorWebsite) models.Website {
+ groups := make([]string, 0, len(w.GroupLinks))
+ for _, l := range w.GroupLinks {
+ groups = append(groups, l.GroupID)
+ }
+ if len(groups) == 0 && w.LegacyGroup != "" {
+ groups = []string{w.LegacyGroup}
+ }
+ urls := make([]models.URLInfo, 0, len(w.URLs))
+ for _, u := range w.URLs {
+ urls = append(urls, models.URLInfo{
+ ID: u.URLID,
+ URL: u.URL,
+ Remark: u.Remark,
+ })
+ }
+ return models.Website{
+ ID: w.ID,
+ Name: w.Name,
+ Groups: groups,
+ Group: "",
+ URLs: urls,
+ IPAddresses: jsonToIPs(w.IPAddresses),
+ Favicon: w.Favicon,
+ Title: w.Title,
+ CreatedAt: w.CreatedAt,
+ UpdatedAt: w.UpdatedAt,
+ }
+}
+
+func websiteToRow(w *models.Website) *MonitorWebsite {
+ return &MonitorWebsite{
+ ID: w.ID,
+ Name: w.Name,
+ LegacyGroup: "",
+ Favicon: w.Favicon,
+ Title: w.Title,
+ IPAddresses: datatypes.JSON(ipsToJSON(w.IPAddresses)),
+ CreatedAt: w.CreatedAt,
+ UpdatedAt: w.UpdatedAt,
+ }
+}
+
+func (s *Storage) listWebsiteModels() ([]models.Website, error) {
+ var rows []MonitorWebsite
+ if err := s.db.Preload("URLs", func(db *gorm.DB) *gorm.DB {
+ return db.Order("sort_order ASC, id ASC")
+ }).Preload("GroupLinks").Order("created_at ASC").Find(&rows).Error; err != nil {
+ return nil, err
+ }
+ out := make([]models.Website, len(rows))
+ for i := range rows {
+ out[i] = rowToWebsite(&rows[i])
+ }
+ return out, nil
+}
+
+// GetWebsites 获取所有网站
+func (s *Storage) GetWebsites() []models.Website {
+ list, err := s.listWebsiteModels()
+ if err != nil {
+ log.Printf("GetWebsites: %v", err)
+ return nil
+ }
+ return list
+}
+
+// GetWebsite 获取单个网站
+func (s *Storage) GetWebsite(id string) *models.Website {
+ var w MonitorWebsite
+ if err := s.db.Preload("URLs", func(db *gorm.DB) *gorm.DB {
+ return db.Order("sort_order ASC, id ASC")
+ }).Preload("GroupLinks").First(&w, "id = ?", id).Error; err != nil {
+ return nil
+ }
+ m := rowToWebsite(&w)
+ return &m
+}
+
+func (s *Storage) persistWebsiteFull(w models.Website) error {
+ return s.db.Transaction(func(tx *gorm.DB) error {
+ row := websiteToRow(&w)
+ if err := tx.Save(row).Error; err != nil {
+ return err
+ }
+ if err := tx.Where("website_id = ?", w.ID).Delete(&MonitorWebsiteURL{}).Error; err != nil {
+ return err
+ }
+ if err := tx.Where("website_id = ?", w.ID).Delete(&MonitorWebsiteGroup{}).Error; err != nil {
+ return err
+ }
+ for i, u := range w.URLs {
+ if err := tx.Create(&MonitorWebsiteURL{
+ WebsiteID: w.ID,
+ URLID: u.ID,
+ URL: u.URL,
+ Remark: u.Remark,
+ SortOrder: i,
+ }).Error; err != nil {
+ return err
+ }
+ }
+ for _, gid := range w.Groups {
+ if err := tx.Create(&MonitorWebsiteGroup{WebsiteID: w.ID, GroupID: gid}).Error; err != nil {
+ return err
+ }
+ }
+ return nil
+ })
+}
+
+// AddWebsite 添加网站
+func (s *Storage) AddWebsite(website models.Website) error {
+ return s.persistWebsiteFull(website)
+}
+
+// UpdateWebsite 更新网站
+func (s *Storage) UpdateWebsite(website models.Website) error {
+ return s.persistWebsiteFull(website)
+}
+
+// DeleteWebsite 删除网站
+func (s *Storage) DeleteWebsite(id string) error {
+ return s.db.Transaction(func(tx *gorm.DB) error {
+ _ = tx.Where("website_id = ?", id).Delete(&MonitorProbeLatest{})
+ _ = tx.Where("website_id = ?", id).Delete(&MonitorProbeHour{})
+ _ = tx.Where("website_id = ?", id).Delete(&MonitorProbeDay{})
+ _ = tx.Where("website_id = ?", id).Delete(&MonitorWebsiteURL{})
+ _ = tx.Where("website_id = ?", id).Delete(&MonitorWebsiteGroup{})
+ return tx.Where("id = ?", id).Delete(&MonitorWebsite{}).Error
+ })
+}
+
+// GetGroups 获取所有分组
+func (s *Storage) GetGroups() []models.Group {
+ var rows []MonitorGroup
+ s.db.Order("sort_order ASC, id ASC").Find(&rows)
+ out := make([]models.Group, len(rows))
+ for i, r := range rows {
+ out[i] = models.Group{ID: r.ID, Name: r.Name}
+ }
+ return out
+}
+
+// AddGroup 添加分组
+func (s *Storage) AddGroup(group models.Group) error {
+ var n int64
+ s.db.Model(&MonitorGroup{}).Count(&n)
+ return s.db.Create(&MonitorGroup{
+ ID: group.ID,
+ Name: group.Name,
+ SortOrder: int(n) + 1,
+ }).Error
+}
+
+// GetGroupByID 按 ID 获取分组(无则 nil)
+func (s *Storage) GetGroupByID(id string) *models.Group {
+ var r MonitorGroup
+ if err := s.db.First(&r, "id = ?", id).Error; err != nil {
+ return nil
+ }
+ g := models.Group{ID: r.ID, Name: r.Name}
+ return &g
+}
+
+// UpdateGroup 更新分组显示名称(ID 不变)
+func (s *Storage) UpdateGroup(id, name string) error {
+ name = strings.TrimSpace(name)
+ if name == "" {
+ return fmt.Errorf("分类名称不能为空")
+ }
+ res := s.db.Model(&MonitorGroup{}).Where("id = ?", id).Update("name", name)
+ if res.Error != nil {
+ return res.Error
+ }
+ if res.RowsAffected == 0 {
+ return fmt.Errorf("分类不存在")
+ }
+ return nil
+}
+
+// DeleteGroup 删除分组;从所有网站中移除该分类;若网站无剩余分类则归入删除后列表中的第一个分类。至少保留一个分类。
+func (s *Storage) DeleteGroup(id string) error {
+ var total int64
+ s.db.Model(&MonitorGroup{}).Count(&total)
+ if total <= 1 {
+ return fmt.Errorf("至少保留一个分类")
+ }
+
+ var remain []MonitorGroup
+ s.db.Where("id != ?", id).Order("sort_order ASC, id ASC").Find(&remain)
+ if len(remain) == 0 {
+ return fmt.Errorf("至少保留一个分类")
+ }
+ fallbackID := remain[0].ID
+
+ var sites []MonitorWebsite
+ if err := s.db.Preload("GroupLinks").Find(&sites).Error; err != nil {
+ return err
+ }
+
+ return s.db.Transaction(func(tx *gorm.DB) error {
+ for i := range sites {
+ next := make([]string, 0)
+ for _, l := range sites[i].GroupLinks {
+ if l.GroupID != id {
+ next = append(next, l.GroupID)
+ }
+ }
+ if len(next) == 0 {
+ next = []string{fallbackID}
+ }
+ if err := tx.Where("website_id = ?", sites[i].ID).Delete(&MonitorWebsiteGroup{}).Error; err != nil {
+ return err
+ }
+ for _, gid := range next {
+ if err := tx.Create(&MonitorWebsiteGroup{WebsiteID: sites[i].ID, GroupID: gid}).Error; err != nil {
+ return err
+ }
+ }
+ }
+ if err := tx.Delete(&MonitorGroup{}, "id = ?", id).Error; err != nil {
+ return err
+ }
+ return nil
+ })
+}
+
+// SaveAll 周期结束时清理过期汇总分区(日表按 history_days,小时表保留约 10 天)
+func (s *Storage) SaveAll() error {
+ s.purgeProbeRollups()
+ return nil
+}
diff --git a/mengyaping-backend/utils/intranet.go b/mengyaping-backend/utils/intranet.go
new file mode 100644
index 0000000..2fcc6b2
--- /dev/null
+++ b/mengyaping-backend/utils/intranet.go
@@ -0,0 +1,37 @@
+package utils
+
+import (
+ "net"
+ "net/url"
+)
+
+// IsIntranetURL 判断监控地址的主机是否为内网 / 本机 IP(直填 IP 的虚拟局域网站点)。
+// 仅识别主机名为 IPv4/IPv6 字面量的情况;公网域名不在此列。
+func IsIntranetURL(raw string) bool {
+ u, err := url.Parse(raw)
+ if err != nil {
+ return false
+ }
+ host := u.Hostname()
+ if host == "" {
+ return false
+ }
+ ip := net.ParseIP(host)
+ if ip == nil {
+ return false
+ }
+ return isIntranetIP(ip)
+}
+
+func isIntranetIP(ip net.IP) bool {
+ if ip.IsLoopback() || ip.IsPrivate() || ip.IsLinkLocalUnicast() {
+ return true
+ }
+ // Go 1.17+ IsPrivate 已含 RFC1918、CGNAT 100.64/10、ULA 等;再兜底部分实现差异
+ if v4 := ip.To4(); v4 != nil {
+ if v4[0] == 100 && v4[1] >= 64 && v4[1] <= 127 {
+ return true
+ }
+ }
+ return false
+}
diff --git a/mengyaping-backend/utils/intranet_test.go b/mengyaping-backend/utils/intranet_test.go
new file mode 100644
index 0000000..3259192
--- /dev/null
+++ b/mengyaping-backend/utils/intranet_test.go
@@ -0,0 +1,24 @@
+package utils
+
+import "testing"
+
+func TestIsIntranetURL(t *testing.T) {
+ cases := []struct {
+ raw string
+ want bool
+ }{
+ {"http://10.0.0.233:8080/path", true},
+ {"https://192.168.1.1/", true},
+ {"http://127.0.0.1:3000", true},
+ {"http://[fd00::1]/", true},
+ {"https://1.1.1.1/", false},
+ {"https://example.com/", false},
+ {"http://nas.local:8080", false},
+ }
+ for _, tc := range cases {
+ got := IsIntranetURL(tc.raw)
+ if got != tc.want {
+ t.Fatalf("%q: got %v want %v", tc.raw, got, tc.want)
+ }
+ }
+}
diff --git a/mengyaping-frontend/package-lock.json b/mengyaping-frontend/package-lock.json
index a3edba7..531d6b3 100644
--- a/mengyaping-frontend/package-lock.json
+++ b/mengyaping-frontend/package-lock.json
@@ -10,7 +10,8 @@
"dependencies": {
"@tailwindcss/vite": "^4.1.18",
"react": "^19.2.0",
- "react-dom": "^19.2.0"
+ "react-dom": "^19.2.0",
+ "react-router-dom": "^7.14.0"
},
"devDependencies": {
"@eslint/js": "^9.39.1",
@@ -58,7 +59,6 @@
"integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@babel/code-frame": "^7.28.6",
"@babel/generator": "^7.28.6",
@@ -1633,7 +1633,6 @@
"integrity": "sha512-Lpo8kgb/igvMIPeNV2rsYKTgaORYdO1XGVZ4Qz3akwOj0ySGYMPlQWa8BaLn0G63D1aSaAQ5ldR06wCpChQCjA==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"csstype": "^3.2.2"
}
@@ -1675,7 +1674,6 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
- "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -1818,7 +1816,6 @@
}
],
"license": "MIT",
- "peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.9.0",
"caniuse-lite": "^1.0.30001759",
@@ -1915,6 +1912,19 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/cookie": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz",
+ "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -2061,7 +2071,6 @@
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -3030,7 +3039,6 @@
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=12"
},
@@ -3057,7 +3065,6 @@
}
],
"license": "MIT",
- "peer": true,
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
@@ -3099,7 +3106,6 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz",
"integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==",
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -3126,6 +3132,44 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-router": {
+ "version": "7.14.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.14.0.tgz",
+ "integrity": "sha512-m/xR9N4LQLmAS0ZhkY2nkPA1N7gQ5TUVa5n8TgANuDTARbn1gt+zLPXEm7W0XDTbrQ2AJSJKhoa6yx1D8BcpxQ==",
+ "license": "MIT",
+ "dependencies": {
+ "cookie": "^1.0.1",
+ "set-cookie-parser": "^2.6.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-router-dom": {
+ "version": "7.14.0",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.14.0.tgz",
+ "integrity": "sha512-2G3ajSVSZMEtmTjIklRWlNvo8wICEpLihfD/0YMDxbWK2UyP5EGfnoIn9AIQGnF3G/FX0MRbHXdFcD+rL1ZreQ==",
+ "license": "MIT",
+ "dependencies": {
+ "react-router": "7.14.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=18",
+ "react-dom": ">=18"
+ }
+ },
"node_modules/resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
@@ -3196,6 +3240,12 @@
"semver": "bin/semver.js"
}
},
+ "node_modules/set-cookie-parser": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz",
+ "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
+ "license": "MIT"
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -3348,7 +3398,6 @@
"resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz",
"integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
"license": "MIT",
- "peer": true,
"dependencies": {
"esbuild": "^0.27.0",
"fdir": "^6.5.0",
@@ -3470,7 +3519,6 @@
"integrity": "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==",
"dev": true,
"license": "MIT",
- "peer": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
diff --git a/mengyaping-frontend/package.json b/mengyaping-frontend/package.json
index a10477c..8852d80 100644
--- a/mengyaping-frontend/package.json
+++ b/mengyaping-frontend/package.json
@@ -14,7 +14,8 @@
"dependencies": {
"@tailwindcss/vite": "^4.1.18",
"react": "^19.2.0",
- "react-dom": "^19.2.0"
+ "react-dom": "^19.2.0",
+ "react-router-dom": "^7.14.0"
},
"devDependencies": {
"@eslint/js": "^9.39.1",
diff --git a/mengyaping-frontend/src/App.jsx b/mengyaping-frontend/src/App.jsx
index 9a8cf16..157ab0e 100644
--- a/mengyaping-frontend/src/App.jsx
+++ b/mengyaping-frontend/src/App.jsx
@@ -1,7 +1,18 @@
-import Dashboard from './pages/Dashboard'
+import { Routes, Route, Navigate } from 'react-router-dom'
+import RandomBackdrop from './components/RandomBackdrop'
+import PublicDashboard from './pages/PublicDashboard'
+import AdminPanel from './pages/AdminPanel'
function App() {
- return
+ 增删改分类后,列表与筛选会同步更新;删除分类时,原归属站点会合并到剩余的第一个分类。
+ 加载中… {err}网站分类
+
+ {(groups || []).map((g) => (
+
+ )}
+
+ {err ? {g.id}
+
+ 所有站点共用同一轮询间隔,保存后立即调整后台定时器(仍会先跑完上一轮逻辑)。 +
+加载中…
+ ) : ( + + )} + {err ?{err}
: null} +
+ 请输入与服务端 ADMIN_TOKEN 一致的口令
++ + ← 返回公开页 + +
+网站监控面板
+ {monitorSettings?.interval_minutes ? ( ++ 检测周期:每 {monitorSettings.interval_minutes} 分钟 +
+ ) : null}{searchTerm ? '没有找到匹配的网站' : '还没有添加任何监控网站'}
- {!searchTerm && ( + {!searchTerm && !readOnly && ( )} + {!searchTerm && readOnly && ( +站点由管理员在「管理后台」维护
+ )}请输入与服务端配置一致的管理员令牌
+ +