权限管理,apk包下载

This commit is contained in:
hahwu 2026-05-07 14:39:24 +08:00
parent 9468ec5873
commit 1bca99d539
15 changed files with 1432 additions and 849 deletions

View File

@ -42,6 +42,42 @@ func AdminAdd(c *gin.Context) {
success(c, result)
}
func AdminEdit(c *gin.Context) {
var admin model.Admin
if err := c.ShouldBindJSON(&admin); err != nil {
failed(c, "Invalid input: "+err.Error())
return
}
if admin.ID == 0 {
failed(c, "id is required")
return
}
if err := admin.Edit(); err != nil {
failed(c, "Failed to edit admin: "+err.Error())
return
}
util.AddAdminLog(c, "编辑管理员", admin)
success(c, "success")
}
func AdminDelete(c *gin.Context) {
type param struct {
ID int `json:"id"`
}
var p param
if err := c.ShouldBindJSON(&p); err != nil {
failed(c, "Invalid input: "+err.Error())
return
}
admin := model.Admin{ID: p.ID}
if err := admin.Delete(); err != nil {
failed(c, "Failed to delete admin: "+err.Error())
return
}
util.AddAdminLog(c, "删除管理员", p)
success(c, "success")
}
func AdminLogList(c *gin.Context) {
// 处理管理员日志列表请求
type param struct {

229
controller/apk.go Normal file
View File

@ -0,0 +1,229 @@
package controller
import (
"encoding/json"
"fmt"
"log"
"os"
"path/filepath"
"strings"
"time"
"backend/util"
"github.com/gin-gonic/gin"
)
const (
apkStorageRoot = "./runtime/apk"
apkManifestName = "manifest.json"
defaultApkUploadToken = "apk-upload-token"
apkUploadTokenHeader = "X-Apk-Upload-Token"
apkUploadTokenEnvName = "APK_UPLOAD_TOKEN"
uploadedAtTimeFormat = time.RFC3339
defaultApkStorageName = "current.apk"
)
var apkEnvironments = []string{"dev", "stable", "prod"}
type apkPackageMeta struct {
DownloadPath string `json:"downloadPath"`
Env string `json:"env"`
Exists bool `json:"exists"`
FileName string `json:"fileName"`
Size int64 `json:"size"`
UploadedAt string `json:"uploadedAt"`
Version string `json:"version"`
}
type apkManifest struct {
Packages map[string]apkPackageMeta `json:"packages"`
}
func UploadApkPackage(c *gin.Context) {
if !validateApkUploadToken(c.GetHeader(apkUploadTokenHeader)) {
failed(c, "上传令牌无效")
return
}
env := strings.TrimSpace(c.PostForm("env"))
if !isValidApkEnv(env) {
failed(c, "无效的 apk 环境,必须是 dev、stable 或 prod")
return
}
fileHeader, err := c.FormFile("file")
if err != nil {
failed(c, "获取 apk 文件失败: "+err.Error())
return
}
if strings.ToLower(filepath.Ext(fileHeader.Filename)) != ".apk" {
failed(c, "仅支持上传 .apk 文件")
return
}
if err := os.MkdirAll(apkEnvDir(env), 0755); err != nil {
failed(c, "创建 apk 目录失败: "+err.Error())
return
}
targetPath := apkFilePath(env)
if err := c.SaveUploadedFile(fileHeader, targetPath); err != nil {
failed(c, "保存 apk 文件失败: "+err.Error())
return
}
version := strings.TrimSpace(c.PostForm("version"))
if version == "" {
version = strings.TrimSuffix(fileHeader.Filename, filepath.Ext(fileHeader.Filename))
}
meta := apkPackageMeta{
DownloadPath: apkDownloadPath(env),
Env: env,
Exists: true,
FileName: fileHeader.Filename,
Size: fileHeader.Size,
UploadedAt: time.Now().Format(uploadedAtTimeFormat),
Version: version,
}
manifest, err := loadApkManifest()
if err != nil {
failed(c, "读取 apk 清单失败: "+err.Error())
return
}
manifest.Packages[env] = meta
if err := saveApkManifest(manifest); err != nil {
failed(c, "保存 apk 清单失败: "+err.Error())
return
}
log.Printf("apk uploaded env=%s file=%s size=%d", env, fileHeader.Filename, fileHeader.Size)
success(c, meta)
}
func GetApkPackages(c *gin.Context) {
manifest, err := loadApkManifest()
if err != nil {
failed(c, "读取 apk 清单失败: "+err.Error())
return
}
packages := make([]apkPackageMeta, 0, len(apkEnvironments))
for _, env := range apkEnvironments {
meta := manifest.Packages[env]
if meta.Env == "" {
meta = apkPackageMeta{Env: env}
}
meta.Exists = fileExists(apkFilePath(env))
meta.DownloadPath = apkDownloadPath(env)
packages = append(packages, meta)
}
success(c, packages)
}
func DownloadApkPackage(c *gin.Context) {
env := c.Param("env")
if !isValidApkEnv(env) {
failed(c, "无效的 apk 环境")
return
}
manifest, err := loadApkManifest()
if err != nil {
failed(c, "读取 apk 清单失败: "+err.Error())
return
}
targetPath := apkFilePath(env)
if !fileExists(targetPath) {
failed(c, fmt.Sprintf("%s 环境暂无可下载的 apk 包", env))
return
}
meta := manifest.Packages[env]
downloadName := meta.FileName
if strings.TrimSpace(downloadName) == "" {
downloadName = fmt.Sprintf("%s.apk", env)
}
util.AddAdminLog(c, "下载客户端APK", gin.H{"env": env, "file": downloadName})
c.FileAttachment(targetPath, downloadName)
}
func validateApkUploadToken(token string) bool {
expectedToken := strings.TrimSpace(os.Getenv(apkUploadTokenEnvName))
if expectedToken == "" {
expectedToken = defaultApkUploadToken
}
return strings.TrimSpace(token) != "" && token == expectedToken
}
func apkEnvDir(env string) string {
return filepath.Join(apkStorageRoot, env)
}
func apkFilePath(env string) string {
return filepath.Join(apkEnvDir(env), defaultApkStorageName)
}
func apkManifestPath() string {
return filepath.Join(apkStorageRoot, apkManifestName)
}
func apkDownloadPath(env string) string {
return fmt.Sprintf("/api/apk/download/%s", env)
}
func isValidApkEnv(env string) bool {
for _, item := range apkEnvironments {
if item == env {
return true
}
}
return false
}
func loadApkManifest() (*apkManifest, error) {
manifest := &apkManifest{Packages: map[string]apkPackageMeta{}}
if err := os.MkdirAll(apkStorageRoot, 0755); err != nil {
return nil, err
}
data, err := os.ReadFile(apkManifestPath())
if err != nil {
if os.IsNotExist(err) {
return manifest, nil
}
return nil, err
}
if len(data) == 0 {
return manifest, nil
}
if err := json.Unmarshal(data, manifest); err != nil {
return nil, err
}
if manifest.Packages == nil {
manifest.Packages = map[string]apkPackageMeta{}
}
return manifest, nil
}
func saveApkManifest(manifest *apkManifest) error {
data, err := json.MarshalIndent(manifest, "", " ")
if err != nil {
return err
}
return os.WriteFile(apkManifestPath(), data, 0644)
}
func fileExists(path string) bool {
info, err := os.Stat(path)
return err == nil && !info.IsDir()
}

View File

@ -47,6 +47,10 @@ type userAdminIDRequest struct {
AdminID int `json:"admin_id" binding:"required"`
}
type userAdminIDsRequest struct {
AdminIDs []int `json:"admin_ids" binding:"required"`
}
func PermissionUserGroupList(c *gin.Context) {
var req model.PermissionUserGroupListParams
if err := c.ShouldBindJSON(&req); err != nil {
@ -364,3 +368,17 @@ func PermissionUserRoleList(c *gin.Context) {
}
success(c, roles)
}
func PermissionUserRoleBatchList(c *gin.Context) {
var req userAdminIDsRequest
if err := c.ShouldBindJSON(&req); err != nil {
failed(c, "Invalid input: "+err.Error())
return
}
roles, err := model.ListUserRolesByAdminIDs(req.AdminIDs)
if err != nil {
failed(c, "Failed to list user roles: "+err.Error())
return
}
success(c, roles)
}

View File

@ -5,27 +5,81 @@ import (
"backend/store"
"backend/util"
"fmt"
"log"
"slices"
"github.com/gin-gonic/gin"
)
func UserInfo(c *gin.Context) {
Token := util.GetToken(c)
Info, _ := store.GetTokenInfo(Token)
info, _ := store.GetTokenInfo(Token)
if info == nil {
c.JSON(401, gin.H{"code": 401, "message": "Unauthorized"})
return
}
homePath := "/dashboard"
if Info.Role == "wb_transfer" {
// 从 DB 查询用户 ID 及是否 super
db := util.MPool.GetGameDB()
if db == nil {
c.JSON(500, gin.H{"code": 500, "message": "db unavailable"})
return
}
var adminRow struct {
ID int `db:"id"`
Role int `db:"role"`
}
if err := db.Get(&adminRow, "SELECT id, role FROM admin WHERE username = ?", info.UserName); err != nil {
db.Close()
log.Printf("UserInfo: query admin failed: %v", err)
c.JSON(500, gin.H{"code": 500, "message": "query failed"})
return
}
db.Close()
isSuperAdmin := util.GetRole(adminRow.Role) == util.RoleSuper
// 更新最后登录 IP 和时间
clientIP := c.ClientIP()
now := int(util.Now())
db2 := util.MPool.GetGameDB()
if db2 != nil {
db2.Exec("UPDATE admin SET lastLoginIp=?, lastLoginTime=? WHERE id=?", clientIP, now, adminRow.ID)
db2.Close()
}
effectiveInfo, err := model.GetUserEffectiveInfo(adminRow.ID, isSuperAdmin)
if err != nil {
log.Printf("UserInfo: GetUserEffectiveInfo failed: %v", err)
// 降级:只返回 token 里的静态角色
effectiveInfo = &model.UserEffectiveInfo{
Roles: []string{info.Role},
Permissions: []string{},
}
}
// super 在 roles 中补充标记,供前端路由守卫识别
roles := effectiveInfo.Roles
if isSuperAdmin || slices.Contains(roles, "R_SUPER") {
roles = []string{util.RoleSuper}
}
if len(roles) == 1 && slices.Contains(roles, "R_LANGUAGE") {
homePath = "/language"
}
c.JSON(200, gin.H{
"code": 0,
"data": map[string]interface{}{
"id": 0,
"realName": Info.UserName,
"roles": []string{Info.Role},
"username": Info.UserName,
"homePath": homePath,
"userId": fmt.Sprintf("%d", adminRow.ID),
"username": info.UserName,
"realName": info.UserName,
"avatar": "",
"homePath": homePath,
"roles": roles,
"permissions": effectiveInfo.Permissions,
},
"message": "Hello, world!",
"message": "ok",
})
}

View File

@ -168,20 +168,112 @@ ON DUPLICATE KEY UPDATE
INSERT INTO `admin_permission` (`permission_code`, `permission_name`, `permission_group`, `api_path`, `http_method`, `status`, `remark`, `create_admin`, `update_admin`, `createTime`, `updateTime`)
VALUES
('AC0001', '管理员列表查询', 'admin', '/api/admin/list', 'POST', 1, '查看管理员列表', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC0002', '管理员新增', 'admin', '/api/admin/add', 'POST', 1, '新增后台管理员', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC0003', '客户端通知查询', 'notification', '/api/client/notification', 'GET', 1, '查看客户端 notification 配置', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC0004', '客户端通知修改', 'notification', '/api/client/notification', 'PUT', 1, '单点权限标签示例AC0004', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC0005', '活动编辑', 'activity', '/api/activity/edit', 'POST', 1, '编辑活动配置', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP())
-- ── 管理员管理 ──────────────────────────────────────────────
('AC1001', '管理员列表', 'admin', '/api/admin/list', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1002', '管理员新增', 'admin', '/api/admin/add', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1003', '管理员操作日志', 'admin', '/api/admin/log/list', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1004', '管理员配置列表', 'admin', '/api/admin/config/list', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1005', '管理员配置新增', 'admin', '/api/admin/config/add', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1006', '管理员配置编辑', 'admin', '/api/admin/config/edit', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
-- ── 权限管理 ────────────────────────────────────────────────
('AC1101', '用户组列表', 'permission', '/api/admin/usergroup/list', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1102', '用户组新增', 'permission', '/api/admin/usergroup/add', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1103', '用户组编辑', 'permission', '/api/admin/usergroup/edit', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1104', '用户组删除', 'permission', '/api/admin/usergroup/delete', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1105', '用户组绑定角色', 'permission', '/api/admin/usergroup/role/set', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1106', '用户组角色查询', 'permission', '/api/admin/usergroup/role/list', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1107', '角色列表', 'permission', '/api/admin/role/list', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1108', '角色新增', 'permission', '/api/admin/role/add', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1109', '角色编辑', 'permission', '/api/admin/role/edit', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1110', '角色删除', 'permission', '/api/admin/role/delete', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1111', '角色绑定权限', 'permission', '/api/admin/role/permission/set', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1112', '角色权限查询', 'permission', '/api/admin/role/permission/list', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1113', '单点权限列表', 'permission', '/api/admin/permission/list', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1114', '单点权限新增', 'permission', '/api/admin/permission/add', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1115', '单点权限编辑', 'permission', '/api/admin/permission/edit', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1116', '单点权限删除', 'permission', '/api/admin/permission/delete', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1117', '用户组分配查询', 'permission', '/api/admin/user/group/list', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1118', '用户组分配设置', 'permission', '/api/admin/user/group/set', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1119', '用户单点权限查询', 'permission', '/api/admin/user/permission/list', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1120', '用户单点权限设置', 'permission', '/api/admin/user/permission/set', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC1121', '用户角色查询', 'permission', '/api/admin/user/role/list', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
-- ── 玩家日志 ────────────────────────────────────────────────
('AC2001', '玩家日志查询', 'log', '/api/log/user', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC2002', '资产日志查询', 'log', '/api/log/asset', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC2003', '事件日志查询', 'log', '/api/log/event', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC2004', '月登录次数统计', 'log', '/api/log/loginCountByMonth', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC2005', '订单日志查询', 'log', '/api/log/order', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
-- ── 玩家数据 ────────────────────────────────────────────────
('AC3001', '玩家列表', 'user', '/api/user/list', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC3002', '当前用户信息', 'user', '/api/user/info', 'GET', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC3003', 'GM操作', 'user', '/api/user/gm', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC3004', '封禁玩家', 'user', '/api/user/ban', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
-- ── 服务器管理 ──────────────────────────────────────────────
('AC4001', '应用列表', 'server', '/api/server/list', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC4002', '服务器列表', 'server', '/api/server/serverList', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC4003', '新增服务器', 'server', '/api/server/addServer', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC4004', '节点列表', 'server', '/api/server/nodeList', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC4005', '新增节点', 'server', '/api/server/addNode', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC4006', '编辑服务器', 'server', '/api/server/editServer', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC4007', '更新应用', 'server', '/api/server/updateApp', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC4008', '更新应用(审核)', 'server', '/api/server/updateAppReview', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC4009', '更新应用(飞书)', 'server', '/api/server/updateAppFeishu', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC4010', '重启服务器', 'server', '/api/server/restart', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC4011', '重载服务器', 'server', '/api/server/reload', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
-- ── 统计 ────────────────────────────────────────────────────
('AC5001', '等级统计', 'statistics', '/api/statistics/level', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC5002', '订单统计', 'statistics', '/api/statistics/order', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC5003', '基础统计信息', 'statistics', '/api/statistics/info', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC5004', '热力图统计', 'statistics', '/api/statistics/heat', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
-- ── 活动管理 ────────────────────────────────────────────────
('AC6001', '活动列表', 'activity', '/api/activity/list', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC6002', '活动编辑', 'activity', '/api/activity/edit', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC6003', '活动新增', 'activity', '/api/activity/add', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC6004', '活动删除', 'activity', '/api/activity/delete', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC6005', '活动同步', 'activity', '/api/activity/sync', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
-- ── 邮件 ────────────────────────────────────────────────────
('AC7001', '发送邮件', 'mail', '/api/mail/send', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC7002', '邮件列表', 'mail', '/api/mail/list', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC7003', '删除邮件', 'mail', '/api/mail/delete', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
-- ── 运营功能 ────────────────────────────────────────────────
('AC8001', '复制用户数据', 'operation', '/api/operation/copyUser', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
-- ── 翻译管理 ────────────────────────────────────────────────
('AC9001', '语言列表', 'language', '/api/language/list', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC9002', '语言导出', 'language', '/api/language/export', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC9003', '语言保存', 'language', '/api/language/save', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC9004', '语言新增', 'language', '/api/language/add', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC9005', '语言删除', 'language', '/api/language/delete', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
-- ── 通知配置 ────────────────────────────────────────────────
('AC9101', '通知配置查询', 'notification', '/api/config/notification', 'GET', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC9102', '通知配置更新', 'notification', '/api/config/notification/update', 'PUT', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
-- ── AB 实验 ─────────────────────────────────────────────────
('AC9201', '实验列表', 'experiment', '/api/v1/experiments', 'GET', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC9202', '实验新增', 'experiment', '/api/v1/experiments', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC9203', '实验更新', 'experiment', '/api/v1/experiments/:id', 'PUT', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC9204', '实验删除', 'experiment', '/api/v1/experiments/:id', 'DELETE', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC9205', '实验变体列表', 'experiment', '/api/v1/experiments/:id/variants', 'GET', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC9206', '实验变体新增', 'experiment', '/api/v1/experiments/:id/variants', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC9207', '实验变体更新', 'experiment', '/api/v1/experiments/:id/variants/:variantId', 'PUT', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC9208', '实验变体删除', 'experiment', '/api/v1/experiments/:id/variants/:variantId', 'DELETE', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC9209', '实验白名单列表', 'experiment', '/api/v1/experiments/:id/whitelist', 'GET', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC9210', '实验白名单新增', 'experiment', '/api/v1/experiments/:id/whitelist', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC9211', '实验白名单批量新增', 'experiment', '/api/v1/experiments/:id/whitelist/batch', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC9212', '实验白名单删除', 'experiment', '/api/v1/experiments/:id/whitelist/:userId', 'DELETE', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC9213', '实验结果查询', 'experiment', '/api/v1/experiments/:id/results', 'GET', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC9214', '用户实验分组查询', 'experiment', '/api/v1/users/:userId/groups', 'GET', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
-- ── 自动化脚本 ──────────────────────────────────────────────
('AC9301', '下载文案文件', 'scripts', '/api/scripts/copywriting', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC9302', '复制线上环境到QA', 'scripts', '/api/scripts/copyonline', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()),
('AC9303', '复制线下环境到QA', 'scripts', '/api/scripts/clientImageGitPull', 'POST', 1, '', 'system', 'system', UNIX_TIMESTAMP(), UNIX_TIMESTAMP())
ON DUPLICATE KEY UPDATE
`permission_name` = VALUES(`permission_name`),
`permission_name` = VALUES(`permission_name`),
`permission_group` = VALUES(`permission_group`),
`api_path` = VALUES(`api_path`),
`http_method` = VALUES(`http_method`),
`status` = VALUES(`status`),
`remark` = VALUES(`remark`),
`update_admin` = VALUES(`update_admin`),
`updateTime` = VALUES(`updateTime`);
`api_path` = VALUES(`api_path`),
`http_method` = VALUES(`http_method`),
`status` = VALUES(`status`),
`remark` = VALUES(`remark`),
`update_admin` = VALUES(`update_admin`),
`updateTime` = VALUES(`updateTime`);
-- 初始化关联关系示例
INSERT INTO `admin_group_role_rel` (`group_id`, `role_id`, `create_admin`, `createTime`)
@ -199,8 +291,8 @@ SELECT r.id, p.id, 'system', UNIX_TIMESTAMP()
FROM `admin_role` r
JOIN `admin_permission` p
WHERE (r.role_code = 'R_SUPER')
OR (r.role_code = 'R_ACTIVITY' AND p.permission_code IN ('AC0005'))
OR (r.role_code = 'R_NOTIFICATION' AND p.permission_code IN ('AC0003', 'AC0004'))
OR (r.role_code = 'R_ACTIVITY' AND p.permission_code IN ('AC6001','AC6002','AC6003','AC6004','AC6005'))
OR (r.role_code = 'R_NOTIFICATION' AND p.permission_code IN ('AC9101','AC9102'))
ON DUPLICATE KEY UPDATE
`create_admin` = VALUES(`create_admin`);

View File

@ -67,13 +67,18 @@ CREATE TABLE `admin` (
`id` int NOT NULL AUTO_INCREMENT,
`username` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户名',
`password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '密码',
`real_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '真实姓名',
`nickname` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '昵称',
`phone` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '手机号',
`email` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '邮箱',
`token` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '令牌',
`group` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户组',
`status` int DEFAULT NULL COMMENT '状态',
`status` int DEFAULT 1 COMMENT '状态 1=正常 0=禁用',
`expires` int DEFAULT 0 COMMENT '过期时间',
`role` int DEFAULT NULL COMMENT '角色',
`role` int DEFAULT NULL COMMENT '角色 0=超管 1=管理员 2=普通用户 99=外包翻译',
`lastLoginTime` int DEFAULT 0 COMMENT '最后登录时间',
`lastLoginIp` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '最后登录IP',
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '备注',
`createTime` int DEFAULT NULL COMMENT '创建时间',
`updateTime` int DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),

View File

@ -1,507 +0,0 @@
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] POST /api/auth/login --> backend/controller.Login (3 handlers)
[GIN-debug] GET /api/auth/Codes --> backend/controller.Codes (3 handlers)
[GIN-debug] POST /api/auth/phoneCode --> backend/controller.PhoneCode (3 handlers)
[GIN-debug] POST /api/auth/phoneLogin --> backend/controller.LoginCode (3 handlers)
[GIN-debug] POST /api/feishu/sendInfo --> backend/controller.FeishuSendInfo (3 handlers)
[GIN-debug] POST /api/feishu/sendInfo2 --> backend/controller.FeishuSendInfo2 (3 handlers)
[GIN-debug] POST /api/feishu/sendWeekInfo --> backend/controller.FeishuSendWeekInfo (3 handlers)
[GIN-debug] POST /api/feishu/updateApp --> backend/controller.FeishuUpdateApp (3 handlers)
[GIN-debug] POST /api/feishu/serverInfo --> backend/controller.FeishuServerInfo (3 handlers)
[GIN-debug] POST /api/feishu/notify --> backend/controller.FeishuNotify (3 handlers)
[GIN-debug] POST /api/feishu/notify/client --> backend/controller.FeishuNotifyClient (3 handlers)
[GIN-debug] POST /api/feishu/notify/order --> backend/controller.FeishuNotifyOrder (3 handlers)
[GIN-debug] POST /api/alibaba/zabbix/notify --> backend/controller.AlibabaNotify (3 handlers)
[GIN-debug] POST /api/alibaba/zabbix/recovery --> backend/controller.AlibabaRecovery (3 handlers)
[GIN-debug] POST /api/alibaba/game/notify --> backend/controller.AlibabaGameNotify (3 handlers)
[GIN-debug] POST /api/alibaba/notify/order --> backend/controller.AlibabaNotifyOrder (3 handlers)
[GIN-debug] GET /api/v1/experiments --> backend/controller.ExperimentList (4 handlers)
[GIN-debug] POST /api/v1/experiments --> backend/controller.ExperimentCreate (4 handlers)
[GIN-debug] PUT /api/v1/experiments/:id --> backend/controller.ExperimentUpdate (4 handlers)
[GIN-debug] DELETE /api/v1/experiments/:id --> backend/controller.ExperimentDelete (4 handlers)
[GIN-debug] GET /api/v1/experiments/:id/variants --> backend/controller.ExperimentVariantList (4 handlers)
[GIN-debug] POST /api/v1/experiments/:id/variants --> backend/controller.ExperimentVariantCreate (4 handlers)
[GIN-debug] PUT /api/v1/experiments/:id/variants/:variantId --> backend/controller.ExperimentVariantUpdate (4 handlers)
[GIN-debug] DELETE /api/v1/experiments/:id/variants/:variantId --> backend/controller.ExperimentVariantDelete (4 handlers)
[GIN-debug] GET /api/v1/experiments/:id/whitelist --> backend/controller.ExperimentWhitelistList (4 handlers)
[GIN-debug] POST /api/v1/experiments/:id/whitelist --> backend/controller.ExperimentWhitelistCreate (4 handlers)
[GIN-debug] POST /api/v1/experiments/:id/whitelist/batch --> backend/controller.ExperimentWhitelistBatchCreate (4 handlers)
[GIN-debug] DELETE /api/v1/experiments/:id/whitelist/:userId --> backend/controller.ExperimentWhitelistDelete (4 handlers)
[GIN-debug] GET /api/v1/experiments/:id/results --> backend/controller.ExperimentResult (4 handlers)
[GIN-debug] GET /api/v1/users/:userId/groups --> backend/controller.UserExperimentGroups (4 handlers)
[GIN-debug] POST /api/admin/list --> backend/controller.AdminList (4 handlers)
[GIN-debug] POST /api/admin/add --> backend/controller.AdminAdd (4 handlers)
[GIN-debug] POST /api/admin/log/list --> backend/controller.AdminLogList (4 handlers)
[GIN-debug] POST /api/admin/config/list --> backend/controller.AdminConfigList (4 handlers)
[GIN-debug] POST /api/admin/config/add --> backend/controller.AdminConfigAdd (4 handlers)
[GIN-debug] POST /api/admin/config/edit --> backend/controller.AdminConfigEdit (4 handlers)
[GIN-debug] POST /api/admin/usergroup/list --> backend/controller.PermissionUserGroupList (4 handlers)
[GIN-debug] POST /api/admin/usergroup/add --> backend/controller.PermissionUserGroupAdd (4 handlers)
[GIN-debug] POST /api/admin/usergroup/edit --> backend/controller.PermissionUserGroupEdit (4 handlers)
[GIN-debug] POST /api/admin/usergroup/delete --> backend/controller.PermissionUserGroupDelete (4 handlers)
[GIN-debug] POST /api/admin/usergroup/role/set --> backend/controller.PermissionGroupRoleSet (4 handlers)
[GIN-debug] POST /api/admin/usergroup/role/list --> backend/controller.PermissionGroupRoleList (4 handlers)
[GIN-debug] POST /api/admin/role/list --> backend/controller.PermissionRoleList (4 handlers)
[GIN-debug] POST /api/admin/role/add --> backend/controller.PermissionRoleAdd (4 handlers)
[GIN-debug] POST /api/admin/role/edit --> backend/controller.PermissionRoleEdit (4 handlers)
[GIN-debug] POST /api/admin/role/delete --> backend/controller.PermissionRoleDelete (4 handlers)
[GIN-debug] POST /api/admin/role/permission/set --> backend/controller.PermissionRolePermissionSet (4 handlers)
[GIN-debug] POST /api/admin/role/permission/list --> backend/controller.PermissionRolePermissionList (4 handlers)
[GIN-debug] POST /api/admin/permission/list --> backend/controller.PermissionPointList (4 handlers)
[GIN-debug] POST /api/admin/permission/add --> backend/controller.PermissionPointAdd (4 handlers)
[GIN-debug] POST /api/admin/permission/edit --> backend/controller.PermissionPointEdit (4 handlers)
[GIN-debug] POST /api/admin/permission/delete --> backend/controller.PermissionPointDelete (4 handlers)
[GIN-debug] POST /api/admin/user/group/list --> backend/controller.PermissionUserGroupRelList (4 handlers)
[GIN-debug] POST /api/admin/user/group/set --> backend/controller.PermissionUserGroupRelSet (4 handlers)
[GIN-debug] POST /api/log/user --> backend/controller.UserDetail (4 handlers)
[GIN-debug] POST /api/log/asset --> backend/controller.Asset (4 handlers)
[GIN-debug] POST /api/log/event --> backend/controller.Event (4 handlers)
[GIN-debug] POST /api/log/loginCountByMonth --> backend/controller.LoginCountByMonth (4 handlers)
[GIN-debug] POST /api/log/order --> backend/controller.Order (4 handlers)
[GIN-debug] POST /api/user/list --> backend/controller.UserList (4 handlers)
[GIN-debug] GET /api/user/info --> backend/controller.UserInfo (4 handlers)
[GIN-debug] POST /api/user/gm --> backend/controller.UserGM (4 handlers)
[GIN-debug] POST /api/user/ban --> backend/controller.UserBan (4 handlers)
[GIN-debug] POST /api/server/list --> backend/controller.AppList (4 handlers)
[GIN-debug] POST /api/server/serverList --> backend/controller.ServerList (4 handlers)
[GIN-debug] POST /api/server/addServer --> backend/controller.AddServer (4 handlers)
[GIN-debug] POST /api/server/nodeList --> backend/controller.NodeList (4 handlers)
[GIN-debug] POST /api/server/addNode --> backend/controller.AddNode (4 handlers)
[GIN-debug] POST /api/server/editServer --> backend/controller.EditServer (4 handlers)
[GIN-debug] POST /api/server/updateApp --> backend/controller.UpdateApp (4 handlers)
[GIN-debug] POST /api/server/updateAppReview --> backend/controller.UpdateAppReview (4 handlers)
[GIN-debug] POST /api/server/updateAppFeishu --> backend/controller.UpdateAppFeishu (4 handlers)
[GIN-debug] POST /api/server/restart --> backend/controller.RestartServer (4 handlers)
[GIN-debug] POST /api/server/reload --> backend/controller.ReloadServer (4 handlers)
[GIN-debug] POST /api/statistics/level --> backend/controller.StatisticsLevel (4 handlers)
[GIN-debug] POST /api/statistics/order --> backend/controller.StatisticsOrder (4 handlers)
[GIN-debug] POST /api/statistics/info --> backend/controller.StatisticsInfo (4 handlers)
[GIN-debug] POST /api/statistics/heat --> backend/controller.StatisticsHeat (4 handlers)
[GIN-debug] POST /api/activity/list --> backend/controller.ActivityList (4 handlers)
[GIN-debug] POST /api/activity/edit --> backend/controller.ActivityEdit (4 handlers)
[GIN-debug] POST /api/activity/add --> backend/controller.ActivityAdd (4 handlers)
[GIN-debug] POST /api/activity/delete --> backend/controller.ActivityDelete (4 handlers)
[GIN-debug] POST /api/activity/sync --> backend/controller.ActivitySync (4 handlers)
[GIN-debug] POST /api/mail/send --> backend/controller.SendMail (4 handlers)
[GIN-debug] POST /api/mail/list --> backend/controller.MailList (4 handlers)
[GIN-debug] POST /api/mail/delete --> backend/controller.MailDelete (4 handlers)
[GIN-debug] POST /api/operation/copyUser --> backend/controller.CopyUser (4 handlers)
[GIN-debug] POST /api/language/list --> backend/controller.Language (4 handlers)
[GIN-debug] POST /api/language/export --> backend/controller.LanguageExport (4 handlers)
[GIN-debug] POST /api/language/save --> backend/controller.LanguageSave (4 handlers)
[GIN-debug] POST /api/language/add --> backend/controller.LanguageAdd (4 handlers)
[GIN-debug] POST /api/language/delete --> backend/controller.LanguageDelete (4 handlers)
[GIN-debug] GET /api/config/notification --> backend/controller.NotificationConfigGet (4 handlers)
[GIN-debug] PUT /api/config/notification/update --> backend/controller.NotificationConfigSave (4 handlers)
[GIN-debug] POST /api/scripts/copywriting --> backend/controller.Copywriting (4 handlers)
[GIN-debug] POST /api/scripts/copyonline --> backend/controller.CopyOnline (4 handlers)
[GIN-debug] POST /api/scripts/clientImageGitPull --> backend/controller.ClientImageGitPull (4 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://github.com/gin-gonic/gin/blob/master/docs/doc.md#dont-trust-all-proxies for details.
[GIN-debug] Listening and serving HTTP on :5320
2026/04/28 15:27:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
[GIN] 2026/04/28 - 15:27:43 | 401 | 0s | ::1 | POST "/api/server/list"
[GIN] 2026/04/28 - 15:27:43 | 401 | 0s | ::1 | POST "/api/mail/list"
[GIN] 2026/04/28 - 15:27:43 | 404 | 0s | ::1 | POST "/api/auth/logout"
[GIN] 2026/04/28 - 15:27:43 | 404 | 0s | ::1 | POST "/api/auth/logout"
[GIN] 2026/04/28 - 15:27:51 | 200 | 81.32ms | ::1 | POST "/api/auth/login"
[GIN] 2026/04/28 - 15:27:51 | 200 | 533.1µs | ::1 | GET "/api/auth/Codes"
[GIN] 2026/04/28 - 15:27:51 | 200 | 58.65ms | ::1 | GET "/api/user/info"
[GIN] 2026/04/28 - 15:27:52 | 200 | 199.04ms | ::1 | POST "/api/server/list"
[GIN] 2026/04/28 - 15:27:52 | 200 | 298.53ms | ::1 | POST "/api/mail/list"
2026/04/28 15:28:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
[GIN] 2026/04/28 - 15:28:29 | 200 | 325.47ms | ::1 | POST "/api/mail/send"
2026/04/28 15:28:29 failed to send admin message: ReloadMail failed: rpc error: code = Unimplemented desc = unknown method ReloadMail for service tutorial.Backend
2026/04/28 15:28:29 sent reload mail message to server 0
2026/04/28 15:28:29 sent reload mail message to server 2
2026/04/28 15:28:29 sent reload mail message to server 1
[GIN] 2026/04/28 - 15:28:30 | 200 | 197.42ms | ::1 | POST "/api/mail/list"
2026/04/28 15:28:32 failed to send admin message: ReloadMail failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:28:32 sent reload mail message to server 3
2026/04/28 15:29:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:30:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:31:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:32:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:33:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:34:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:35:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:36:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:37:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:38:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:39:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:40:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:41:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:42:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:43:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:44:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:45:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:46:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:47:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:48:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:49:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:50:04 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:51:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:52:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:53:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:54:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:55:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:56:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:57:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:58:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 15:59:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:00:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:01:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:02:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:03:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:04:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:05:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:06:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:07:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:08:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:09:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:10:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:11:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:12:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:13:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:14:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:15:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:16:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:17:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:18:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:19:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:20:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:21:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:22:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:23:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:24:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:25:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:26:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:27:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:28:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:29:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:30:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:31:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:32:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:33:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:34:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:35:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:36:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:37:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:38:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:39:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:40:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:41:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:42:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:43:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:44:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:45:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:46:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:47:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:48:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:49:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:50:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:51:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:52:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:53:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:54:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:55:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:56:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:57:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:58:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 16:59:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:00:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:01:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:02:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:03:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:04:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:05:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:06:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:07:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:08:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:09:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:10:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:11:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:12:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:13:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:14:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:15:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:16:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:17:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:18:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:19:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:20:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:21:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:22:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:23:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:24:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:25:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:26:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:27:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:28:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:29:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:30:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:31:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:32:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:33:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:34:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:35:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:36:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:37:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:38:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:39:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:40:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:41:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:42:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:43:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:44:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:45:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:46:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:47:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:48:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:49:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:50:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:51:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:52:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:53:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:54:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:55:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:56:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:57:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:58:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 17:59:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:00:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:01:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:02:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:03:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:04:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:05:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:06:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:07:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:08:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:09:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:10:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:11:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:12:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:13:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:14:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:15:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:16:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:17:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:18:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:19:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:20:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:21:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:22:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:23:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:24:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:25:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:26:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:27:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:28:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:29:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:30:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:31:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:32:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:33:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:34:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:35:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:36:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:37:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:38:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:39:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:40:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:41:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:42:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:43:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:44:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:45:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:46:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:47:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:48:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:49:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:50:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:51:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:52:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:53:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:54:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:55:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:56:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:57:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:58:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 18:59:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:00:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:01:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:02:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:03:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:04:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:05:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:06:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:07:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:08:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:09:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:10:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:11:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:12:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:13:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:14:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:15:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:16:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:17:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:18:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:19:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:20:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:21:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:22:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:23:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:24:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:25:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:26:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:27:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:28:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:29:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:30:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:31:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:32:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:33:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:34:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:35:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:36:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:37:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:38:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:39:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:40:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:41:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:42:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:43:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:44:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:45:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:46:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:47:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:48:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:49:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:50:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:51:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:52:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:53:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:54:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:55:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:56:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:57:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:58:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 19:59:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:00:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:01:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:02:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:03:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:04:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:05:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:06:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:07:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:08:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:09:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:10:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:11:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:12:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:13:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:14:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:15:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:16:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:17:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:18:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:19:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:20:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:21:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:22:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:23:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:24:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:25:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:26:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:27:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:28:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:29:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:30:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:31:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:32:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:33:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:34:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:35:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:36:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:37:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:38:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:39:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:40:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:41:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:42:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:43:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:44:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:45:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:46:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:47:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:48:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:49:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:50:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:51:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:52:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:53:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:54:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:55:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:56:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:57:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:58:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 20:59:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:00:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:01:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:02:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:03:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:04:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:05:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:06:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:07:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:08:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:09:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:10:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:11:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:12:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:13:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:14:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:15:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:16:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:17:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:18:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:19:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:20:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:21:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:22:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:23:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:24:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:25:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:26:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:27:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:28:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:29:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:30:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:31:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:32:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:33:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:34:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:35:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:36:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:37:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:38:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:39:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:40:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:41:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:42:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:43:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:44:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:45:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:46:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:47:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:48:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:49:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded
2026/04/28 21:50:03 Failed to get server info for AppId=1, ServerId=3: ServerInfo failed: rpc error: code = DeadlineExceeded desc = received context error while waiting for new LB policy update: context deadline exceeded

22
main.go
View File

@ -78,6 +78,10 @@ func main() {
}
}()
r := gin.Default()
openApi := r.Group("/api/open")
{
openApi.POST("/apk/upload", controller.UploadApkPackage)
}
loginApi := r.Group("/api/auth")
{
// 认证
@ -128,9 +132,18 @@ func main() {
}
api := r.Group("/api", middleware.ValidateToken())
{
// 以下路由只校验 token不校验权限
r.GET("/api/user/info", middleware.ValidateTokenOnly(), controller.UserInfo)
r.POST("/api/statistics/info", middleware.ValidateTokenOnly(), controller.StatisticsInfo)
r.POST("/api/statistics/level", middleware.ValidateTokenOnly(), controller.StatisticsLevel)
r.POST("/api/statistics/order", middleware.ValidateTokenOnly(), controller.StatisticsOrder)
r.POST("/api/statistics/heat", middleware.ValidateTokenOnly(), controller.StatisticsHeat)
// 账号管理
api.POST("/admin/list", controller.AdminList)
api.POST("/admin/add", controller.AdminAdd)
api.POST("/admin/edit", controller.AdminEdit)
api.POST("/admin/delete", controller.AdminDelete)
api.POST("/admin/log/list", controller.AdminLogList)
api.POST("/admin/config/list", controller.AdminConfigList)
api.POST("/admin/config/add", controller.AdminConfigAdd)
@ -156,6 +169,7 @@ func main() {
api.POST("/admin/user/permission/list", controller.PermissionUserPermissionList)
api.POST("/admin/user/permission/set", controller.PermissionUserPermissionSet)
api.POST("/admin/user/role/list", controller.PermissionUserRoleList)
api.POST("/admin/user/role/batch-list", controller.PermissionUserRoleBatchList)
// 玩家日志
api.POST("/log/user", controller.UserDetail)
api.POST("/log/asset", controller.Asset)
@ -165,7 +179,6 @@ func main() {
// 玩家数据
api.POST("/user/list", controller.UserList)
api.GET("/user/info", controller.UserInfo)
api.POST("/user/gm", controller.UserGM)
api.POST("/user/ban", controller.UserBan)
@ -182,11 +195,6 @@ func main() {
api.POST("/server/restart", controller.RestartServer)
api.POST("/server/reload", controller.ReloadServer)
api.POST("/statistics/level", controller.StatisticsLevel)
api.POST("/statistics/order", controller.StatisticsOrder)
api.POST("/statistics/info", controller.StatisticsInfo)
api.POST("/statistics/heat", controller.StatisticsHeat)
//活动
api.POST("/activity/list", controller.ActivityList)
api.POST("/activity/edit", controller.ActivityEdit)
@ -200,6 +208,8 @@ func main() {
api.POST("/mail/delete", controller.MailDelete)
// 运营功能
api.POST("/operation/copyUser", controller.CopyUser)
api.GET("/apk/packages", controller.GetApkPackages)
api.GET("/apk/download/:env", controller.DownloadApkPackage)
// 翻译
api.POST("/language/list", controller.Language)

View File

@ -30,7 +30,7 @@ func ValidateToken() gin.HandlerFunc {
// 验证用户权限
if tokenInfo != nil {
hasPermission := model.CheckUserPermission(tokenInfo.UserName, path)
hasPermission := model.CheckUserPermission(tokenInfo.UserName, path, c.Request.Method)
if !hasPermission {
c.JSON(403, gin.H{"error": "Permission denied"})
c.Abort()
@ -41,3 +41,23 @@ func ValidateToken() gin.HandlerFunc {
c.Next()
}
}
// ValidateTokenOnly 只校验 token 有效性,不做权限校验
func ValidateTokenOnly() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.GetHeader("Authorization")
if len(token) > 7 && token[:7] == "Bearer " {
token = token[7:]
}
if token == "" || !store.IsTokenValid(token) {
c.JSON(401, gin.H{"error": "Authorization header is required"})
c.Abort()
return
}
tokenInfo, _ := store.GetTokenInfo(token)
if tokenInfo != nil {
c.Set("admin", tokenInfo.UserName)
}
c.Next()
}
}

View File

@ -5,8 +5,24 @@ import (
"fmt"
"sort"
"strconv"
"sync"
"time"
)
type statisticsInfoCacheEntry struct {
data map[string]interface{}
expireAt time.Time
}
var statisticsInfoCache = struct {
mu sync.RWMutex
items map[int]statisticsInfoCacheEntry
}{
items: make(map[int]statisticsInfoCacheEntry),
}
const statisticsInfoCacheTTL = time.Minute
type Statistics struct {
AppId int `json:"AppId"`
ServerList []int `json:"ServerList"`
@ -57,40 +73,62 @@ func (s *Statistics) StatisticsLevel() (interface{}, error) {
}
func (s *Statistics) StatisticsInfo() (interface{}, error) {
statisticsInfoCache.mu.RLock()
if entry, ok := statisticsInfoCache.items[s.AppId]; ok && time.Now().Before(entry.expireAt) {
cached := make(map[string]interface{}, len(entry.data))
for k, v := range entry.data {
cached[k] = v
}
statisticsInfoCache.mu.RUnlock()
return cached, nil
}
statisticsInfoCache.mu.RUnlock()
AppConfig, err := util.GetAppConfig(s.AppId)
if err != nil {
return nil, err
}
LogDb := util.MPool.GetTopicDB(AppConfig.Topic)
defer LogDb.Close()
if LogDb == nil {
return nil, fmt.Errorf("failed to get mysql database")
overview, err := util.CountStatisticsOverview(s.AppId, AppConfig.OpenTime, AppConfig.Tz)
if err != nil {
return nil, err
}
var Register int
var TotalRegistger int
var Recharge float64
var TotalRecharge float64
var RechargeUser int
rechargeFloat, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", Recharge), 64)
totalRechargeFloat, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", TotalRecharge), 64)
return map[string]interface{}{
"register": Register,
"totalRegister": TotalRegistger,
rechargeFloat, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", overview.Recharge), 64)
totalRechargeFloat, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", overview.TotalRecharge), 64)
result := map[string]interface{}{
"register": overview.Register,
"totalRegister": overview.TotalRegister,
"recharge": rechargeFloat,
"totalRecharge": totalRechargeFloat,
"rechargeUser": RechargeUser,
"totalRechargeUser": 0,
"rechargeUser": overview.RechargeUser,
"totalRechargeUser": overview.TotalRechargeUser,
"remain": 0,
}, nil
}
statisticsInfoCache.mu.Lock()
statisticsInfoCache.items[s.AppId] = statisticsInfoCacheEntry{
data: result,
expireAt: time.Now().Add(statisticsInfoCacheTTL),
}
statisticsInfoCache.mu.Unlock()
return result, nil
}
func (s *Statistics) StatisticsHeat() (interface{}, error) {
AppConfig, err := util.GetAppConfig(s.AppId)
if err != nil {
return nil, err
}
trend, err := util.CountStatisticsHeat7Days(s.AppId, AppConfig.Tz)
if err != nil {
return nil, err
}
return map[string]interface{}{
"key": nil,
"value": nil,
"value2": nil,
"key": trend.Key,
"value": trend.DailyActive,
"value2": trend.Register,
}, nil
}

View File

@ -4,6 +4,7 @@ import (
"backend/store"
"backend/util"
"fmt"
"strings"
"github.com/gin-gonic/gin"
)
@ -38,15 +39,13 @@ type AdminLog struct {
}
func (a *Admin) List() (*Result, error) {
// 这里可以添加数据库查询逻辑来获取管理员列表
// 假设我们从数据库中查询到数据并返回
var admins []Admin
db := util.MPool.GetGameDB() // 假设使用默认的AppConfig和ServerId为0
db := util.MPool.GetGameDB()
defer db.Close()
if db == nil {
return nil, fmt.Errorf("failed to get database connection")
}
err := db.Select(&admins, "SELECT * FROM admin")
err := db.Select(&admins, "SELECT `id`,`username`,`real_name`,`nickname`,`phone`,`email`,`group`,`status`,`role`,`lastLoginTime`,`lastLoginIp`,`createTime`,`updateTime`,`remark` FROM admin ORDER BY id DESC")
if err != nil {
return nil, fmt.Errorf("failed to scan rows: %v", err)
}
@ -69,8 +68,11 @@ func (a *Admin) Add() (*Result, error) {
defer db.Close()
a.CreateTime = int(util.Now())
a.UpdateTime = a.CreateTime
a.Password, _ = util.Encrypt(a.Password) // 假设有一个加密函数
_, err := db.NamedExec("INSERT INTO admin (`username`, `password`, `phone`, `email`, `token`, `group`, `status`, `role`, `createTime`, `updateTime`, `expires`, `remark`) VALUES (:username, :password, :phone, :email, :token, :group, :status, :role, :createTime, :updateTime, :expires, :remark)", a)
if a.Status == 0 {
a.Status = 1 // 默认启用
}
a.Password, _ = util.Encrypt(a.Password)
_, err := db.NamedExec("INSERT INTO admin (`username`, `password`, `real_name`, `nickname`, `phone`, `email`, `token`, `group`, `status`, `role`, `createTime`, `updateTime`, `expires`, `remark`) VALUES (:username, :password, :real_name, :nickname, :phone, :email, :token, :group, :status, :role, :createTime, :updateTime, :expires, :remark)", a)
if err != nil {
return nil, fmt.Errorf("failed to add admin: %v", err)
}
@ -186,6 +188,32 @@ func InitToken() {
}
}
func (a *Admin) Edit() error {
db := util.MPool.GetGameDB()
defer db.Close()
if db == nil {
return fmt.Errorf("failed to get database connection")
}
a.UpdateTime = int(util.Now())
if a.Password != "" {
a.Password, _ = util.Encrypt(a.Password)
_, err := db.NamedExec("UPDATE admin SET `real_name`=:real_name, `nickname`=:nickname, `phone`=:phone, `email`=:email, `group`=:group, `role`=:role, `status`=:status, `remark`=:remark, `password`=:password, `updateTime`=:updateTime WHERE id=:id", a)
return err
}
_, err := db.NamedExec("UPDATE admin SET `real_name`=:real_name, `nickname`=:nickname, `phone`=:phone, `email`=:email, `group`=:group, `role`=:role, `status`=:status, `remark`=:remark, `updateTime`=:updateTime WHERE id=:id", a)
return err
}
func (a *Admin) Delete() error {
db := util.MPool.GetGameDB()
defer db.Close()
if db == nil {
return fmt.Errorf("failed to get database connection")
}
_, err := db.Exec("DELETE FROM admin WHERE id = ?", a.ID)
return err
}
func SendPhoneCode(phone string) error {
// 这里可以添加逻辑来发送验证码到手机
// 假设我们使用一个外部服务发送验证码
@ -197,83 +225,90 @@ func SendPhoneCode(phone string) error {
return nil
}
var PermissionList = map[string][]string{
"/api/admin/list": {"super", "admin"},
"/api/admin/add": {"super"},
"/api/admin/log/list": {"super", "admin"},
"/api/admin/usergroup/list": {"super", "admin"},
"/api/admin/usergroup/add": {"super", "admin"},
"/api/admin/usergroup/edit": {"super", "admin"},
"/api/admin/usergroup/delete": {"super", "admin"},
"/api/admin/usergroup/role/set": {"super", "admin"},
"/api/admin/usergroup/role/list": {"super", "admin"},
"/api/admin/role/list": {"super", "admin"},
"/api/admin/role/add": {"super", "admin"},
"/api/admin/role/edit": {"super", "admin"},
"/api/admin/role/delete": {"super", "admin"},
"/api/admin/role/permission/set": {"super", "admin"},
"/api/admin/role/permission/list": {"super", "admin"},
"/api/admin/permission/list": {"super", "admin"},
"/api/admin/permission/add": {"super", "admin"},
"/api/admin/permission/edit": {"super", "admin"},
"/api/admin/permission/delete": {"super", "admin"},
"/api/admin/user/group/list": {"super", "admin"},
"/api/admin/user/group/set": {"super", "admin"},
"/api/log/user": {"super", "admin", "user"},
"/api/log/asset": {"super", "admin", "user"},
"/api/log/event": {"super", "admin", "user"},
"/api/log/order": {"super", "admin", "user"},
"/api/user/list": {"super", "admin", "user"},
"/api/user/gm": {"super", "admin"},
"/api/user/ban": {"super", "admin"},
"/api/server/list": {"super", "admin"},
"/api/server/serverList": {"super", "admin"},
"/api/server/addServer": {"super"},
"/api/server/nodeList": {"super"},
"/api/server/addNode": {"super"},
"/api/server/updateApp": {"super", "admin"},
"/api/server/restart": {"super", "admin"},
"/api/server/reload": {"super", "admin"},
"/api/statistics/level": {"super", "admin"},
"/api/statistics/order": {"super", "admin"},
"/api/statistics/info": {"super", "admin"},
"/api/statistics/heat": {"super", "admin"},
"/api/mail/send": {"super", "admin"},
"/api/mail/list": {"super", "admin"},
"/api/mail/delete": {"super", "admin"},
"/api/language/list": {"super", "admin", "wb_transfer"},
"/api/language/export": {"super", "admin", "wb_transfer"},
"/api/language/save": {"super", "admin", "wb_transfer"},
"/api/language/add": {"super", "admin", "wb_transfer"},
"/api/language/delete": {"super", "admin"},
"/api/client/notification": {"super", "admin"},
"/api/v1/experiments": {"super", "admin"},
"/api/v1/experiments/:id": {"super", "admin"},
"/api/v1/experiments/:id/variants": {"super", "admin"},
"/api/v1/experiments/:id/variants/:variantId": {"super", "admin"},
"/api/v1/experiments/:id/whitelist": {"super", "admin"},
"/api/v1/experiments/:id/whitelist/batch": {"super", "admin"},
"/api/v1/experiments/:id/whitelist/:userId": {"super", "admin"},
"/api/v1/experiments/:id/results": {"super", "admin"},
"/api/v1/users/:userId/groups": {"super", "admin"},
}
func CheckUserPermission(username, path string) bool {
Admin := &Admin{}
err := Admin.GetAdmin(username)
if err != nil {
// CheckUserPermission 基于 admin_permission 表进行动态 DB 鉴权。
// 鉴权优先级super 全放行 → 路径无受控权限点放行 →
// 用户直接权限(显式允许/拒绝)→ 用户组→角色→权限链路 → 默认拒绝。
func CheckUserPermission(username, path, method string) bool {
db := util.MPool.GetGameDB()
if db == nil {
return false
}
PermissionRoles, exists := PermissionList[path]
if !exists {
// 如果路径不存在于权限列表中,默认允许访问
defer db.Close()
// 查询用户 ID 和角色
var adminInfo struct {
ID int `db:"id"`
Role int `db:"role"`
}
if err := db.Get(&adminInfo, "SELECT id, role FROM admin WHERE username = ?", username); err != nil {
return false
}
// super 超级管理员跳过所有权限检查
if util.GetRole(adminInfo.Role) == util.RoleSuper {
return true
}
for _, role := range PermissionRoles {
if util.GetRole(Admin.Role) == role {
return true
// 用户通过用户组继承到 R_SUPER 角色时放行
var superRoleCount int
if err := db.Get(&superRoleCount,
`SELECT COUNT(*)
FROM admin_user_group_rel ugr
INNER JOIN admin_group_role_rel grr ON grr.group_id = ugr.group_id
INNER JOIN admin_role r ON r.id = grr.role_id
WHERE ugr.admin_id = ? AND r.role_code = 'R_SUPER' AND r.status = 1`,
adminInfo.ID,
); err == nil && superRoleCount > 0 {
return true
}
// 查找匹配路径的受控权限点http_method 为空视为不限方法)
var permIDs []int
if err := db.Select(&permIDs,
"SELECT id FROM admin_permission WHERE api_path = ? AND status = 1 AND (http_method = '' OR http_method = ?)",
path, method,
); err != nil || len(permIDs) == 0 {
// 路径未被任何权限点管控 → 放行
return true
}
// 检查用户直接权限(优先级最高)
for _, pid := range permIDs {
var grantType int
err := db.Get(&grantType,
"SELECT grant_type FROM admin_user_permission_rel WHERE admin_id = ? AND permission_id = ?",
adminInfo.ID, pid,
)
if err == nil {
if grantType == 2 {
return false // 显式拒绝
}
if grantType == 1 {
return true // 显式允许
}
}
}
// 检查 用户 → 用户组 → 角色 → 权限 链路
placeholders := make([]string, len(permIDs))
pidArgs := make([]interface{}, 1+len(permIDs))
pidArgs[0] = adminInfo.ID
for i, pid := range permIDs {
placeholders[i] = "?"
pidArgs[i+1] = pid
}
var count int
q := fmt.Sprintf(
`SELECT COUNT(*) FROM admin_role_permission_rel rpr
INNER JOIN admin_group_role_rel grr ON grr.role_id = rpr.role_id
INNER JOIN admin_user_group_rel ugr ON ugr.group_id = grr.group_id
WHERE ugr.admin_id = ? AND rpr.permission_id IN (%s)`,
strings.Join(placeholders, ","),
)
if err := db.Get(&count, q, pidArgs...); err == nil && count > 0 {
return true
}
return false
}

View File

@ -541,3 +541,135 @@ func ListUserRoles(adminID int) ([]PermissionRole, error) {
}
return list, nil
}
func ListUserRolesByAdminIDs(adminIDs []int) (map[int][]PermissionRole, error) {
result := make(map[int][]PermissionRole, len(adminIDs))
if len(adminIDs) == 0 {
return result, nil
}
db := util.MPool.GetGameDB()
defer db.Close()
if db == nil {
return nil, fmt.Errorf("failed to get database connection")
}
placeholders := strings.TrimRight(strings.Repeat("?,", len(adminIDs)), ",")
args := make([]interface{}, 0, len(adminIDs))
for _, adminID := range adminIDs {
args = append(args, adminID)
result[adminID] = []PermissionRole{}
}
type userRoleRow struct {
AdminID int `db:"admin_id"`
PermissionRole
}
rows := []userRoleRow{}
query := `SELECT DISTINCT ugr.admin_id, r.id, r.role_code, r.role_name, r.status, r.is_system, r.remark, r.createTime, r.updateTime
FROM admin_role r
INNER JOIN admin_group_role_rel grr ON grr.role_id = r.id
INNER JOIN admin_user_group_rel ugr ON ugr.group_id = grr.group_id
WHERE ugr.admin_id IN (` + placeholders + `)
ORDER BY ugr.admin_id ASC, r.id DESC`
if err := db.Select(&rows, query, args...); err != nil {
return nil, err
}
for _, row := range rows {
result[row.AdminID] = append(result[row.AdminID], row.PermissionRole)
}
return result, nil
}
// UserEffectiveInfo 用户登录后的有效权限摘要
type UserEffectiveInfo struct {
// Roles 用户通过用户组继承的角色 code 列表
Roles []string `json:"roles"`
// Permissions 用户最终有效的权限 code 列表:
// 角色链路授予 + 直接允许grant_type=1再减去直接拒绝grant_type=2
Permissions []string `json:"permissions"`
}
// GetUserEffectiveInfo 一次查询返回用户的有效角色和权限列表。
// adminID 为 admin 表的 idisSuperAdmin 时直接返回空列表(表示不受控)。
func GetUserEffectiveInfo(adminID int, isSuperAdmin bool) (*UserEffectiveInfo, error) {
if isSuperAdmin {
return &UserEffectiveInfo{Roles: []string{}, Permissions: []string{}}, nil
}
db := util.MPool.GetGameDB()
if db == nil {
return nil, fmt.Errorf("failed to get database connection")
}
defer db.Close()
// 1. 角色 code 列表(用户组 → 角色)
var roleCodes []string
roleQuery := `SELECT DISTINCT r.role_code
FROM admin_role r
INNER JOIN admin_group_role_rel grr ON grr.role_id = r.id
INNER JOIN admin_user_group_rel ugr ON ugr.group_id = grr.group_id
WHERE ugr.admin_id = ? AND r.status = 1`
if err := db.Select(&roleCodes, roleQuery, adminID); err != nil {
return nil, err
}
if roleCodes == nil {
roleCodes = []string{}
}
// 2. 通过角色链路获得的权限 code 集合
permSet := map[string]struct{}{}
if len(roleCodes) > 0 {
ph := strings.Repeat("?,", len(roleCodes))
ph = ph[:len(ph)-1]
args := make([]interface{}, len(roleCodes))
for i, c := range roleCodes {
args[i] = c
}
var rolePerm []string
q := fmt.Sprintf(`SELECT DISTINCT p.permission_code
FROM admin_permission p
INNER JOIN admin_role_permission_rel rpr ON rpr.permission_id = p.id
INNER JOIN admin_role r ON r.id = rpr.role_id
WHERE r.role_code IN (%s) AND p.status = 1`, ph)
if err := db.Select(&rolePerm, q, args...); err != nil {
return nil, err
}
for _, code := range rolePerm {
permSet[code] = struct{}{}
}
}
// 3. 直接单点权限:允许补入,拒绝剔除
var directPerms []struct {
Code string `db:"permission_code"`
GrantType int `db:"grant_type"`
}
directQuery := `SELECT p.permission_code, rel.grant_type
FROM admin_permission p
INNER JOIN admin_user_permission_rel rel ON rel.permission_id = p.id
WHERE rel.admin_id = ? AND p.status = 1`
if err := db.Select(&directPerms, directQuery, adminID); err != nil {
return nil, err
}
for _, dp := range directPerms {
if dp.GrantType == 1 {
permSet[dp.Code] = struct{}{}
} else if dp.GrantType == 2 {
delete(permSet, dp.Code)
}
}
perms := make([]string, 0, len(permSet))
for code := range permSet {
perms = append(perms, code)
}
return &UserEffectiveInfo{
Roles: roleCodes,
Permissions: perms,
}, nil
}

View File

@ -7,6 +7,7 @@ import (
"backend/model"
"backend/msg"
"backend/util"
"errors"
"fmt"
"log"
"net"
@ -59,10 +60,10 @@ func ServerInfoMonitor() {
}
func monitorServerInfo() {
Db := util.MPool.GetGameDB()
db := util.MPool.GetGameDB()
var server []*Type.ServerInfo
defer Db.Close()
err := Db.Select(&server, "SELECT `AppId`, `ServerId`, `ServerName`, `Status`, `CreateTime`, `OpenServerTime`, `Host`, `Port` FROM server ")
defer db.Close()
err := db.Select(&server, "SELECT `AppId`, `ServerId`, `ServerName`, `Status`, `CreateTime`, `OpenServerTime`, `Host`, `Port` FROM server ")
if err != nil {
return
}
@ -70,85 +71,117 @@ func monitorServerInfo() {
if v.Status == 2 || v.Status == 3 { // 维护中或停用跳过
continue
}
if v.AppId == 1 || v.AppId == 2 { // example condition, adjust as needed
go func(v *Type.ServerInfo) {
resp, err := client.GetServerInfo(v.AppId, v.ServerId, &msg.ReqServerInfo{})
if err != nil {
log.Printf("Failed to get server info for AppId=%d, ServerId=%d: %v", v.AppId, v.ServerId, err)
return
}
tmpDb := util.MPool.GetGameDB()
defer tmpDb.Close()
latency, err := util.GetAddressLatency(v.Host, v.Port)
if err != nil {
// Connection failed, mark server as offline
tmpDb.Exec("update server set Status=0 where AppId=? and ServerId=?", v.AppId, v.ServerId)
return
}
weight := util.GetServerWeight(resp)
extra, _ := protojson.Marshal(resp)
tmpDb.Exec("update server set Status=1, Online=?,free_mem=?,cpu=?,weight=?,latency=?,extra=? where AppId=? and ServerId=?", resp.PlayerNum, resp.Sys, resp.CPU, weight, latency, string(extra), v.AppId, v.ServerId)
}(v)
continue
}
go func(v *Type.ServerInfo) {
tmpDb := util.MPool.GetGameDB()
defer tmpDb.Close()
// TCP ping test for server connectivity
address := fmt.Sprintf("%s:%d", v.Host, v.Port) // adjust port as needed
timeout := 3 * time.Second
start := time.Now()
conn, err := net.DialTimeout("tcp", address, timeout)
latency := time.Since(start).Milliseconds()
if err != nil {
// Connection failed, mark server as offline
tmpDb.Exec("update server set Status=0 where AppId=? and ServerId=?", v.AppId, v.ServerId)
return
if err := monitorServerByFallback(v); err != nil {
log.Printf("monitor server failed, AppId=%d, ServerId=%d, err=%v", v.AppId, v.ServerId, err)
markServerOffline(v.AppId, v.ServerId)
}
conn.Close()
res, err := model.GetServerInfo(v.AppId, v.ServerId)
if err != nil {
//tmpDb.Exec("update server set Status=0 where AppId=? and ServerId=?", v.AppId, v.ServerId)
return
}
serverInfo := res.(map[string]interface{})
free_mem := util.Int(serverInfo["FreeMem"])
usage_mem := util.Int(serverInfo["Sys"])
cpu := util.Int(serverInfo["CPU"])
// compute weight in 0-100 based on free_mem (MB) and cpu (%)
// heuristic: more free memory and lower CPU -> higher weight
memCap := 8192 // 8GB as reference cap for normalization
if free_mem < 0 {
free_mem = 0
}
memScore := 0
if free_mem >= memCap {
memScore = 100
} else {
memScore = free_mem * 100 / memCap
}
if cpu < 0 {
cpu = 0
}
if cpu > 100 {
cpu = 100
}
cpuScore := 100 - cpu // lower CPU -> higher score
// weighted: 60% memory, 40% CPU
weight := (memScore*6 + cpuScore*4) / 10
if weight < 0 {
weight = 0
}
if weight > 100 {
weight = 100
}
// optionally store/update weight
serverInfo["Weight"] = weight
// Process serverInfo as needed
tmpDb.Exec("update server set Status=1, Online=?,free_mem=?,cpu=?,weight=?,latency=? where AppId=? and ServerId=?", util.Int(serverInfo["PlayerNum"]), usage_mem, cpu, weight, latency, v.AppId, v.ServerId)
}(v)
}
}
func monitorServerByFallback(v *Type.ServerInfo) error {
// 默认优先使用第一种方式;失败后自动切换第二种,再反向回退第一种重试一次。
firstErr := monitorServerByMethod1(v)
if firstErr == nil {
return nil
}
secondErr := monitorServerByMethod2(v)
if secondErr == nil {
return nil
}
if err := monitorServerByMethod1(v); err == nil {
return nil
}
return fmt.Errorf("method1 and method2 both failed, method1Err=%v, method2Err=%v", firstErr, secondErr)
}
func monitorServerByMethod1(v *Type.ServerInfo) error {
resp, err := client.GetServerInfo(v.AppId, v.ServerId, &msg.ReqServerInfo{})
if err != nil {
return err
}
latency, err := util.GetAddressLatency(v.Host, v.Port)
if err != nil {
return err
}
tmpDb := util.MPool.GetGameDB()
defer tmpDb.Close()
weight := util.GetServerWeight(resp)
extra, _ := protojson.Marshal(resp)
_, err = tmpDb.Exec("update server set Status=1, Online=?,free_mem=?,cpu=?,weight=?,latency=?,extra=? where AppId=? and ServerId=?", resp.PlayerNum, resp.Sys, resp.CPU, weight, latency, string(extra), v.AppId, v.ServerId)
return err
}
func monitorServerByMethod2(v *Type.ServerInfo) error {
address := fmt.Sprintf("%s:%d", v.Host, v.Port)
timeout := 3 * time.Second
start := time.Now()
conn, err := net.DialTimeout("tcp", address, timeout)
latency := time.Since(start).Milliseconds()
if err != nil {
return err
}
conn.Close()
res, err := model.GetServerInfo(v.AppId, v.ServerId)
if err != nil {
return err
}
serverInfo, ok := res.(map[string]interface{})
if !ok {
return errors.New("invalid server info response type")
}
freeMem := util.Int(serverInfo["FreeMem"])
usageMem := util.Int(serverInfo["Sys"])
cpu := util.Int(serverInfo["CPU"])
weight := calcServerWeight(freeMem, cpu)
tmpDb := util.MPool.GetGameDB()
defer tmpDb.Close()
_, err = tmpDb.Exec("update server set Status=1, Online=?,free_mem=?,cpu=?,weight=?,latency=? where AppId=? and ServerId=?", util.Int(serverInfo["PlayerNum"]), usageMem, cpu, weight, latency, v.AppId, v.ServerId)
return err
}
func calcServerWeight(freeMem int, cpu int) int {
memCap := 8192 // 8GB as reference cap for normalization
if freeMem < 0 {
freeMem = 0
}
memScore := 0
if freeMem >= memCap {
memScore = 100
} else {
memScore = freeMem * 100 / memCap
}
if cpu < 0 {
cpu = 0
}
if cpu > 100 {
cpu = 100
}
cpuScore := 100 - cpu
weight := (memScore*6 + cpuScore*4) / 10
if weight < 0 {
return 0
}
if weight > 100 {
return 100
}
return weight
}
func markServerOffline(appID int, serverID int) {
tmpDb := util.MPool.GetGameDB()
defer tmpDb.Close()
_, _ = tmpDb.Exec("update server set Status=0 where AppId=? and ServerId=?", appID, serverID)
}

View File

@ -140,7 +140,7 @@ func TestEncrypt(t *testing.T) {
}
func TestDecrypt(t *testing.T) {
str := "linyiling123"
str := "guositeng123"
enc, _ := util.Encrypt(str)
dec, _ := util.Decrypt("mz-AJj2wjQ5F6MY5hbxiqsfqcwjRj8P85w==")
fmt.Printf("enc:%s\ndec:%s\n", enc, dec)

View File

@ -45,14 +45,14 @@ func GetEsClient() (*elasticsearch.Client, error) {
// DSlSearch 执行 DSL 查询
// query 参数为查询 DSL 的 map 结构
// sort 参数为排序条件,传 nil 表示不排序
func DSlSearch(ctx context.Context, index string, query map[string]interface{}, from, size int, sort []map[string]interface{}) (map[string]interface{}, error) {
func DSlSearch(ctx context.Context, index string, query map[string]any, from, size int, sort []map[string]any) (map[string]any, error) {
client, err := GetEsClient()
if err != nil {
return nil, err
}
// 构建完整查询
fullQuery := map[string]interface{}{
fullQuery := map[string]any{
"query": query,
"from": from,
"size": size,
@ -67,7 +67,6 @@ func DSlSearch(ctx context.Context, index string, query map[string]interface{},
if err := json.NewEncoder(&buf).Encode(fullQuery); err != nil {
return nil, fmt.Errorf("编码查询失败: %w", err)
}
fmt.Printf("%s", buf.String())
res, err := client.Search(
client.Search.WithContext(ctx),
client.Search.WithIndex(index),
@ -84,7 +83,7 @@ func DSlSearch(ctx context.Context, index string, query map[string]interface{},
return nil, fmt.Errorf("ES 搜索错误 [%s]: %s", res.Status(), string(bodyBytes))
}
var result map[string]interface{}
var result map[string]any
if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
return nil, fmt.Errorf("解析响应失败: %w", err)
}
@ -93,9 +92,9 @@ func DSlSearch(ctx context.Context, index string, query map[string]interface{},
}
// SimpleSearch 简单搜索match 查询)
func SimpleSearch(ctx context.Context, index, field, value string, from, size int) (map[string]interface{}, error) {
query := map[string]interface{}{
"match": map[string]interface{}{
func SimpleSearch(ctx context.Context, index, field, value string, from, size int) (map[string]any, error) {
query := map[string]any{
"match": map[string]any{
field: value,
},
}
@ -103,15 +102,405 @@ func SimpleSearch(ctx context.Context, index, field, value string, from, size in
}
// TermSearch 精确匹配查询
func TermSearch(ctx context.Context, index, field, value string, from, size int) (map[string]interface{}, error) {
query := map[string]interface{}{
"term": map[string]interface{}{
func TermSearch(ctx context.Context, index, field, value string, from, size int) (map[string]any, error) {
query := map[string]any{
"term": map[string]any{
field: value,
},
}
return DSlSearch(ctx, index, query, from, size, nil)
}
type StatisticsOverview struct {
Register int64
TotalRegister int64
Recharge float64
TotalRecharge float64
RechargeUser int64
TotalRechargeUser int64
}
type StatisticsHeatTrend struct {
Key []string
DailyActive []int64
Register []int64
}
func CountStatisticsOverview(appId int, appOpenTime int64, tz string) (*StatisticsOverview, error) {
client, err := GetEsClient()
if err != nil {
return nil, err
}
todayStart, err := GetZeroTimestamp(tz, 0)
if err != nil {
return nil, err
}
now := time.Now().Unix()
if appOpenTime <= 0 {
appOpenTime = todayStart
}
region := GetAppRegion(appId)
query := map[string]any{
"size": 0,
"query": map[string]any{
"bool": map[string]any{
"must": []map[string]any{
{
"term": map[string]any{
"fields.environment": region,
},
},
{
"range": map[string]any{
"game.#timestamp": map[string]any{
"gte": appOpenTime,
"lte": now,
},
},
},
},
},
},
"aggs": map[string]any{
"scopes": map[string]any{
"filters": map[string]any{
"filters": map[string]any{
"today": map[string]any{
"range": map[string]any{
"game.#timestamp": map[string]any{
"gte": todayStart,
"lte": now,
},
},
},
"total": map[string]any{
"range": map[string]any{
"game.#timestamp": map[string]any{
"gte": appOpenTime,
"lte": now,
},
},
},
},
},
"aggs": map[string]any{
"register": map[string]any{
"filter": map[string]any{
"term": map[string]any{
"game.#event_name": "register",
},
},
},
"login": map[string]any{
"filter": map[string]any{
"bool": map[string]any{
"minimum_should_match": 1,
"should": []map[string]any{
{
"term": map[string]any{
"game.#event_name": "Login_log",
},
},
{
"term": map[string]any{
"game.#event_name": "login",
},
},
{
"term": map[string]any{
"game.#event_name": "Login",
},
},
},
},
},
"aggs": map[string]any{
"uid_count": map[string]any{
"cardinality": map[string]any{
"field": "game.#distinct_id.keyword",
},
},
},
},
"pay": map[string]any{
"filter": map[string]any{
"term": map[string]any{
"game.#event_name": "pay",
},
},
"aggs": map[string]any{
"uid_count": map[string]any{
"cardinality": map[string]any{
"field": "game.#distinct_id.keyword",
},
},
"amount_sum": map[string]any{
"sum": map[string]any{
"script": map[string]any{
"source": "double v = 0; if (doc.containsKey('game.properties.price') && !doc['game.properties.price'].empty) { v = doc['game.properties.price'].value; } else if (doc.containsKey('game.properties.Price') && !doc['game.properties.Price'].empty) { v = doc['game.properties.Price'].value; } else if (doc.containsKey('game.properties.amount') && !doc['game.properties.amount'].empty) { v = doc['game.properties.amount'].value; } else if (doc.containsKey('game.properties.pay_amount') && !doc['game.properties.pay_amount'].empty) { v = doc['game.properties.pay_amount'].value; } return v;",
},
},
},
},
},
},
},
},
}
var buf bytes.Buffer
if err := json.NewEncoder(&buf).Encode(query); err != nil {
return nil, fmt.Errorf("编码查询失败: %w", err)
}
res, err := client.Search(
client.Search.WithContext(context.Background()),
client.Search.WithIndex("game-user-log*"),
client.Search.WithBody(&buf),
)
if err != nil {
return nil, fmt.Errorf("执行搜索失败: %w", err)
}
defer res.Body.Close()
if res.IsError() {
bodyBytes, _ := io.ReadAll(res.Body)
return nil, fmt.Errorf("ES 搜索错误 [%s]: %s", res.Status(), string(bodyBytes))
}
var result map[string]any
if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
return nil, fmt.Errorf("解析响应失败: %w", err)
}
overview := &StatisticsOverview{}
aggs, ok := result["aggregations"].(map[string]any)
if !ok {
return overview, nil
}
scopes, ok := aggs["scopes"].(map[string]any)
if !ok {
return overview, nil
}
buckets, ok := scopes["buckets"].(map[string]any)
if !ok {
return overview, nil
}
parseScope := func(scopeName string) (int64, float64, int64, int64) {
scope, ok := buckets[scopeName].(map[string]any)
if !ok {
return 0, 0, 0, 0
}
registerCount := int64(0)
if registerAgg, ok := scope["register"].(map[string]any); ok {
if docCount, ok := registerAgg["doc_count"].(float64); ok {
registerCount = int64(docCount)
}
}
loginUser := int64(0)
if loginAgg, ok := scope["login"].(map[string]any); ok {
if uidCount, ok := loginAgg["uid_count"].(map[string]any); ok {
if value, ok := uidCount["value"].(float64); ok {
loginUser = int64(value)
}
}
}
payAmount := float64(0)
payUser := int64(0)
if payAgg, ok := scope["pay"].(map[string]any); ok {
if amountSum, ok := payAgg["amount_sum"].(map[string]any); ok {
if value, ok := amountSum["value"].(float64); ok {
payAmount = value
}
}
if uidCount, ok := payAgg["uid_count"].(map[string]any); ok {
if value, ok := uidCount["value"].(float64); ok {
payUser = int64(value)
}
}
}
return registerCount, payAmount, payUser, loginUser
}
overview.Register, overview.Recharge, overview.RechargeUser, _ = parseScope("today")
overview.TotalRegister, overview.TotalRecharge, overview.TotalRechargeUser, _ = parseScope("total")
return overview, nil
}
func CountStatisticsHeat7Days(appId int, tz string) (*StatisticsHeatTrend, error) {
client, err := GetEsClient()
if err != nil {
return nil, err
}
start, err := GetZeroTimestamp(tz, -6)
if err != nil {
return nil, err
}
now := time.Now().Unix()
region := GetAppRegion(appId)
dayKeys := make([]string, 0, 7)
dayLabels := make([]string, 0, 7)
dayFilters := make(map[string]any, 7)
for i := -6; i <= 0; i++ {
dayKey, err := GetDateStr(tz, i)
if err != nil {
return nil, err
}
dayStart, err := GetZeroTimestamp(tz, i)
if err != nil {
return nil, err
}
dayEnd := now
if i < 0 {
nextDayStart, err := GetZeroTimestamp(tz, i+1)
if err != nil {
return nil, err
}
dayEnd = nextDayStart - 1
}
dayKeys = append(dayKeys, dayKey)
dayLabels = append(dayLabels, dayKey[5:])
dayFilters[dayKey] = map[string]any{
"range": map[string]any{
"game.#timestamp": map[string]any{
"gte": dayStart,
"lte": dayEnd,
},
},
}
}
query := map[string]any{
"size": 0,
"query": map[string]any{
"bool": map[string]any{
"must": []map[string]any{
{
"term": map[string]any{
"fields.environment": region,
},
},
{
"range": map[string]any{
"game.#timestamp": map[string]any{
"gte": start,
"lte": now,
},
},
},
},
},
},
"aggs": map[string]any{
"days": map[string]any{
"filters": map[string]any{
"filters": dayFilters,
},
"aggs": map[string]any{
"register": map[string]any{
"filter": map[string]any{
"term": map[string]any{
"game.#event_name": "register",
},
},
},
"login": map[string]any{
"filter": map[string]any{
"term": map[string]any{
"game.#event_name.keyword": "Login_log",
},
},
"aggs": map[string]any{
"uid_count": map[string]any{
"cardinality": map[string]any{
"field": "game.#distinct_id.keyword",
},
},
},
},
},
},
},
}
var buf bytes.Buffer
if err := json.NewEncoder(&buf).Encode(query); err != nil {
return nil, fmt.Errorf("编码查询失败: %w", err)
}
res, err := client.Search(
client.Search.WithContext(context.Background()),
client.Search.WithIndex("game-user-log*"),
client.Search.WithBody(&buf),
)
if err != nil {
return nil, fmt.Errorf("执行搜索失败: %w", err)
}
defer res.Body.Close()
if res.IsError() {
bodyBytes, _ := io.ReadAll(res.Body)
return nil, fmt.Errorf("ES 搜索错误 [%s]: %s", res.Status(), string(bodyBytes))
}
var result map[string]any
if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
return nil, fmt.Errorf("解析响应失败: %w", err)
}
registerByDay := make(map[string]int64)
activeByDay := make(map[string]int64)
aggs, _ := result["aggregations"].(map[string]any)
daysAgg, _ := aggs["days"].(map[string]any)
buckets, _ := daysAgg["buckets"].(map[string]any)
for day, b := range buckets {
bucket, ok := b.(map[string]any)
if !ok {
continue
}
if registerAgg, ok := bucket["register"].(map[string]any); ok {
if docCount, ok := registerAgg["doc_count"].(float64); ok {
registerByDay[day] = int64(docCount)
}
}
if loginAgg, ok := bucket["login"].(map[string]any); ok {
if uidCount, ok := loginAgg["uid_count"].(map[string]any); ok {
if value, ok := uidCount["value"].(float64); ok {
activeByDay[day] = int64(value)
}
}
}
}
trend := &StatisticsHeatTrend{
Key: make([]string, 0, 7),
DailyActive: make([]int64, 0, 7),
Register: make([]int64, 0, 7),
}
for idx, day := range dayKeys {
trend.Key = append(trend.Key, dayLabels[idx])
trend.DailyActive = append(trend.DailyActive, activeByDay[day])
trend.Register = append(trend.Register, registerByDay[day])
}
return trend, nil
}
func SearchAssetByUid(app, _uid int, from, size int, start, end int64, itemid int, param string) ([]*Type.AssetData, int64, error) {
defer func() {
if r := recover(); r != nil {
@ -121,25 +510,25 @@ func SearchAssetByUid(app, _uid int, from, size int, start, end int64, itemid in
uid := Int(_uid)
ctx := context.Background()
region := GetAppRegion(app)
mustCondition := []map[string]interface{}{
mustCondition := []map[string]any{
{
"term": map[string]interface{}{
"term": map[string]any{
"game.#distinct_id.keyword": uid,
},
},
{
"term": map[string]interface{}{
"term": map[string]any{
"fields.environment": region,
},
},
{
"term": map[string]interface{}{
"term": map[string]any{
"game.#event_name": "asset_change",
},
},
{
"range": map[string]interface{}{
"game.#timestamp": map[string]interface{}{
"range": map[string]any{
"game.#timestamp": map[string]any{
"gte": start,
"lte": end,
},
@ -147,29 +536,29 @@ func SearchAssetByUid(app, _uid int, from, size int, start, end int64, itemid in
},
}
if itemid != 0 {
mustCondition = append(mustCondition, map[string]interface{}{
"term": map[string]interface{}{
mustCondition = append(mustCondition, map[string]any{
"term": map[string]any{
"game.properties.item_id": itemid,
},
})
}
if param != "" {
mustCondition = append(mustCondition, map[string]interface{}{
"match": map[string]interface{}{
mustCondition = append(mustCondition, map[string]any{
"match": map[string]any{
"game.properties.change_type": param,
},
})
}
query := map[string]interface{}{
"bool": map[string]interface{}{
query := map[string]any{
"bool": map[string]any{
"must": mustCondition,
},
}
// 添加降序排序
sort := []map[string]interface{}{
sort := []map[string]any{
{
"game.#timestamp": map[string]interface{}{
"game.#timestamp": map[string]any{
"order": "desc",
},
},
@ -182,18 +571,18 @@ func SearchAssetByUid(app, _uid int, from, size int, start, end int64, itemid in
// 获取总数
var total int64
hits := result["hits"].(map[string]interface{})
if totalObj, ok := hits["total"].(map[string]interface{}); ok {
hits := result["hits"].(map[string]any)
if totalObj, ok := hits["total"].(map[string]any); ok {
if value, ok := totalObj["value"].(float64); ok {
total = int64(value)
}
}
var assets []*Type.AssetData
for _, hit := range hits["hits"].([]interface{}) {
source := hit.(map[string]interface{})["_source"].(map[string]interface{})
game := source["game"].(map[string]interface{})
properties := game["properties"].(map[string]interface{})
for _, hit := range hits["hits"].([]any) {
source := hit.(map[string]any)["_source"].(map[string]any)
game := source["game"].(map[string]any)
properties := game["properties"].(map[string]any)
hitData := Type.AssetData{
ChangeNum: int(properties["change_num"].(float64)),
ChangeAfter: int(properties["change_after"].(float64)),
@ -216,20 +605,20 @@ func SearchEventByUid(app, _uid int, from, size int, start, end int64, event_nam
uid := Int(_uid)
ctx := context.Background()
region := GetAppRegion(app)
mustConditions := []map[string]interface{}{
mustConditions := []map[string]any{
{
"term": map[string]interface{}{
"term": map[string]any{
"game.#distinct_id.keyword": uid,
},
},
{
"term": map[string]interface{}{
"term": map[string]any{
"fields.environment": region,
},
},
{
"range": map[string]interface{}{
"game.#timestamp": map[string]interface{}{
"range": map[string]any{
"game.#timestamp": map[string]any{
"gte": start,
"lte": end,
},
@ -238,24 +627,24 @@ func SearchEventByUid(app, _uid int, from, size int, start, end int64, event_nam
}
if event_name != "" {
mustConditions = append(mustConditions, map[string]interface{}{
"term": map[string]interface{}{
mustConditions = append(mustConditions, map[string]any{
"term": map[string]any{
"game.#event_name": event_name,
},
})
}
query := map[string]interface{}{
"bool": map[string]interface{}{
query := map[string]any{
"bool": map[string]any{
"must": mustConditions,
"must_not": []map[string]interface{}{
"must_not": []map[string]any{
{
"term": map[string]interface{}{
"term": map[string]any{
"game.#event_name": "asset_change",
},
},
{
"term": map[string]interface{}{
"term": map[string]any{
"game.#event_name": "func_exec_time",
},
},
@ -264,9 +653,9 @@ func SearchEventByUid(app, _uid int, from, size int, start, end int64, event_nam
}
// 添加降序排序
sort := []map[string]interface{}{
sort := []map[string]any{
{
"game.#timestamp": map[string]interface{}{
"game.#timestamp": map[string]any{
"order": "desc",
},
},
@ -278,18 +667,18 @@ func SearchEventByUid(app, _uid int, from, size int, start, end int64, event_nam
// 获取总数
var total int64
hits := result["hits"].(map[string]interface{})
if totalObj, ok := hits["total"].(map[string]interface{}); ok {
hits := result["hits"].(map[string]any)
if totalObj, ok := hits["total"].(map[string]any); ok {
if value, ok := totalObj["value"].(float64); ok {
total = int64(value)
}
}
var assets []*Type.EventData
for _, hit := range hits["hits"].([]interface{}) {
source := hit.(map[string]interface{})["_source"].(map[string]interface{})
game := source["game"].(map[string]interface{})
//properites := game["properties"].(map[string]interface{})
for _, hit := range hits["hits"].([]any) {
source := hit.(map[string]any)["_source"].(map[string]any)
game := source["game"].(map[string]any)
//properites := game["properties"].(map[string]any)
properties_summary := game["properties_summary"].(string)
hitData := Type.EventData{
Event: game["#event_name"].(string),
@ -333,13 +722,13 @@ func SearchLoginCountByUidMonth(app, _uid int, month string) ([]*Type.LoginDaily
monthEnd := monthStart.AddDate(0, 1, 0).Add(-time.Second)
region := GetAppRegion(app)
dailyFilters := make(map[string]interface{})
dailyFilters := make(map[string]any)
for day := monthStart; !day.After(monthEnd); day = day.AddDate(0, 0, 1) {
dayStart := time.Date(day.Year(), day.Month(), day.Day(), 0, 0, 0, 0, loc)
dayEnd := dayStart.AddDate(0, 0, 1).Add(-time.Second)
dailyFilters[dayStart.Format("2006-01-02")] = map[string]interface{}{
"range": map[string]interface{}{
"game.#timestamp": map[string]interface{}{
dailyFilters[dayStart.Format("2006-01-02")] = map[string]any{
"range": map[string]any{
"game.#timestamp": map[string]any{
"gte": dayStart.Unix(),
"lte": dayEnd.Unix(),
},
@ -347,27 +736,27 @@ func SearchLoginCountByUidMonth(app, _uid int, month string) ([]*Type.LoginDaily
}
}
query := map[string]interface{}{
"bool": map[string]interface{}{
"must": []map[string]interface{}{
query := map[string]any{
"bool": map[string]any{
"must": []map[string]any{
{
"term": map[string]interface{}{
"term": map[string]any{
"game.#distinct_id.keyword": uid,
},
},
{
"term": map[string]interface{}{
"term": map[string]any{
"fields.environment": region,
},
},
{
"term": map[string]interface{}{
"term": map[string]any{
"game.#event_name.keyword": "Login_log",
},
},
{
"range": map[string]interface{}{
"game.#timestamp": map[string]interface{}{
"range": map[string]any{
"game.#timestamp": map[string]any{
"gte": monthStart.Unix(),
"lte": monthEnd.Unix(),
},
@ -382,12 +771,12 @@ func SearchLoginCountByUidMonth(app, _uid int, month string) ([]*Type.LoginDaily
return nil, 0, err
}
fullQuery := map[string]interface{}{
fullQuery := map[string]any{
"query": query,
"size": 0,
"aggs": map[string]interface{}{
"daily_login": map[string]interface{}{
"filters": map[string]interface{}{
"aggs": map[string]any{
"daily_login": map[string]any{
"filters": map[string]any{
"filters": dailyFilters,
},
},
@ -415,14 +804,14 @@ func SearchLoginCountByUidMonth(app, _uid int, month string) ([]*Type.LoginDaily
return nil, 0, fmt.Errorf("ES 搜索错误 [%s]: %s", res.Status(), string(bodyBytes))
}
var result map[string]interface{}
var result map[string]any
if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
return nil, 0, fmt.Errorf("解析响应失败: %w", err)
}
var total int64
if hits, ok := result["hits"].(map[string]interface{}); ok {
if totalObj, ok := hits["total"].(map[string]interface{}); ok {
if hits, ok := result["hits"].(map[string]any); ok {
if totalObj, ok := hits["total"].(map[string]any); ok {
if value, ok := totalObj["value"].(float64); ok {
total = int64(value)
}
@ -430,11 +819,11 @@ func SearchLoginCountByUidMonth(app, _uid int, month string) ([]*Type.LoginDaily
}
counts := make(map[string]int64, len(dailyFilters))
if aggregations, ok := result["aggregations"].(map[string]interface{}); ok {
if dailyLogin, ok := aggregations["daily_login"].(map[string]interface{}); ok {
if buckets, ok := dailyLogin["buckets"].(map[string]interface{}); ok {
if aggregations, ok := result["aggregations"].(map[string]any); ok {
if dailyLogin, ok := aggregations["daily_login"].(map[string]any); ok {
if buckets, ok := dailyLogin["buckets"].(map[string]any); ok {
for day, bucket := range buckets {
bucketMap, ok := bucket.(map[string]interface{})
bucketMap, ok := bucket.(map[string]any)
if !ok {
continue
}
@ -488,28 +877,28 @@ func CountDistinctUidLastHour() (int64, int64, error) {
oneDayAgo := (now - 24*3600)
// 构建查询:使用过滤器聚合分别统计两个时间段
query := map[string]interface{}{
"query": map[string]interface{}{
"bool": map[string]interface{}{
"must": []map[string]interface{}{
query := map[string]any{
"query": map[string]any{
"bool": map[string]any{
"must": []map[string]any{
{
"term": map[string]interface{}{
"term": map[string]any{
"fields.region.keyword": "us-newyork",
},
},
},
"should": []map[string]interface{}{
"should": []map[string]any{
{
"range": map[string]interface{}{
"game.#timestamp": map[string]interface{}{
"range": map[string]any{
"game.#timestamp": map[string]any{
"gte": oneHourAgo,
"lte": nowMs,
},
},
},
{
"range": map[string]interface{}{
"game.#timestamp": map[string]interface{}{
"range": map[string]any{
"game.#timestamp": map[string]any{
"gte": oneDayOneHourAgo,
"lte": oneDayAgo,
},
@ -520,36 +909,36 @@ func CountDistinctUidLastHour() (int64, int64, error) {
},
},
"from": 0,
"aggs": map[string]interface{}{
"current_hour": map[string]interface{}{
"filter": map[string]interface{}{
"range": map[string]interface{}{
"game.#timestamp": map[string]interface{}{
"aggs": map[string]any{
"current_hour": map[string]any{
"filter": map[string]any{
"range": map[string]any{
"game.#timestamp": map[string]any{
"gte": oneHourAgo,
"lte": nowMs,
},
},
},
"aggs": map[string]interface{}{
"unique_users": map[string]interface{}{
"cardinality": map[string]interface{}{
"aggs": map[string]any{
"unique_users": map[string]any{
"cardinality": map[string]any{
"field": "game.#distinct_id.keyword",
},
},
},
},
"yesterday_hour": map[string]interface{}{
"filter": map[string]interface{}{
"range": map[string]interface{}{
"game.#timestamp": map[string]interface{}{
"yesterday_hour": map[string]any{
"filter": map[string]any{
"range": map[string]any{
"game.#timestamp": map[string]any{
"gte": oneDayOneHourAgo,
"lte": oneDayAgo,
},
},
},
"aggs": map[string]interface{}{
"unique_users": map[string]interface{}{
"cardinality": map[string]interface{}{
"aggs": map[string]any{
"unique_users": map[string]any{
"cardinality": map[string]any{
"field": "game.#distinct_id.keyword",
},
},
@ -562,7 +951,6 @@ func CountDistinctUidLastHour() (int64, int64, error) {
if err := json.NewEncoder(&buf).Encode(query); err != nil {
return 0, 0, fmt.Errorf("编码查询失败: %w", err)
}
fmt.Printf("%s", buf.String())
res, err := client.Search(
client.Search.WithContext(ctx),
client.Search.WithIndex("game-user-log*"),
@ -579,7 +967,7 @@ func CountDistinctUidLastHour() (int64, int64, error) {
return 0, 0, fmt.Errorf("ES 搜索错误 [%s]: %s", res.Status(), string(bodyBytes))
}
var result map[string]interface{}
var result map[string]any
if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
return 0, 0, fmt.Errorf("解析响应失败: %w", err)
}
@ -587,10 +975,10 @@ func CountDistinctUidLastHour() (int64, int64, error) {
// 从聚合结果中提取去重计数
var currentCount, yesterdayCount int64
if aggregations, ok := result["aggregations"].(map[string]interface{}); ok {
if aggregations, ok := result["aggregations"].(map[string]any); ok {
// 提取当前小时的数据
if currentHour, ok := aggregations["current_hour"].(map[string]interface{}); ok {
if uniqueUsers, ok := currentHour["unique_users"].(map[string]interface{}); ok {
if currentHour, ok := aggregations["current_hour"].(map[string]any); ok {
if uniqueUsers, ok := currentHour["unique_users"].(map[string]any); ok {
if value, ok := uniqueUsers["value"].(float64); ok {
currentCount = int64(value)
}
@ -598,8 +986,8 @@ func CountDistinctUidLastHour() (int64, int64, error) {
}
// 提取昨天同一小时的数据
if yesterdayHour, ok := aggregations["yesterday_hour"].(map[string]interface{}); ok {
if uniqueUsers, ok := yesterdayHour["unique_users"].(map[string]interface{}); ok {
if yesterdayHour, ok := aggregations["yesterday_hour"].(map[string]any); ok {
if uniqueUsers, ok := yesterdayHour["unique_users"].(map[string]any); ok {
if value, ok := uniqueUsers["value"].(float64); ok {
yesterdayCount = int64(value)
}
@ -610,7 +998,7 @@ func CountDistinctUidLastHour() (int64, int64, error) {
return currentCount, yesterdayCount, nil
}
func CountDistinctUidLastHourTest() interface{} {
func CountDistinctUidLastHourTest() any {
defer func() {
if r := recover(); r != nil {
log.Println("Recovered in CountDistinctUidLastHour", r)
@ -633,28 +1021,28 @@ func CountDistinctUidLastHourTest() interface{} {
oneDayAgo := (now - 24*3600)
// 构建查询:使用过滤器聚合分别统计两个时间段
query := map[string]interface{}{
"query": map[string]interface{}{
"bool": map[string]interface{}{
"must": []map[string]interface{}{
query := map[string]any{
"query": map[string]any{
"bool": map[string]any{
"must": []map[string]any{
{
"term": map[string]interface{}{
"term": map[string]any{
"fields.region.keyword": "us-newyork",
},
},
},
"should": []map[string]interface{}{
"should": []map[string]any{
{
"range": map[string]interface{}{
"game.#timestamp": map[string]interface{}{
"range": map[string]any{
"game.#timestamp": map[string]any{
"gte": oneHourAgo,
"lte": nowMs,
},
},
},
{
"range": map[string]interface{}{
"game.#timestamp": map[string]interface{}{
"range": map[string]any{
"game.#timestamp": map[string]any{
"gte": oneDayOneHourAgo,
"lte": oneDayAgo,
},
@ -666,36 +1054,36 @@ func CountDistinctUidLastHourTest() interface{} {
},
"size": 0,
"from": 0,
"aggs": map[string]interface{}{
"current_hour": map[string]interface{}{
"filter": map[string]interface{}{
"range": map[string]interface{}{
"game.#timestamp": map[string]interface{}{
"aggs": map[string]any{
"current_hour": map[string]any{
"filter": map[string]any{
"range": map[string]any{
"game.#timestamp": map[string]any{
"gte": oneHourAgo,
"lte": nowMs,
},
},
},
"aggs": map[string]interface{}{
"unique_users": map[string]interface{}{
"cardinality": map[string]interface{}{
"aggs": map[string]any{
"unique_users": map[string]any{
"cardinality": map[string]any{
"field": "game.#distinct_id.keyword",
},
},
},
},
"yesterday_hour": map[string]interface{}{
"filter": map[string]interface{}{
"range": map[string]interface{}{
"game.#timestamp": map[string]interface{}{
"yesterday_hour": map[string]any{
"filter": map[string]any{
"range": map[string]any{
"game.#timestamp": map[string]any{
"gte": oneDayOneHourAgo,
"lte": oneDayAgo,
},
},
},
"aggs": map[string]interface{}{
"unique_users": map[string]interface{}{
"cardinality": map[string]interface{}{
"aggs": map[string]any{
"unique_users": map[string]any{
"cardinality": map[string]any{
"field": "game.#distinct_id.keyword",
},
},
@ -725,7 +1113,7 @@ func CountDistinctUidLastHourTest() interface{} {
return fmt.Errorf("ES 搜索错误 [%s]: %s", res.Status(), string(bodyBytes))
}
var result map[string]interface{}
var result map[string]any
if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
return fmt.Errorf("解析响应失败: %w", err)
}