Files
MeBox/internal/service/boot_cloud_health.go
T

103 lines
3.1 KiB
Go

package service
import (
"context"
"strings"
"time"
"go.uber.org/zap"
)
const cloudStorageMissingConfigWarnPrefix = "cloud.storage.missing_config_warned."
// BootCloudStorageHealthCheck验证所有已配置的云盘存储在启动时是否可用
func (c *Container) BootCloudStorageHealthCheck(ctx context.Context) {
if c == nil || c.StorageCfg == nil {
return
}
configs, err := c.StorageCfg.List(ctx)
if err != nil {
c.Log.Warn("boot: cloud storage health check failed to list configs", zap.Error(err))
return
}
cloudConfigs := make([]StorageView, 0)
for _, cfg := range configs {
if cfg.Enabled && IsAdminCloudConfigurable(cfg.Type) {
cloudConfigs = append(cloudConfigs, cfg)
}
}
if len(cloudConfigs) == 0 {
c.Log.Info("boot: no enabled cloud storage configured")
return
}
c.Log.Info("boot: checking cloud storage health", zap.Int("count", len(cloudConfigs)))
for _, cfg := range cloudConfigs {
go func(typ string) {
checkCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
provider, err := c.StorageCfg.CloudProvider(checkCtx, typ)
if err != nil {
if c.warnMissingCloudStorageConfigOnce(checkCtx, typ, err) {
return
}
c.Log.Warn("boot: cloud storage unavailable", zap.String("type", typ), zap.Error(err))
return
}
if err := provider.Ping(checkCtx); err != nil {
if c.warnMissingCloudStorageConfigOnce(checkCtx, typ, err) {
return
}
c.Log.Warn("boot: cloud storage ping failed", zap.String("type", typ), zap.Error(err))
} else {
c.Log.Info("boot: cloud storage healthy", zap.String("type", typ))
}
}(cfg.Type)
}
}
func (c *Container) warnMissingCloudStorageConfigOnce(ctx context.Context, typ string, err error) bool {
reason := cloudStorageMissingConfigReason(err)
if reason == "" {
return false
}
if c == nil || c.Repo == nil || c.Repo.Setting == nil {
if c != nil && c.Log != nil {
c.Log.Warn("boot: cloud storage config incomplete; skipping health check", zap.String("type", typ), zap.String("reason", reason), zap.Error(err))
}
return true
}
key := cloudStorageMissingConfigWarnPrefix + strings.TrimSpace(typ) + "." + reason
if value, getErr := c.Repo.Setting.Get(ctx, key); getErr == nil && strings.EqualFold(strings.TrimSpace(value), "true") {
return true
}
if c.Log != nil {
c.Log.Warn("boot: cloud storage config incomplete; skipping health check", zap.String("type", typ), zap.String("reason", reason), zap.Error(err))
}
if setErr := c.Repo.Setting.Set(ctx, key, "true"); setErr != nil && c.Log != nil {
c.Log.Debug("remember cloud storage config warning failed", zap.String("type", typ), zap.Error(setErr))
}
return true
}
func cloudStorageMissingConfigReason(err error) string {
if err == nil {
return ""
}
msg := strings.ToLower(strings.TrimSpace(err.Error()))
switch {
case strings.Contains(msg, "missing cookie") || (strings.Contains(msg, "missing") && strings.Contains(msg, "cookie")):
return "missing_cookie"
case strings.Contains(msg, "missing webdav url"):
return "missing_webdav_url"
default:
return ""
}
}