You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
3.8 KiB
97 lines
3.8 KiB
package console
|
|
|
|
import (
|
|
"sort"
|
|
"strings"
|
|
|
|
"yunyan/comm"
|
|
"yunyan/lego/sys/log"
|
|
"yunyan/lego/sys/postgres"
|
|
)
|
|
|
|
// ============================ 作用域键一致性巡检(只读,只打日志) ============================
|
|
//
|
|
// 按应用隔离的配置(svc_config / 会议模板 …)用 app_name 当作用域键,而这个键有三个来源,
|
|
// 三者必须是同一个字符串,错一个就会「后台改半天不生效」或「后台整页空白」,且**不报任何错**:
|
|
//
|
|
// ① 业务部署 .env 的 ANALYZE_APP_NAME —— 运行时 comm.AppName(),决定客户端读哪一套;
|
|
// ② 应用注册表 app_registry.app_name —— 迁移/复制/后台下拉用它;
|
|
// ③ 应用注册表 app_registry.name —— 统计落库认它(console.stat 的 getAppByName 查的是 name)。
|
|
//
|
|
// 线上真实踩过:测试机 app_registry 是 (name=EAIMAR-TEST, app_name=EAIMAR),而部署的
|
|
// ANALYZE_APP_NAME=EAIMAR-TEST。于是配置全落在 'EAIMAR-TEST' 作用域(客户端读得到),
|
|
// 后台下拉给出的却是 'EAIMAR'(app_name||name)→ 选它看到的是空页面,在那里新建的服务
|
|
// 客户端一个都读不到。两边都不报错,只有对着库查才看得出来。
|
|
//
|
|
// 巡检不改数据(作用域键是运维决定的,自动改名可能把线上配置搬到没人读的地方),
|
|
// 只把对不上的地方点名打出来。
|
|
func checkScopeConsistency(apps []*AppRegistry) {
|
|
known := map[string]bool{} // 注册表认得的作用域键(app_name 与 name 都算)
|
|
declared := map[string]bool{} // 后台下拉会给出的键(前端取 app_name||name,与它一致)
|
|
for _, a := range apps {
|
|
if !a.Enabled {
|
|
continue
|
|
}
|
|
n, an := strings.TrimSpace(a.Name), strings.TrimSpace(a.AppName)
|
|
if n != "" {
|
|
known[n] = true
|
|
}
|
|
if an != "" {
|
|
known[an] = true
|
|
}
|
|
if an != "" && n != "" && an != n {
|
|
log.Warnf("console.scope: 应用注册表 id=%d 的 name(%q) 与 app_name(%q) 不同值——"+
|
|
"配置作用域、后台下拉、统计落库三者会各认一个,务必改成同值(见 comm/appscope.go)", a.Id, n, an)
|
|
}
|
|
if d := an; d != "" {
|
|
declared[d] = true
|
|
} else if n != "" {
|
|
declared[n] = true
|
|
}
|
|
}
|
|
if len(known) == 0 {
|
|
return
|
|
}
|
|
|
|
for _, table := range []string{comm.TableSvcConfig, comm.TableEchomeetTemplate} {
|
|
var scopes []string
|
|
if err := postgres.Table(table).Group("app_name").Pluck("app_name", &scopes).Error; err != nil {
|
|
log.Warnf("console.scope: 巡检 %s 的作用域键失败(跳过): %v", table, err)
|
|
continue
|
|
}
|
|
orphan := make([]string, 0)
|
|
for _, s := range scopes {
|
|
s = strings.TrimSpace(s)
|
|
if s == "" || known[s] {
|
|
continue
|
|
}
|
|
orphan = append(orphan, s)
|
|
}
|
|
if len(orphan) > 0 {
|
|
sort.Strings(orphan)
|
|
log.Warnf("console.scope: %s 里有配置挂在注册表不认识的作用域 %v ——"+
|
|
"若某个业务部署的 ANALYZE_APP_NAME 正是它,那套配置正在生效却在后台**看不到也改不了**;"+
|
|
"对齐办法是把 app_registry 的 name/app_name 都改成这个值(不要改业务部署的 .env,"+
|
|
"那会让客户端立刻读到另一套配置)", table, orphan)
|
|
}
|
|
// 反向:后台下拉会给出、但库里一行配置都没有的作用域——选中它就是空白页。
|
|
empty := make([]string, 0)
|
|
for d := range declared {
|
|
found := false
|
|
for _, s := range scopes {
|
|
if strings.TrimSpace(s) == d {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
empty = append(empty, d)
|
|
}
|
|
}
|
|
if len(empty) > 0 && len(orphan) > 0 {
|
|
sort.Strings(empty)
|
|
log.Warnf("console.scope: %s 里作用域 %v 一行都没有,而后台下拉正会给出它们——"+
|
|
"配合上面那条孤儿作用域看,多半是同一个应用的两个名字", table, empty)
|
|
}
|
|
}
|
|
}
|
|
|