feat: nlog, config hot-reload, and concurrency fixes
This commit is contained in:
@@ -3,10 +3,10 @@ package kernel
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/cedar2025/xboard-node/internal/nlog"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
@@ -20,7 +20,7 @@ func LoadCustomConfig(path string) (map[string]any, error) {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
slog.Warn("custom config file not found, skipping", "path", path)
|
||||
nlog.Core().Warn("custom config file not found, skipping", "path", path)
|
||||
return nil, nil
|
||||
}
|
||||
return nil, fmt.Errorf("read custom config %s: %w", path, err)
|
||||
@@ -43,7 +43,7 @@ func LoadCustomConfig(path string) (map[string]any, error) {
|
||||
}
|
||||
}
|
||||
|
||||
slog.Info("loaded custom config", "path", path, "keys", mapKeys(result))
|
||||
nlog.Core().Info("loaded custom config", "path", path, "keys", mapKeys(result))
|
||||
return result, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,12 @@ package geodata
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/cedar2025/xboard-node/internal/nlog"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -49,7 +50,7 @@ func Ensure(dir string, needGeoIP, needGeoSite bool, kernelType string) error {
|
||||
var firstErr error
|
||||
for _, f := range files {
|
||||
if err := ensureFile(dir, f.name, f.url); err != nil {
|
||||
slog.Warn("geo database auto-download failed", "file", f.name, "error", err)
|
||||
nlog.Core().Warn("geo database auto-download failed", "file", f.name, "error", err)
|
||||
if firstErr == nil {
|
||||
firstErr = err
|
||||
}
|
||||
@@ -63,12 +64,12 @@ func ensureFile(dir, name, url string) error {
|
||||
if _, err := os.Stat(dst); err == nil {
|
||||
return nil
|
||||
}
|
||||
slog.Info("geo database missing, downloading automatically", "file", name, "url", url)
|
||||
nlog.Core().Info("geo database missing, downloading automatically", "file", name, "url", url)
|
||||
if err := atomicDownload(dst, url); err != nil {
|
||||
return err
|
||||
}
|
||||
if fi, err := os.Stat(dst); err == nil {
|
||||
slog.Info("geo database ready", "file", name, "size_kb", fi.Size()/1024)
|
||||
nlog.Core().Info("geo database ready", "file", name, "size_kb", fi.Size()/1024)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package singbox
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
@@ -11,6 +10,7 @@ import (
|
||||
|
||||
"github.com/cedar2025/xboard-node/internal/config"
|
||||
"github.com/cedar2025/xboard-node/internal/kernel"
|
||||
"github.com/cedar2025/xboard-node/internal/nlog"
|
||||
"github.com/cedar2025/xboard-node/internal/panel"
|
||||
"github.com/go-viper/mapstructure/v2"
|
||||
)
|
||||
@@ -251,7 +251,7 @@ func buildRoutes(panelRoutes []panel.RouteRule, custom []map[string]any) M {
|
||||
func mergeCustomSingbox(cfg M, kcfg config.KernelConfig) {
|
||||
custom, err := kernel.LoadCustomConfig(kcfg.CustomConfig)
|
||||
if err != nil {
|
||||
slog.Error("failed to load custom sing-box config", "error", err)
|
||||
nlog.Core().Error("failed to load custom sing-box config", "error", err)
|
||||
return
|
||||
}
|
||||
if custom == nil {
|
||||
@@ -427,7 +427,7 @@ func buildShadowsocks(base M, nc *panel.NodeConfig, users []panel.User) M {
|
||||
base["users"] = userList
|
||||
|
||||
if nc.Plugin != "" {
|
||||
slog.Warn("sing-box shadowsocks inbound does not support plugin, ignoring", "plugin", nc.Plugin)
|
||||
nlog.Core().Warn("sing-box shadowsocks inbound does not support plugin, ignoring", "plugin", nc.Plugin)
|
||||
}
|
||||
|
||||
return base
|
||||
|
||||
@@ -3,7 +3,6 @@ package singbox
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net"
|
||||
"sort"
|
||||
"sync"
|
||||
@@ -15,6 +14,8 @@ import (
|
||||
singM "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
"golang.org/x/time/rate"
|
||||
|
||||
"github.com/cedar2025/xboard-node/internal/nlog"
|
||||
)
|
||||
|
||||
const rateLimitThreshold = 64 * 1024
|
||||
@@ -171,7 +172,7 @@ func (t *ConnTracker) RoutedConnection(
|
||||
if dlf := t.deviceLimitFunc.Load(); dlf != nil {
|
||||
if limit, hasLimit := (*dlf)(uuid); hasLimit {
|
||||
if t.checkDeviceGate(us, sourceIP, limit) {
|
||||
slog.Info("singbox: device limit gate-keep, rejecting connection",
|
||||
nlog.Core().Info("singbox: device limit gate-keep, rejecting connection",
|
||||
"user", uuid, "ip", sourceIP, "limit", limit)
|
||||
conn.Close()
|
||||
return conn
|
||||
@@ -197,17 +198,17 @@ func (t *ConnTracker) RoutedConnection(
|
||||
}
|
||||
|
||||
return &trackedConn{
|
||||
Conn: conn,
|
||||
tracker: t,
|
||||
us: us,
|
||||
connID: connID,
|
||||
Conn: conn,
|
||||
tracker: t,
|
||||
us: us,
|
||||
connID: connID,
|
||||
sourceIP: sourceIP,
|
||||
limiter: lim,
|
||||
ctx: ctx,
|
||||
limiter: lim,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
// RoutedPacketConnection wraps a UDP PacketConn with per-user byte counting.
|
||||
// RoutedPacketConnection wraps UDP with per-user counting (UDP not in connMap).
|
||||
func (t *ConnTracker) RoutedPacketConnection(
|
||||
ctx context.Context, conn N.PacketConn,
|
||||
metadata adapter.InboundContext,
|
||||
@@ -221,6 +222,17 @@ func (t *ConnTracker) RoutedPacketConnection(
|
||||
us := t.users[uid]
|
||||
t.usersMu.RUnlock()
|
||||
|
||||
if dlf := t.deviceLimitFunc.Load(); dlf != nil {
|
||||
if limit, hasLimit := (*dlf)(uuid); hasLimit {
|
||||
if t.checkDeviceGate(us, sourceIP, limit) {
|
||||
nlog.Core().Info("singbox: device limit gate-keep, rejecting UDP connection",
|
||||
"user", uuid, "ip", sourceIP, "limit", limit)
|
||||
conn.Close()
|
||||
return conn
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if us != nil {
|
||||
us.addConn(sourceIP)
|
||||
}
|
||||
@@ -372,7 +384,7 @@ func (t *ConnTracker) removeConnRef(connID string) {
|
||||
type trackedConn struct {
|
||||
net.Conn
|
||||
tracker *ConnTracker
|
||||
us *userStats // per-user stats (upload/download atomics + IP tracking)
|
||||
us *userStats // per-user stats (upload/download atomics + IP tracking)
|
||||
connID string
|
||||
sourceIP string
|
||||
limiter *rate.Limiter
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -20,6 +19,7 @@ import (
|
||||
|
||||
"github.com/cedar2025/xboard-node/internal/config"
|
||||
"github.com/cedar2025/xboard-node/internal/kernel"
|
||||
"github.com/cedar2025/xboard-node/internal/nlog"
|
||||
"github.com/cedar2025/xboard-node/internal/panel"
|
||||
)
|
||||
|
||||
@@ -88,7 +88,7 @@ func (s *SingBox) Start(nodeConfig *panel.NodeConfig, users []panel.User, certFi
|
||||
return fmt.Errorf("marshal config: %w", err)
|
||||
}
|
||||
|
||||
slog.Debug("sing-box config generated", "len", len(data))
|
||||
nlog.Core().Debug("sing-box config generated", "len", len(data))
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx = include.Context(ctx)
|
||||
@@ -147,7 +147,7 @@ func (s *SingBox) Start(nodeConfig *panel.NodeConfig, users []panel.User, certFi
|
||||
go recycleOldBox(oldBox, oldCancel, oldCtx, oldTracker)
|
||||
}
|
||||
|
||||
slog.Debug("sing-box started", "users", len(users))
|
||||
nlog.Core().Debug("sing-box started", "users", len(users))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ func recycleOldBox(oldBox *box.Box, oldCancel context.CancelFunc, oldCtx context
|
||||
if oldCancel != nil {
|
||||
oldCancel()
|
||||
}
|
||||
slog.Debug("sing-box: old instance recycled")
|
||||
nlog.Core().Debug("sing-box: old instance recycled")
|
||||
}
|
||||
|
||||
// Reload hot-swaps the inbound users and routing rules without restarting the box.
|
||||
@@ -213,9 +213,9 @@ func (s *SingBox) Reload(nodeConfig *panel.NodeConfig, users []panel.User, certF
|
||||
|
||||
// Update routing rules
|
||||
if err := router.UpdateRules(opts.Route.Rules, opts.Route.RuleSet); err != nil {
|
||||
slog.Debug("routing reload failed", "error", err)
|
||||
nlog.Core().Debug("routing reload failed", "error", err)
|
||||
} else {
|
||||
slog.Debug("sing-box routing reloaded")
|
||||
nlog.Core().Debug("sing-box routing reloaded")
|
||||
}
|
||||
|
||||
nopFactory := singLog.NewNOPFactory()
|
||||
@@ -270,7 +270,7 @@ func (s *SingBox) Reload(nodeConfig *panel.NodeConfig, users []panel.User, certF
|
||||
if err == nil {
|
||||
continue
|
||||
}
|
||||
slog.Warn("incremental update failed, falling back to recreate", "tag", tag, "error", err)
|
||||
nlog.Core().Warn("incremental update failed, falling back to recreate", "tag", tag, "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ func (s *SingBox) Reload(nodeConfig *panel.NodeConfig, users []panel.User, certF
|
||||
s.connTracker.SetUserMap(buildUserMap(users))
|
||||
}
|
||||
|
||||
slog.Debug("sing-box reloaded", "users", len(users))
|
||||
nlog.Core().Debug("sing-box reloaded", "users", len(users))
|
||||
s.users = users
|
||||
s.nodeConfig = nodeConfig
|
||||
s.certFile = certFile
|
||||
@@ -559,7 +559,7 @@ func (s *SingBox) reloadInboundsLocked(users []panel.User) error {
|
||||
if err == nil {
|
||||
continue
|
||||
}
|
||||
slog.Warn("incremental update failed, recreating inbound", "tag", tag, "error", err)
|
||||
nlog.Core().Warn("incremental update failed, recreating inbound", "tag", tag, "error", err)
|
||||
}
|
||||
|
||||
_ = im.Remove(tag)
|
||||
@@ -573,7 +573,7 @@ func (s *SingBox) reloadInboundsLocked(users []panel.User) error {
|
||||
s.connTracker.SetUserMap(buildUserMap(users))
|
||||
}
|
||||
|
||||
slog.Debug("sing-box users hot-swapped", "users", len(users))
|
||||
nlog.Core().Debug("sing-box users hot-swapped", "users", len(users))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -594,7 +594,7 @@ func (s *SingBox) CloseConnection(_ context.Context, connID string) error {
|
||||
return fmt.Errorf("not running")
|
||||
}
|
||||
if !ct.CloseByID(connID) {
|
||||
slog.Debug("CloseConnection: connection not found (already closed?)", "id", connID)
|
||||
nlog.Core().Debug("CloseConnection: connection not found (already closed?)", "id", connID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -3,11 +3,11 @@ package xray
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
|
||||
"github.com/cedar2025/xboard-node/internal/config"
|
||||
"github.com/cedar2025/xboard-node/internal/kernel"
|
||||
"github.com/cedar2025/xboard-node/internal/nlog"
|
||||
"github.com/cedar2025/xboard-node/internal/panel"
|
||||
)
|
||||
|
||||
@@ -70,7 +70,7 @@ func buildConfig(kcfg config.KernelConfig, nc *panel.NodeConfig, users []panel.U
|
||||
if inbound != nil {
|
||||
cfg["inbounds"] = []M{inbound}
|
||||
} else {
|
||||
slog.Warn("xray: unsupported protocol, no inbound configured — node will not accept connections",
|
||||
nlog.Core().Warn("xray: unsupported protocol, no inbound configured — node will not accept connections",
|
||||
"protocol", nc.Protocol,
|
||||
"supported", "vmess, vless, trojan, shadowsocks, socks, http")
|
||||
}
|
||||
@@ -116,7 +116,7 @@ func mergeRouteList(a, b []map[string]any) []map[string]any {
|
||||
func mergeCustomXray(cfg M, kcfg config.KernelConfig) {
|
||||
custom, err := kernel.LoadCustomConfig(kcfg.CustomConfig)
|
||||
if err != nil {
|
||||
slog.Error("failed to load custom xray config", "error", err)
|
||||
nlog.Core().Error("failed to load custom xray config", "error", err)
|
||||
return
|
||||
}
|
||||
if custom == nil {
|
||||
|
||||
@@ -3,7 +3,6 @@ package xray
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"reflect"
|
||||
"sort"
|
||||
"sync"
|
||||
@@ -18,6 +17,8 @@ import (
|
||||
"github.com/xtls/xray-core/features/routing"
|
||||
"github.com/xtls/xray-core/transport"
|
||||
"golang.org/x/time/rate"
|
||||
|
||||
"github.com/cedar2025/xboard-node/internal/nlog"
|
||||
)
|
||||
|
||||
// Access xray's internal config creator registry so we can replace the
|
||||
@@ -54,7 +55,7 @@ func limitDispatcherFactory(ctx context.Context, config interface{}) (interface{
|
||||
limitedIPs: make(map[string]map[string]int),
|
||||
}
|
||||
globalLimitDispatcher.Store(ld)
|
||||
slog.Debug("xray: limit dispatcher installed")
|
||||
nlog.Core().Debug("xray: limit dispatcher installed")
|
||||
return ld, nil
|
||||
}
|
||||
|
||||
@@ -158,7 +159,7 @@ func (d *LimitDispatcher) identifyAndCheck(ctx context.Context, dest net.Destina
|
||||
isTCP = dest.Network == net.Network_TCP
|
||||
|
||||
if d.checkDeviceLimit(email, sourceIP, isTCP) {
|
||||
slog.Info("xray: device limit exceeded", "email", email, "ip", sourceIP)
|
||||
nlog.Core().Info("xray: device limit exceeded", "email", email, "ip", sourceIP)
|
||||
return "", "", false, errors.New("device limit exceeded for " + email)
|
||||
}
|
||||
return email, sourceIP, isTCP, nil
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -32,6 +31,7 @@ import (
|
||||
"github.com/cedar2025/xboard-node/internal/config"
|
||||
"github.com/cedar2025/xboard-node/internal/kernel"
|
||||
"github.com/cedar2025/xboard-node/internal/kernel/geodata"
|
||||
"github.com/cedar2025/xboard-node/internal/nlog"
|
||||
"github.com/cedar2025/xboard-node/internal/panel"
|
||||
)
|
||||
|
||||
@@ -153,7 +153,7 @@ func (x *Xray) Start(nodeConfig *panel.NodeConfig, users []panel.User, certFile,
|
||||
|
||||
x.updateDispatcherLimits(users)
|
||||
|
||||
slog.Info("xray started",
|
||||
nlog.Core().Info("xray started",
|
||||
"users", len(users),
|
||||
"protocol", nodeConfig.Protocol,
|
||||
)
|
||||
@@ -174,12 +174,12 @@ func (x *Xray) Reload(nodeConfig *panel.NodeConfig, users []panel.User, certFile
|
||||
if same {
|
||||
x.users = users
|
||||
x.mu.Unlock()
|
||||
slog.Debug("xray: limits updated, kernel configuration unchanged")
|
||||
nlog.Core().Debug("xray: limits updated, kernel configuration unchanged")
|
||||
return nil
|
||||
}
|
||||
x.mu.Unlock()
|
||||
|
||||
slog.Info("xray: configuration changed, performing full restart")
|
||||
nlog.Core().Info("xray: configuration changed, performing full restart")
|
||||
return x.Start(nodeConfig, users, certFile, keyFile)
|
||||
}
|
||||
|
||||
@@ -220,8 +220,10 @@ func (x *Xray) GetUserTraffic(_ context.Context) (traffic map[int][2]int64, aliv
|
||||
return traffic, aliveIPs, connCount, nil
|
||||
}
|
||||
|
||||
// Fallback: read xray's native stats counters
|
||||
// Fallback path: aggregateStats needs x.mu.
|
||||
x.mu.Lock()
|
||||
traffic, err = x.aggregateStats()
|
||||
x.mu.Unlock()
|
||||
return traffic, nil, 0, err
|
||||
}
|
||||
|
||||
@@ -289,7 +291,7 @@ func (x *Xray) AddUsers(users []panel.User) (int, error) {
|
||||
// Protocol doesn't support UserManager → full restart
|
||||
nc, cf, kf := x.nodeConfig, x.certFile, x.keyFile
|
||||
x.mu.Unlock()
|
||||
slog.Debug("xray: AddUsers fallback to restart", "reason", err)
|
||||
nlog.Core().Debug("xray: AddUsers fallback to restart", "reason", err)
|
||||
if err := x.Start(nc, merged, cf, kf); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -305,11 +307,11 @@ func (x *Xray) AddUsers(users []panel.User) (int, error) {
|
||||
for _, u := range toAdd {
|
||||
mu, err := toMemoryUser(proto, nc, u)
|
||||
if err != nil {
|
||||
slog.Warn("xray: skip user, cannot build account", "user", u.ID, "error", err)
|
||||
nlog.Core().Warn("xray: skip user, cannot build account", "user", u.ID, "error", err)
|
||||
continue
|
||||
}
|
||||
if err := um.AddUser(ctx, mu); err != nil {
|
||||
slog.Warn("xray: AddUser failed", "user", u.ID, "error", err)
|
||||
nlog.Core().Warn("xray: AddUser failed", "user", u.ID, "error", err)
|
||||
continue
|
||||
}
|
||||
added++
|
||||
@@ -321,7 +323,7 @@ func (x *Xray) AddUsers(users []panel.User) (int, error) {
|
||||
x.mu.Unlock()
|
||||
x.updateDispatcherLimits(merged)
|
||||
|
||||
slog.Info("xray: users added via UserManager", "added", added, "total", len(merged))
|
||||
nlog.Core().Info("xray: users added via UserManager", "added", added, "total", len(merged))
|
||||
return added, nil
|
||||
}
|
||||
|
||||
@@ -361,7 +363,7 @@ func (x *Xray) RemoveUsers(users []panel.User) (int, error) {
|
||||
if err != nil {
|
||||
nc, cf, kf := x.nodeConfig, x.certFile, x.keyFile
|
||||
x.mu.Unlock()
|
||||
slog.Debug("xray: RemoveUsers fallback to restart", "reason", err)
|
||||
nlog.Core().Debug("xray: RemoveUsers fallback to restart", "reason", err)
|
||||
if err := x.Start(nc, kept, cf, kf); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -374,7 +376,7 @@ func (x *Xray) RemoveUsers(users []panel.User) (int, error) {
|
||||
for _, u := range users {
|
||||
email := userEmail(u.ID)
|
||||
if err := um.RemoveUser(ctx, email); err != nil {
|
||||
slog.Debug("xray: RemoveUser skipped", "user", u.ID, "error", err)
|
||||
nlog.Core().Debug("xray: RemoveUser skipped", "user", u.ID, "error", err)
|
||||
continue
|
||||
}
|
||||
actualRemoved++
|
||||
@@ -385,7 +387,7 @@ func (x *Xray) RemoveUsers(users []panel.User) (int, error) {
|
||||
x.mu.Unlock()
|
||||
x.updateDispatcherLimits(kept)
|
||||
|
||||
slog.Info("xray: users removed via UserManager", "removed", actualRemoved, "total", len(kept))
|
||||
nlog.Core().Info("xray: users removed via UserManager", "removed", actualRemoved, "total", len(kept))
|
||||
return actualRemoved, nil
|
||||
}
|
||||
|
||||
@@ -406,7 +408,7 @@ func (x *Xray) UpdateUsers(users []panel.User) (added, removed int, err error) {
|
||||
x.users = users
|
||||
x.mu.Unlock()
|
||||
x.updateDispatcherLimits(users)
|
||||
slog.Info("xray: limits updated, kernel unchanged")
|
||||
nlog.Core().Info("xray: limits updated, kernel unchanged")
|
||||
return 0, 0, nil
|
||||
}
|
||||
|
||||
@@ -415,7 +417,7 @@ func (x *Xray) UpdateUsers(users []panel.User) (added, removed int, err error) {
|
||||
// Protocol doesn't support UserManager → full restart
|
||||
nc, cf, kf := x.nodeConfig, x.certFile, x.keyFile
|
||||
x.mu.Unlock()
|
||||
slog.Debug("xray: UpdateUsers fallback to restart", "reason", umErr)
|
||||
nlog.Core().Debug("xray: UpdateUsers fallback to restart", "reason", umErr)
|
||||
if err = x.Start(nc, users, cf, kf); err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
@@ -432,17 +434,17 @@ func (x *Xray) UpdateUsers(users []panel.User) (added, removed int, err error) {
|
||||
for _, u := range toRemove {
|
||||
email := userEmail(u.ID)
|
||||
if err := um.RemoveUser(ctx, email); err != nil {
|
||||
slog.Debug("xray: RemoveUser skipped in UpdateUsers", "user", u.ID, "error", err)
|
||||
nlog.Core().Debug("xray: RemoveUser skipped in UpdateUsers", "user", u.ID, "error", err)
|
||||
}
|
||||
}
|
||||
for _, u := range toAdd {
|
||||
mu, err := toMemoryUser(proto, nc, u)
|
||||
if err != nil {
|
||||
slog.Warn("xray: skip user in UpdateUsers", "user", u.ID, "error", err)
|
||||
nlog.Core().Warn("xray: skip user in UpdateUsers", "user", u.ID, "error", err)
|
||||
continue
|
||||
}
|
||||
if err := um.AddUser(ctx, mu); err != nil {
|
||||
slog.Warn("xray: AddUser failed in UpdateUsers", "user", u.ID, "error", err)
|
||||
nlog.Core().Warn("xray: AddUser failed in UpdateUsers", "user", u.ID, "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,7 +453,7 @@ func (x *Xray) UpdateUsers(users []panel.User) (added, removed int, err error) {
|
||||
x.mu.Unlock()
|
||||
x.updateDispatcherLimits(users)
|
||||
|
||||
slog.Info("xray: users updated via UserManager", "added", added, "removed", removed, "total", len(users))
|
||||
nlog.Core().Info("xray: users updated via UserManager", "added", added, "removed", removed, "total", len(users))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -597,7 +599,7 @@ func (x *Xray) ensureGeoData(nc *panel.NodeConfig) {
|
||||
}
|
||||
dir := x.cfg.GeoDataDir
|
||||
if err := geodata.Ensure(dir, needIP, needSite, "xray"); err != nil {
|
||||
slog.Warn("geo database unavailable", "error", err)
|
||||
nlog.Core().Warn("geo database unavailable", "error", err)
|
||||
}
|
||||
os.Setenv("XRAY_LOCATION_ASSET", dir)
|
||||
}
|
||||
@@ -609,7 +611,7 @@ func marshalConfig(cfg config.KernelConfig, nc *panel.NodeConfig, users []panel.
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("marshal config: %w", err)
|
||||
}
|
||||
slog.Debug("xray config generated", "len", len(data))
|
||||
nlog.Core().Debug("xray config generated", "len", len(data))
|
||||
return data, nil
|
||||
}
|
||||
|
||||
@@ -625,6 +627,7 @@ func startWithTimeout(inst *xrayCore.Instance, timeout time.Duration) error {
|
||||
}
|
||||
return nil
|
||||
case <-time.After(timeout):
|
||||
go inst.Close()
|
||||
return fmt.Errorf("start xray: timeout after %v", timeout)
|
||||
}
|
||||
}
|
||||
@@ -648,7 +651,7 @@ func closeOld(inst *xrayCore.Instance, ld *LimitDispatcher) {
|
||||
if ld != nil {
|
||||
ld.ResetConns()
|
||||
}
|
||||
slog.Debug("xray: old instance recycled")
|
||||
nlog.Core().Debug("xray: old instance recycled")
|
||||
}()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user