diff --git a/outlinecaddy/app.go b/outlinecaddy/app.go index 73c51a95..fa4b8d7d 100644 --- a/outlinecaddy/app.go +++ b/outlinecaddy/app.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" "log/slog" + "strings" outline_prometheus "github.com/Jigsaw-Code/outline-ss-server/prometheus" outline "github.com/Jigsaw-Code/outline-ss-server/service" @@ -127,7 +128,8 @@ func (app *OutlineApp) defineMetrics() error { func registerCollector[T prometheus.Collector](registerer prometheus.Registerer, coll T) (T, error) { if err := registerer.Register(coll); err != nil { are := &prometheus.AlreadyRegisteredError{} - if !errors.As(err, are) { + dupeErr := strings.Contains(err.Error(), "duplicate metrics collector registration attempted") + if !errors.As(err, are) || dupeErr { // This collector has been registered before. This is expected during a config reload. coll = are.ExistingCollector.(T) } else { diff --git a/service/shadowsocks.go b/service/shadowsocks.go index 75bfe245..668da1c8 100644 --- a/service/shadowsocks.go +++ b/service/shadowsocks.go @@ -63,9 +63,17 @@ func NewShadowsocksHandlers(opts ...Option) (StreamHandler, AssociationHandler) opt(s) } + var ( + tcpShadowsocksConnMetrics ShadowsocksConnMetrics + udpShadowsocksConnMetrics ShadowsocksConnMetrics + ) + if s.metrics != nil { + tcpShadowsocksConnMetrics = &ssConnMetrics{s.metrics.AddTCPCipherSearch} + udpShadowsocksConnMetrics = &ssConnMetrics{s.metrics.AddUDPCipherSearch} + } // TODO: Register initial data metrics at zero. sh := NewStreamHandler( - NewShadowsocksStreamAuthenticator(s.ciphers, s.replayCache, &ssConnMetrics{s.metrics.AddTCPCipherSearch}, s.logger), + NewShadowsocksStreamAuthenticator(s.ciphers, s.replayCache, tcpShadowsocksConnMetrics, s.logger), tcpReadTimeout, ) if s.streamDialer != nil { @@ -73,7 +81,7 @@ func NewShadowsocksHandlers(opts ...Option) (StreamHandler, AssociationHandler) } sh.SetLogger(s.logger) - ah := NewAssociationHandler(s.ciphers, &ssConnMetrics{s.metrics.AddUDPCipherSearch}) + ah := NewAssociationHandler(s.ciphers, udpShadowsocksConnMetrics) if s.packetListener != nil { ah.SetTargetPacketListener(s.packetListener) }