浏览代码

Refactor log (#3446)

* Refactor log

* Add new log methods

* Fix logger test

* Change all logging code

* Clean up pathObj

* Rebase to latest main

* Remove invoking method name after the dot
yuhan6665 1 年之前
父节点
当前提交
079d0bd8a9
共有 100 个文件被更改,包括 560 次插入728 次删除
  1. 6 5
      app/commander/commander.go
  2. 0 9
      app/commander/errors.generated.go
  3. 2 1
      app/commander/outbound.go
  4. 13 12
      app/dispatcher/default.go
  5. 0 9
      app/dispatcher/errors.generated.go
  6. 5 4
      app/dispatcher/fakednssniffer.go
  7. 2 1
      app/dispatcher/sniffer.go
  8. 4 3
      app/dns/config.go
  9. 14 14
      app/dns/dns.go
  10. 6 6
      app/dns/dnscommon.go
  11. 0 9
      app/dns/errors.generated.go
  12. 0 9
      app/dns/fakedns/errors.generated.go
  13. 9 8
      app/dns/fakedns/fake.go
  14. 8 5
      app/dns/hosts.go
  15. 11 11
      app/dns/nameserver.go
  16. 13 12
      app/dns/nameserver_doh.go
  17. 4 3
      app/dns/nameserver_fakedns.go
  18. 4 3
      app/dns/nameserver_local.go
  19. 15 14
      app/dns/nameserver_quic.go
  20. 14 13
      app/dns/nameserver_tcp.go
  21. 11 11
      app/dns/nameserver_udp.go
  22. 4 3
      app/log/command/command.go
  23. 0 9
      app/log/command/errors.generated.go
  24. 0 9
      app/log/errors.generated.go
  25. 5 4
      app/log/log.go
  26. 3 2
      app/log/log_creator.go
  27. 0 9
      app/metrics/errors.generated.go
  28. 3 2
      app/metrics/metrics.go
  29. 2 1
      app/metrics/outbound.go
  30. 7 5
      app/observatory/burst/burstobserver.go
  31. 0 9
      app/observatory/burst/errors.generated.go
  32. 9 8
      app/observatory/burst/healthping.go
  33. 0 9
      app/observatory/errors.generated.go
  34. 3 3
      app/observatory/explainErrors.go
  35. 11 14
      app/observatory/observer.go
  36. 0 9
      app/policy/errors.generated.go
  37. 10 9
      app/proxyman/command/command.go
  38. 0 9
      app/proxyman/command/errors.generated.go
  39. 5 5
      app/proxyman/inbound/always.go
  40. 6 5
      app/proxyman/inbound/dynamic.go
  41. 0 9
      app/proxyman/inbound/errors.generated.go
  42. 11 10
      app/proxyman/inbound/inbound.go
  43. 29 27
      app/proxyman/inbound/worker.go
  44. 0 9
      app/proxyman/outbound/errors.generated.go
  45. 22 21
      app/proxyman/outbound/handler.go
  46. 1 1
      app/proxyman/outbound/outbound.go
  47. 3 2
      app/proxyman/outbound/uot.go
  48. 5 4
      app/reverse/bridge.go
  49. 0 9
      app/reverse/errors.generated.go
  50. 13 12
      app/reverse/portal.go
  51. 12 11
      app/router/balancing.go
  52. 3 1
      app/router/balancing_override.go
  53. 9 8
      app/router/command/command.go
  54. 0 9
      app/router/command/errors.generated.go
  55. 4 3
      app/router/condition.go
  56. 8 6
      app/router/config.go
  57. 0 9
      app/router/errors.generated.go
  58. 7 6
      app/router/router.go
  59. 4 3
      app/router/strategy_leastload.go
  60. 2 1
      app/router/strategy_leastping.go
  61. 5 2
      app/router/weight.go
  62. 2 1
      app/stats/channel.go
  63. 3 2
      app/stats/command/command.go
  64. 0 9
      app/stats/command/errors.generated.go
  65. 0 9
      app/stats/errors.generated.go
  66. 7 7
      app/stats/stats.go
  67. 3 2
      common/buf/buffer.go
  68. 1 1
      common/buf/copy.go
  69. 2 2
      common/buf/copy_test.go
  70. 0 9
      common/buf/errors.generated.go
  71. 4 2
      common/buf/io.go
  72. 1 1
      common/buf/reader.go
  73. 5 4
      common/crypto/auth.go
  74. 0 9
      common/crypto/errors.generated.go
  75. 25 0
      common/ctx/context.go
  76. 4 3
      common/drain/drainer.go
  77. 0 9
      common/drain/errors.generated.go
  78. 0 9
      common/errors.generated.go
  79. 0 37
      common/errors/errorgen/main.go
  80. 76 39
      common/errors/errors.go
  81. 2 8
      common/errors/errors_test.go
  82. 11 11
      common/mux/client.go
  83. 0 9
      common/mux/errors.generated.go
  84. 6 5
      common/mux/frame.go
  85. 2 1
      common/mux/reader.go
  86. 13 13
      common/mux/server.go
  87. 4 2
      common/mux/session.go
  88. 4 1
      common/net/address.go
  89. 0 9
      common/net/errors.generated.go
  90. 4 2
      common/net/port.go
  91. 0 9
      common/ocsp/errors.generated.go
  92. 9 8
      common/ocsp/ocsp.go
  93. 6 4
      common/platform/ctlcmd/ctlcmd.go
  94. 0 9
      common/platform/ctlcmd/errors.generated.go
  95. 6 5
      common/protocol/address.go
  96. 0 9
      common/protocol/dns/errors.generated.go
  97. 2 1
      common/protocol/dns/io.go
  98. 0 9
      common/protocol/errors.generated.go
  99. 9 8
      common/protocol/tls/cert/cert.go
  100. 2 1
      common/protocol/tls/cert/cert_test.go

+ 6 - 5
app/commander/commander.go

@@ -8,6 +8,7 @@ import (
 	"sync"
 	"sync"
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/signal/done"
 	"github.com/xtls/xray-core/common/signal/done"
 	core "github.com/xtls/xray-core/core"
 	core "github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/features/outbound"
 	"github.com/xtls/xray-core/features/outbound"
@@ -46,7 +47,7 @@ func NewCommander(ctx context.Context, config *Config) (*Commander, error) {
 		}
 		}
 		service, ok := rawService.(Service)
 		service, ok := rawService.(Service)
 		if !ok {
 		if !ok {
-			return nil, newError("not a Service.")
+			return nil, errors.New("not a Service.")
 		}
 		}
 		c.services = append(c.services, service)
 		c.services = append(c.services, service)
 	}
 	}
@@ -70,16 +71,16 @@ func (c *Commander) Start() error {
 
 
 	var listen = func(listener net.Listener) {
 	var listen = func(listener net.Listener) {
 		if err := c.server.Serve(listener); err != nil {
 		if err := c.server.Serve(listener); err != nil {
-			newError("failed to start grpc server").Base(err).AtError().WriteToLog()
+			errors.LogErrorInner(context.Background(), err, "failed to start grpc server")
 		}
 		}
 	}
 	}
 
 
 	if len(c.listen) > 0 {
 	if len(c.listen) > 0 {
 		if l, err := net.Listen("tcp", c.listen); err != nil {
 		if l, err := net.Listen("tcp", c.listen); err != nil {
-			newError("API server failed to listen on ", c.listen).Base(err).AtError().WriteToLog()
+			errors.LogErrorInner(context.Background(), err, "API server failed to listen on ", c.listen)
 			return err
 			return err
 		} else {
 		} else {
-			newError("API server listening on ", l.Addr()).AtInfo().WriteToLog()
+			errors.LogInfo(context.Background(), "API server listening on ", l.Addr())
 			go listen(l)
 			go listen(l)
 		}
 		}
 		return nil
 		return nil
@@ -93,7 +94,7 @@ func (c *Commander) Start() error {
 	go listen(listener)
 	go listen(listener)
 
 
 	if err := c.ohm.RemoveHandler(context.Background(), c.tag); err != nil {
 	if err := c.ohm.RemoveHandler(context.Background(), c.tag); err != nil {
-		newError("failed to remove existing handler").WriteToLog()
+		errors.LogInfoInner(context.Background(), err, "failed to remove existing handler")
 	}
 	}
 
 
 	return c.ohm.AddHandler(context.Background(), &Outbound{
 	return c.ohm.AddHandler(context.Background(), &Outbound{

+ 0 - 9
app/commander/errors.generated.go

@@ -1,9 +0,0 @@
-package commander
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 2 - 1
app/commander/outbound.go

@@ -5,6 +5,7 @@ import (
 	"sync"
 	"sync"
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net/cnc"
 	"github.com/xtls/xray-core/common/net/cnc"
 	"github.com/xtls/xray-core/common/signal/done"
 	"github.com/xtls/xray-core/common/signal/done"
@@ -31,7 +32,7 @@ func (l *OutboundListener) add(conn net.Conn) {
 func (l *OutboundListener) Accept() (net.Conn, error) {
 func (l *OutboundListener) Accept() (net.Conn, error) {
 	select {
 	select {
 	case <-l.done.Wait():
 	case <-l.done.Wait():
-		return nil, newError("listen closed")
+		return nil, errors.New("listen closed")
 	case c := <-l.buffer:
 	case c := <-l.buffer:
 		return c, nil
 		return c, nil
 	}
 	}

+ 13 - 12
app/dispatcher/default.go

@@ -10,6 +10,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/buf"
 	"github.com/xtls/xray-core/common/buf"
 	"github.com/xtls/xray-core/common/log"
 	"github.com/xtls/xray-core/common/log"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
@@ -26,7 +27,7 @@ import (
 	"github.com/xtls/xray-core/transport/pipe"
 	"github.com/xtls/xray-core/transport/pipe"
 )
 )
 
 
-var errSniffingTimeout = newError("timeout on sniffing")
+var errSniffingTimeout = errors.New("timeout on sniffing")
 
 
 type cachedReader struct {
 type cachedReader struct {
 	sync.Mutex
 	sync.Mutex
@@ -191,7 +192,7 @@ func (d *DefaultDispatcher) shouldOverride(ctx context.Context, result SniffResu
 			pattern := d[7:]
 			pattern := d[7:]
 			re, err := regexp.Compile(pattern)
 			re, err := regexp.Compile(pattern)
 			if err != nil {
 			if err != nil {
-				newError("Unable to compile regex").WriteToLog(session.ExportIDToError(ctx))
+				errors.LogInfo(ctx, "Unable to compile regex")
 				continue
 				continue
 			}
 			}
 			if re.MatchString(domain) {
 			if re.MatchString(domain) {
@@ -213,7 +214,7 @@ func (d *DefaultDispatcher) shouldOverride(ctx context.Context, result SniffResu
 		}
 		}
 		if fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok && protocolString != "bittorrent" && p == "fakedns" &&
 		if fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok && protocolString != "bittorrent" && p == "fakedns" &&
 			fkr0.IsIPInIPPool(destination.Address) {
 			fkr0.IsIPInIPPool(destination.Address) {
-			newError("Using sniffer ", protocolString, " since the fake DNS missed").WriteToLog(session.ExportIDToError(ctx))
+			errors.LogInfo(ctx, "Using sniffer ", protocolString, " since the fake DNS missed")
 			return true
 			return true
 		}
 		}
 		if resultSubset, ok := result.(SnifferIsProtoSubsetOf); ok {
 		if resultSubset, ok := result.(SnifferIsProtoSubsetOf); ok {
@@ -261,7 +262,7 @@ func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destin
 			}
 			}
 			if err == nil && d.shouldOverride(ctx, result, sniffingRequest, destination) {
 			if err == nil && d.shouldOverride(ctx, result, sniffingRequest, destination) {
 				domain := result.Domain()
 				domain := result.Domain()
-				newError("sniffed domain: ", domain).WriteToLog(session.ExportIDToError(ctx))
+				errors.LogInfo(ctx, "sniffed domain: ", domain)
 				destination.Address = net.ParseAddress(domain)
 				destination.Address = net.ParseAddress(domain)
 				protocol := result.Protocol()
 				protocol := result.Protocol()
 				if resComp, ok := result.(SnifferResultComposite); ok {
 				if resComp, ok := result.(SnifferResultComposite); ok {
@@ -286,7 +287,7 @@ func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destin
 // DispatchLink implements routing.Dispatcher.
 // DispatchLink implements routing.Dispatcher.
 func (d *DefaultDispatcher) DispatchLink(ctx context.Context, destination net.Destination, outbound *transport.Link) error {
 func (d *DefaultDispatcher) DispatchLink(ctx context.Context, destination net.Destination, outbound *transport.Link) error {
 	if !destination.IsValid() {
 	if !destination.IsValid() {
-		return newError("Dispatcher: Invalid destination.")
+		return errors.New("Dispatcher: Invalid destination.")
 	}
 	}
 	outbounds := session.OutboundsFromContext(ctx)
 	outbounds := session.OutboundsFromContext(ctx)
 	if len(outbounds) == 0 {
 	if len(outbounds) == 0 {
@@ -315,7 +316,7 @@ func (d *DefaultDispatcher) DispatchLink(ctx context.Context, destination net.De
 		}
 		}
 		if err == nil && d.shouldOverride(ctx, result, sniffingRequest, destination) {
 		if err == nil && d.shouldOverride(ctx, result, sniffingRequest, destination) {
 			domain := result.Domain()
 			domain := result.Domain()
-			newError("sniffed domain: ", domain).WriteToLog(session.ExportIDToError(ctx))
+			errors.LogInfo(ctx, "sniffed domain: ", domain)
 			destination.Address = net.ParseAddress(domain)
 			destination.Address = net.ParseAddress(domain)
 			protocol := result.Protocol()
 			protocol := result.Protocol()
 			if resComp, ok := result.(SnifferResultComposite); ok {
 			if resComp, ok := result.(SnifferResultComposite); ok {
@@ -407,10 +408,10 @@ func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.
 		ctx = session.SetForcedOutboundTagToContext(ctx, "")
 		ctx = session.SetForcedOutboundTagToContext(ctx, "")
 		if h := d.ohm.GetHandler(forcedOutboundTag); h != nil {
 		if h := d.ohm.GetHandler(forcedOutboundTag); h != nil {
 			isPickRoute = 1
 			isPickRoute = 1
-			newError("taking platform initialized detour [", forcedOutboundTag, "] for [", destination, "]").WriteToLog(session.ExportIDToError(ctx))
+			errors.LogInfo(ctx, "taking platform initialized detour [", forcedOutboundTag, "] for [", destination, "]")
 			handler = h
 			handler = h
 		} else {
 		} else {
-			newError("non existing tag for platform initialized detour: ", forcedOutboundTag).AtError().WriteToLog(session.ExportIDToError(ctx))
+			errors.LogError(ctx, "non existing tag for platform initialized detour: ", forcedOutboundTag)
 			common.Close(link.Writer)
 			common.Close(link.Writer)
 			common.Interrupt(link.Reader)
 			common.Interrupt(link.Reader)
 			return
 			return
@@ -420,13 +421,13 @@ func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.
 			outTag := route.GetOutboundTag()
 			outTag := route.GetOutboundTag()
 			if h := d.ohm.GetHandler(outTag); h != nil {
 			if h := d.ohm.GetHandler(outTag); h != nil {
 				isPickRoute = 2
 				isPickRoute = 2
-				newError("taking detour [", outTag, "] for [", destination, "]").WriteToLog(session.ExportIDToError(ctx))
+				errors.LogInfo(ctx, "taking detour [", outTag, "] for [", destination, "]")
 				handler = h
 				handler = h
 			} else {
 			} else {
-				newError("non existing outTag: ", outTag).AtWarning().WriteToLog(session.ExportIDToError(ctx))
+				errors.LogWarning(ctx, "non existing outTag: ", outTag)
 			}
 			}
 		} else {
 		} else {
-			newError("default route for ", destination).WriteToLog(session.ExportIDToError(ctx))
+			errors.LogInfo(ctx, "default route for ", destination)
 		}
 		}
 	}
 	}
 
 
@@ -435,7 +436,7 @@ func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.
 	}
 	}
 
 
 	if handler == nil {
 	if handler == nil {
-		newError("default outbound handler not exist").WriteToLog(session.ExportIDToError(ctx))
+		errors.LogInfo(ctx, "default outbound handler not exist")
 		common.Close(link.Writer)
 		common.Close(link.Writer)
 		common.Interrupt(link.Reader)
 		common.Interrupt(link.Reader)
 		return
 		return

+ 0 - 9
app/dispatcher/errors.generated.go

@@ -1,9 +0,0 @@
-package dispatcher
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 5 - 4
app/dispatcher/fakednssniffer.go

@@ -5,6 +5,7 @@ import (
 	"strings"
 	"strings"
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/session"
 	"github.com/xtls/xray-core/common/session"
 	"github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/core"
@@ -22,7 +23,7 @@ func newFakeDNSSniffer(ctx context.Context) (protocolSnifferWithMetadata, error)
 	}
 	}
 
 
 	if fakeDNSEngine == nil {
 	if fakeDNSEngine == nil {
-		errNotInit := newError("FakeDNSEngine is not initialized, but such a sniffer is used").AtError()
+		errNotInit := errors.New("FakeDNSEngine is not initialized, but such a sniffer is used").AtError()
 		return protocolSnifferWithMetadata{}, errNotInit
 		return protocolSnifferWithMetadata{}, errNotInit
 	}
 	}
 	return protocolSnifferWithMetadata{protocolSniffer: func(ctx context.Context, bytes []byte) (SniffResult, error) {
 	return protocolSnifferWithMetadata{protocolSniffer: func(ctx context.Context, bytes []byte) (SniffResult, error) {
@@ -31,7 +32,7 @@ func newFakeDNSSniffer(ctx context.Context) (protocolSnifferWithMetadata, error)
 		if ob.Target.Network == net.Network_TCP || ob.Target.Network == net.Network_UDP {
 		if ob.Target.Network == net.Network_TCP || ob.Target.Network == net.Network_UDP {
 			domainFromFakeDNS := fakeDNSEngine.GetDomainFromFakeDNS(ob.Target.Address)
 			domainFromFakeDNS := fakeDNSEngine.GetDomainFromFakeDNS(ob.Target.Address)
 			if domainFromFakeDNS != "" {
 			if domainFromFakeDNS != "" {
-				newError("fake dns got domain: ", domainFromFakeDNS, " for ip: ", ob.Target.Address.String()).WriteToLog(session.ExportIDToError(ctx))
+				errors.LogInfo(ctx, "fake dns got domain: ", domainFromFakeDNS, " for ip: ", ob.Target.Address.String())
 				return &fakeDNSSniffResult{domainName: domainFromFakeDNS}, nil
 				return &fakeDNSSniffResult{domainName: domainFromFakeDNS}, nil
 			}
 			}
 		}
 		}
@@ -109,10 +110,10 @@ func newFakeDNSThenOthers(ctx context.Context, fakeDNSSniffer protocolSnifferWit
 					}
 					}
 					return nil, common.ErrNoClue
 					return nil, common.ErrNoClue
 				}
 				}
-				newError("ip address not in fake dns range, return as is").AtDebug().WriteToLog()
+				errors.LogDebug(ctx, "ip address not in fake dns range, return as is")
 				return nil, common.ErrNoClue
 				return nil, common.ErrNoClue
 			}
 			}
-			newError("fake dns sniffer did not set address in range option, assume false.").AtWarning().WriteToLog()
+			errors.LogWarning(ctx, "fake dns sniffer did not set address in range option, assume false.")
 			return nil, common.ErrNoClue
 			return nil, common.ErrNoClue
 		},
 		},
 		metadataSniffer: false,
 		metadataSniffer: false,

+ 2 - 1
app/dispatcher/sniffer.go

@@ -4,6 +4,7 @@ import (
 	"context"
 	"context"
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/protocol/bittorrent"
 	"github.com/xtls/xray-core/common/protocol/bittorrent"
 	"github.com/xtls/xray-core/common/protocol/http"
 	"github.com/xtls/xray-core/common/protocol/http"
@@ -52,7 +53,7 @@ func NewSniffer(ctx context.Context) *Sniffer {
 	return ret
 	return ret
 }
 }
 
 
-var errUnknownContent = newError("unknown content")
+var errUnknownContent = errors.New("unknown content")
 
 
 func (s *Sniffer) Sniff(c context.Context, payload []byte, network net.Network) (SniffResult, error) {
 func (s *Sniffer) Sniff(c context.Context, payload []byte, network net.Network) (SniffResult, error) {
 	var pendingSniffer []protocolSnifferWithMetadata
 	var pendingSniffer []protocolSnifferWithMetadata

+ 4 - 3
app/dns/config.go

@@ -1,6 +1,7 @@
 package dns
 package dns
 
 
 import (
 import (
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/strmatcher"
 	"github.com/xtls/xray-core/common/strmatcher"
 	"github.com/xtls/xray-core/common/uuid"
 	"github.com/xtls/xray-core/common/uuid"
@@ -36,11 +37,11 @@ var localTLDsAndDotlessDomainsRule = &NameServer_OriginalRule{
 func toStrMatcher(t DomainMatchingType, domain string) (strmatcher.Matcher, error) {
 func toStrMatcher(t DomainMatchingType, domain string) (strmatcher.Matcher, error) {
 	strMType, f := typeMap[t]
 	strMType, f := typeMap[t]
 	if !f {
 	if !f {
-		return nil, newError("unknown mapping type", t).AtWarning()
+		return nil, errors.New("unknown mapping type", t).AtWarning()
 	}
 	}
 	matcher, err := strMType.New(domain)
 	matcher, err := strMType.New(domain)
 	if err != nil {
 	if err != nil {
-		return nil, newError("failed to create str matcher").Base(err)
+		return nil, errors.New("failed to create str matcher").Base(err)
 	}
 	}
 	return matcher, nil
 	return matcher, nil
 }
 }
@@ -51,7 +52,7 @@ func toNetIP(addrs []net.Address) ([]net.IP, error) {
 		if addr.Family().IsIP() {
 		if addr.Family().IsIP() {
 			ips = append(ips, addr.IP())
 			ips = append(ips, addr.IP())
 		} else {
 		} else {
-			return nil, newError("Failed to convert address", addr, "to Net IP.").AtWarning()
+			return nil, errors.New("Failed to convert address", addr, "to Net IP.").AtWarning()
 		}
 		}
 	}
 	}
 	return ips, nil
 	return ips, nil

+ 14 - 14
app/dns/dns.go

@@ -54,7 +54,7 @@ func New(ctx context.Context, config *Config) (*DNS, error) {
 	case 0, net.IPv4len, net.IPv6len:
 	case 0, net.IPv4len, net.IPv6len:
 		clientIP = net.IP(config.ClientIp)
 		clientIP = net.IP(config.ClientIp)
 	default:
 	default:
-		return nil, newError("unexpected client IP length ", len(config.ClientIp))
+		return nil, errors.New("unexpected client IP length ", len(config.ClientIp))
 	}
 	}
 
 
 	var ipOption *dns.IPOption
 	var ipOption *dns.IPOption
@@ -81,7 +81,7 @@ func New(ctx context.Context, config *Config) (*DNS, error) {
 
 
 	hosts, err := NewStaticHosts(config.StaticHosts, config.Hosts)
 	hosts, err := NewStaticHosts(config.StaticHosts, config.Hosts)
 	if err != nil {
 	if err != nil {
-		return nil, newError("failed to create hosts").Base(err)
+		return nil, errors.New("failed to create hosts").Base(err)
 	}
 	}
 
 
 	clients := []*Client{}
 	clients := []*Client{}
@@ -99,7 +99,7 @@ func New(ctx context.Context, config *Config) (*DNS, error) {
 		features.PrintDeprecatedFeatureWarning("simple DNS server")
 		features.PrintDeprecatedFeatureWarning("simple DNS server")
 		client, err := NewSimpleClient(ctx, endpoint, clientIP)
 		client, err := NewSimpleClient(ctx, endpoint, clientIP)
 		if err != nil {
 		if err != nil {
-			return nil, newError("failed to create client").Base(err)
+			return nil, errors.New("failed to create client").Base(err)
 		}
 		}
 		clients = append(clients, client)
 		clients = append(clients, client)
 	}
 	}
@@ -122,7 +122,7 @@ func New(ctx context.Context, config *Config) (*DNS, error) {
 		}
 		}
 		client, err := NewClient(ctx, ns, myClientIP, geoipContainer, &matcherInfos, updateDomain)
 		client, err := NewClient(ctx, ns, myClientIP, geoipContainer, &matcherInfos, updateDomain)
 		if err != nil {
 		if err != nil {
-			return nil, newError("failed to create client").Base(err)
+			return nil, errors.New("failed to create client").Base(err)
 		}
 		}
 		clients = append(clients, client)
 		clients = append(clients, client)
 	}
 	}
@@ -170,7 +170,7 @@ func (s *DNS) IsOwnLink(ctx context.Context) bool {
 // LookupIP implements dns.Client.
 // LookupIP implements dns.Client.
 func (s *DNS) LookupIP(domain string, option dns.IPOption) ([]net.IP, error) {
 func (s *DNS) LookupIP(domain string, option dns.IPOption) ([]net.IP, error) {
 	if domain == "" {
 	if domain == "" {
-		return nil, newError("empty domain name")
+		return nil, errors.New("empty domain name")
 	}
 	}
 
 
 	option.IPv4Enable = option.IPv4Enable && s.ipOption.IPv4Enable
 	option.IPv4Enable = option.IPv4Enable && s.ipOption.IPv4Enable
@@ -190,10 +190,10 @@ func (s *DNS) LookupIP(domain string, option dns.IPOption) ([]net.IP, error) {
 	case len(addrs) == 0: // Domain recorded, but no valid IP returned (e.g. IPv4 address with only IPv6 enabled)
 	case len(addrs) == 0: // Domain recorded, but no valid IP returned (e.g. IPv4 address with only IPv6 enabled)
 		return nil, dns.ErrEmptyResponse
 		return nil, dns.ErrEmptyResponse
 	case len(addrs) == 1 && addrs[0].Family().IsDomain(): // Domain replacement
 	case len(addrs) == 1 && addrs[0].Family().IsDomain(): // Domain replacement
-		newError("domain replaced: ", domain, " -> ", addrs[0].Domain()).WriteToLog()
+		errors.LogInfo(s.ctx, "domain replaced: ", domain, " -> ", addrs[0].Domain())
 		domain = addrs[0].Domain()
 		domain = addrs[0].Domain()
 	default: // Successfully found ip records in static host
 	default: // Successfully found ip records in static host
-		newError("returning ", len(addrs), " IP(s) for domain ", domain, " -> ", addrs).WriteToLog()
+		errors.LogInfo(s.ctx, "returning ", len(addrs), " IP(s) for domain ", domain, " -> ", addrs)
 		return toNetIP(addrs)
 		return toNetIP(addrs)
 	}
 	}
 
 
@@ -202,7 +202,7 @@ func (s *DNS) LookupIP(domain string, option dns.IPOption) ([]net.IP, error) {
 	ctx := session.ContextWithInbound(s.ctx, &session.Inbound{Tag: s.tag})
 	ctx := session.ContextWithInbound(s.ctx, &session.Inbound{Tag: s.tag})
 	for _, client := range s.sortClients(domain) {
 	for _, client := range s.sortClients(domain) {
 		if !option.FakeEnable && strings.EqualFold(client.Name(), "FakeDNS") {
 		if !option.FakeEnable && strings.EqualFold(client.Name(), "FakeDNS") {
-			newError("skip DNS resolution for domain ", domain, " at server ", client.Name()).AtDebug().WriteToLog()
+			errors.LogDebug(s.ctx, "skip DNS resolution for domain ", domain, " at server ", client.Name())
 			continue
 			continue
 		}
 		}
 		ips, err := client.QueryIP(ctx, domain, option, s.disableCache)
 		ips, err := client.QueryIP(ctx, domain, option, s.disableCache)
@@ -210,7 +210,7 @@ func (s *DNS) LookupIP(domain string, option dns.IPOption) ([]net.IP, error) {
 			return ips, nil
 			return ips, nil
 		}
 		}
 		if err != nil {
 		if err != nil {
-			newError("failed to lookup ip for domain ", domain, " at server ", client.Name()).Base(err).WriteToLog()
+			errors.LogInfoInner(s.ctx, err, "failed to lookup ip for domain ", domain, " at server ", client.Name())
 			errs = append(errs, err)
 			errs = append(errs, err)
 		}
 		}
 		// 5 for RcodeRefused in miekg/dns, hardcode to reduce binary size
 		// 5 for RcodeRefused in miekg/dns, hardcode to reduce binary size
@@ -219,7 +219,7 @@ func (s *DNS) LookupIP(domain string, option dns.IPOption) ([]net.IP, error) {
 		}
 		}
 	}
 	}
 
 
-	return nil, newError("returning nil for domain ", domain).Base(errors.Combine(errs...))
+	return nil, errors.New("returning nil for domain ", domain).Base(errors.Combine(errs...))
 }
 }
 
 
 // LookupHosts implements dns.HostsLookup.
 // LookupHosts implements dns.HostsLookup.
@@ -231,7 +231,7 @@ func (s *DNS) LookupHosts(domain string) *net.Address {
 	// Normalize the FQDN form query
 	// Normalize the FQDN form query
 	addrs := s.hosts.Lookup(domain, *s.ipOption)
 	addrs := s.hosts.Lookup(domain, *s.ipOption)
 	if len(addrs) > 0 {
 	if len(addrs) > 0 {
-		newError("domain replaced: ", domain, " -> ", addrs[0].String()).AtInfo().WriteToLog()
+		errors.LogInfo(s.ctx, "domain replaced: ", domain, " -> ", addrs[0].String())
 		return &addrs[0]
 		return &addrs[0]
 	}
 	}
 
 
@@ -289,16 +289,16 @@ func (s *DNS) sortClients(domain string) []*Client {
 	}
 	}
 
 
 	if len(domainRules) > 0 {
 	if len(domainRules) > 0 {
-		newError("domain ", domain, " matches following rules: ", domainRules).AtDebug().WriteToLog()
+		errors.LogDebug(s.ctx, "domain ", domain, " matches following rules: ", domainRules)
 	}
 	}
 	if len(clientNames) > 0 {
 	if len(clientNames) > 0 {
-		newError("domain ", domain, " will use DNS in order: ", clientNames).AtDebug().WriteToLog()
+		errors.LogDebug(s.ctx, "domain ", domain, " will use DNS in order: ", clientNames)
 	}
 	}
 
 
 	if len(clients) == 0 {
 	if len(clients) == 0 {
 		clients = append(clients, s.clients[0])
 		clients = append(clients, s.clients[0])
 		clientNames = append(clientNames, s.clients[0].Name())
 		clientNames = append(clientNames, s.clients[0].Name())
-		newError("domain ", domain, " will use the first DNS: ", clientNames).AtDebug().WriteToLog()
+		errors.LogDebug(s.ctx, "domain ", domain, " will use the first DNS: ", clientNames)
 	}
 	}
 
 
 	return clients
 	return clients

+ 6 - 6
app/dns/dnscommon.go

@@ -171,10 +171,10 @@ func parseResponse(payload []byte) (*IPRecord, error) {
 	var parser dnsmessage.Parser
 	var parser dnsmessage.Parser
 	h, err := parser.Start(payload)
 	h, err := parser.Start(payload)
 	if err != nil {
 	if err != nil {
-		return nil, newError("failed to parse DNS response").Base(err).AtWarning()
+		return nil, errors.New("failed to parse DNS response").Base(err).AtWarning()
 	}
 	}
 	if err := parser.SkipAllQuestions(); err != nil {
 	if err := parser.SkipAllQuestions(); err != nil {
-		return nil, newError("failed to skip questions in DNS response").Base(err).AtWarning()
+		return nil, errors.New("failed to skip questions in DNS response").Base(err).AtWarning()
 	}
 	}
 
 
 	now := time.Now()
 	now := time.Now()
@@ -189,7 +189,7 @@ L:
 		ah, err := parser.AnswerHeader()
 		ah, err := parser.AnswerHeader()
 		if err != nil {
 		if err != nil {
 			if err != dnsmessage.ErrSectionDone {
 			if err != dnsmessage.ErrSectionDone {
-				newError("failed to parse answer section for domain: ", ah.Name.String()).Base(err).WriteToLog()
+				errors.LogInfoInner(context.Background(), err, "failed to parse answer section for domain: ", ah.Name.String())
 			}
 			}
 			break
 			break
 		}
 		}
@@ -207,20 +207,20 @@ L:
 		case dnsmessage.TypeA:
 		case dnsmessage.TypeA:
 			ans, err := parser.AResource()
 			ans, err := parser.AResource()
 			if err != nil {
 			if err != nil {
-				newError("failed to parse A record for domain: ", ah.Name).Base(err).WriteToLog()
+				errors.LogInfoInner(context.Background(), err, "failed to parse A record for domain: ", ah.Name)
 				break L
 				break L
 			}
 			}
 			ipRecord.IP = append(ipRecord.IP, net.IPAddress(ans.A[:]))
 			ipRecord.IP = append(ipRecord.IP, net.IPAddress(ans.A[:]))
 		case dnsmessage.TypeAAAA:
 		case dnsmessage.TypeAAAA:
 			ans, err := parser.AAAAResource()
 			ans, err := parser.AAAAResource()
 			if err != nil {
 			if err != nil {
-				newError("failed to parse AAAA record for domain: ", ah.Name).Base(err).WriteToLog()
+				errors.LogInfoInner(context.Background(), err, "failed to parse AAAA record for domain: ", ah.Name)
 				break L
 				break L
 			}
 			}
 			ipRecord.IP = append(ipRecord.IP, net.IPAddress(ans.AAAA[:]))
 			ipRecord.IP = append(ipRecord.IP, net.IPAddress(ans.AAAA[:]))
 		default:
 		default:
 			if err := parser.SkipAnswer(); err != nil {
 			if err := parser.SkipAnswer(); err != nil {
-				newError("failed to skip answer").Base(err).WriteToLog()
+				errors.LogInfoInner(context.Background(), err, "failed to skip answer")
 				break L
 				break L
 			}
 			}
 			continue
 			continue

+ 0 - 9
app/dns/errors.generated.go

@@ -1,9 +0,0 @@
-package dns
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 0 - 9
app/dns/fakedns/errors.generated.go

@@ -1,9 +0,0 @@
-package fakedns
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 9 - 8
app/dns/fakedns/fake.go

@@ -10,6 +10,7 @@ import (
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common/cache"
 	"github.com/xtls/xray-core/common/cache"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/features/dns"
 	"github.com/xtls/xray-core/features/dns"
 )
 )
@@ -45,7 +46,7 @@ func (fkdns *Holder) Start() error {
 	if fkdns.config != nil && fkdns.config.IpPool != "" && fkdns.config.LruSize != 0 {
 	if fkdns.config != nil && fkdns.config.IpPool != "" && fkdns.config.LruSize != 0 {
 		return fkdns.initializeFromConfig()
 		return fkdns.initializeFromConfig()
 	}
 	}
-	return newError("invalid fakeDNS setting")
+	return errors.New("invalid fakeDNS setting")
 }
 }
 
 
 func (fkdns *Holder) Close() error {
 func (fkdns *Holder) Close() error {
@@ -60,7 +61,7 @@ func NewFakeDNSHolder() (*Holder, error) {
 	var err error
 	var err error
 
 
 	if fkdns, err = NewFakeDNSHolderConfigOnly(nil); err != nil {
 	if fkdns, err = NewFakeDNSHolderConfigOnly(nil); err != nil {
-		return nil, newError("Unable to create Fake Dns Engine").Base(err).AtError()
+		return nil, errors.New("Unable to create Fake Dns Engine").Base(err).AtError()
 	}
 	}
 	err = fkdns.initialize(dns.FakeIPv4Pool, 65535)
 	err = fkdns.initialize(dns.FakeIPv4Pool, 65535)
 	if err != nil {
 	if err != nil {
@@ -82,13 +83,13 @@ func (fkdns *Holder) initialize(ipPoolCidr string, lruSize int) error {
 	var err error
 	var err error
 
 
 	if _, ipRange, err = gonet.ParseCIDR(ipPoolCidr); err != nil {
 	if _, ipRange, err = gonet.ParseCIDR(ipPoolCidr); err != nil {
-		return newError("Unable to parse CIDR for Fake DNS IP assignment").Base(err).AtError()
+		return errors.New("Unable to parse CIDR for Fake DNS IP assignment").Base(err).AtError()
 	}
 	}
 
 
 	ones, bits := ipRange.Mask.Size()
 	ones, bits := ipRange.Mask.Size()
 	rooms := bits - ones
 	rooms := bits - ones
 	if math.Log2(float64(lruSize)) >= float64(rooms) {
 	if math.Log2(float64(lruSize)) >= float64(rooms) {
-		return newError("LRU size is bigger than subnet size").AtError()
+		return errors.New("LRU size is bigger than subnet size").AtError()
 	}
 	}
 	fkdns.domainToIP = cache.NewLru(lruSize)
 	fkdns.domainToIP = cache.NewLru(lruSize)
 	fkdns.ipRange = ipRange
 	fkdns.ipRange = ipRange
@@ -137,7 +138,7 @@ func (fkdns *Holder) GetDomainFromFakeDNS(ip net.Address) string {
 	if k, ok := fkdns.domainToIP.GetKeyFromValue(ip); ok {
 	if k, ok := fkdns.domainToIP.GetKeyFromValue(ip); ok {
 		return k.(string)
 		return k.(string)
 	}
 	}
-	newError("A fake ip request to ", ip, ", however there is no matching domain name in fake DNS").AtInfo().WriteToLog()
+	errors.LogInfo(context.Background(), "A fake ip request to ", ip, ", however there is no matching domain name in fake DNS")
 	return ""
 	return ""
 }
 }
 
 
@@ -192,10 +193,10 @@ func (h *HolderMulti) Start() error {
 	for _, v := range h.holders {
 	for _, v := range h.holders {
 		if v.config != nil && v.config.IpPool != "" && v.config.LruSize != 0 {
 		if v.config != nil && v.config.IpPool != "" && v.config.LruSize != 0 {
 			if err := v.Start(); err != nil {
 			if err := v.Start(); err != nil {
-				return newError("Cannot start all fake dns pools").Base(err)
+				return errors.New("Cannot start all fake dns pools").Base(err)
 			}
 			}
 		} else {
 		} else {
-			return newError("invalid fakeDNS setting")
+			return errors.New("invalid fakeDNS setting")
 		}
 		}
 	}
 	}
 	return nil
 	return nil
@@ -204,7 +205,7 @@ func (h *HolderMulti) Start() error {
 func (h *HolderMulti) Close() error {
 func (h *HolderMulti) Close() error {
 	for _, v := range h.holders {
 	for _, v := range h.holders {
 		if err := v.Close(); err != nil {
 		if err := v.Close(); err != nil {
-			return newError("Cannot close all fake dns pools").Base(err)
+			return errors.New("Cannot close all fake dns pools").Base(err)
 		}
 		}
 	}
 	}
 	return nil
 	return nil

+ 8 - 5
app/dns/hosts.go

@@ -1,7 +1,10 @@
 package dns
 package dns
 
 
 import (
 import (
+	"context"
+
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/strmatcher"
 	"github.com/xtls/xray-core/common/strmatcher"
 	"github.com/xtls/xray-core/features"
 	"github.com/xtls/xray-core/features"
@@ -32,7 +35,7 @@ func NewStaticHosts(hosts []*Config_HostMapping, legacy map[string]*net.IPOrDoma
 
 
 			address := ip.AsAddress()
 			address := ip.AsAddress()
 			if address.Family().IsDomain() {
 			if address.Family().IsDomain() {
-				return nil, newError("invalid domain address in static hosts: ", address.Domain()).AtWarning()
+				return nil, errors.New("invalid domain address in static hosts: ", address.Domain()).AtWarning()
 			}
 			}
 
 
 			sh.ips[id] = []net.Address{address}
 			sh.ips[id] = []net.Address{address}
@@ -42,7 +45,7 @@ func NewStaticHosts(hosts []*Config_HostMapping, legacy map[string]*net.IPOrDoma
 	for _, mapping := range hosts {
 	for _, mapping := range hosts {
 		matcher, err := toStrMatcher(mapping.Type, mapping.Domain)
 		matcher, err := toStrMatcher(mapping.Type, mapping.Domain)
 		if err != nil {
 		if err != nil {
-			return nil, newError("failed to create domain matcher").Base(err)
+			return nil, errors.New("failed to create domain matcher").Base(err)
 		}
 		}
 		id := g.Add(matcher)
 		id := g.Add(matcher)
 		ips := make([]net.Address, 0, len(mapping.Ip)+1)
 		ips := make([]net.Address, 0, len(mapping.Ip)+1)
@@ -53,12 +56,12 @@ func NewStaticHosts(hosts []*Config_HostMapping, legacy map[string]*net.IPOrDoma
 			for _, ip := range mapping.Ip {
 			for _, ip := range mapping.Ip {
 				addr := net.IPAddress(ip)
 				addr := net.IPAddress(ip)
 				if addr == nil {
 				if addr == nil {
-					return nil, newError("invalid IP address in static hosts: ", ip).AtWarning()
+					return nil, errors.New("invalid IP address in static hosts: ", ip).AtWarning()
 				}
 				}
 				ips = append(ips, addr)
 				ips = append(ips, addr)
 			}
 			}
 		default:
 		default:
-			return nil, newError("neither IP address nor proxied domain specified for domain: ", mapping.Domain).AtWarning()
+			return nil, errors.New("neither IP address nor proxied domain specified for domain: ", mapping.Domain).AtWarning()
 		}
 		}
 
 
 		sh.ips[id] = ips
 		sh.ips[id] = ips
@@ -90,7 +93,7 @@ func (h *StaticHosts) lookup(domain string, option dns.IPOption, maxDepth int) [
 	case len(addrs) == 0: // Not recorded in static hosts, return nil
 	case len(addrs) == 0: // Not recorded in static hosts, return nil
 		return nil
 		return nil
 	case len(addrs) == 1 && addrs[0].Family().IsDomain(): // Try to unwrap domain
 	case len(addrs) == 1 && addrs[0].Family().IsDomain(): // Try to unwrap domain
-		newError("found replaced domain: ", domain, " -> ", addrs[0].Domain(), ". Try to unwrap it").AtDebug().WriteToLog()
+		errors.LogDebug(context.Background(), "found replaced domain: ", domain, " -> ", addrs[0].Domain(), ". Try to unwrap it")
 		if maxDepth > 0 {
 		if maxDepth > 0 {
 			unwrapped := h.lookup(addrs[0].Domain(), option, maxDepth-1)
 			unwrapped := h.lookup(addrs[0].Domain(), option, maxDepth-1)
 			if unwrapped != nil {
 			if unwrapped != nil {

+ 11 - 11
app/dns/nameserver.go

@@ -64,7 +64,7 @@ func NewServer(dest net.Destination, dispatcher routing.Dispatcher, queryStrateg
 	if dest.Network == net.Network_UDP { // UDP classic DNS mode
 	if dest.Network == net.Network_UDP { // UDP classic DNS mode
 		return NewClassicNameServer(dest, dispatcher), nil
 		return NewClassicNameServer(dest, dispatcher), nil
 	}
 	}
-	return nil, newError("No available name server could be created from ", dest).AtWarning()
+	return nil, errors.New("No available name server could be created from ", dest).AtWarning()
 }
 }
 
 
 // NewClient creates a DNS client managing a name server with client IP, domain rules and expected IPs.
 // NewClient creates a DNS client managing a name server with client IP, domain rules and expected IPs.
@@ -82,7 +82,7 @@ func NewClient(
 		// Create a new server for each client for now
 		// Create a new server for each client for now
 		server, err := NewServer(ns.Address.AsDestination(), dispatcher, ns.GetQueryStrategy())
 		server, err := NewServer(ns.Address.AsDestination(), dispatcher, ns.GetQueryStrategy())
 		if err != nil {
 		if err != nil {
-			return newError("failed to create nameserver").Base(err).AtWarning()
+			return errors.New("failed to create nameserver").Base(err).AtWarning()
 		}
 		}
 
 
 		// Priotize local domains with specific TLDs or without any dot to local DNS
 		// Priotize local domains with specific TLDs or without any dot to local DNS
@@ -111,7 +111,7 @@ func NewClient(
 		for _, domain := range ns.PrioritizedDomain {
 		for _, domain := range ns.PrioritizedDomain {
 			domainRule, err := toStrMatcher(domain.Type, domain.Domain)
 			domainRule, err := toStrMatcher(domain.Type, domain.Domain)
 			if err != nil {
 			if err != nil {
-				return newError("failed to create prioritized domain").Base(err).AtWarning()
+				return errors.New("failed to create prioritized domain").Base(err).AtWarning()
 			}
 			}
 			originalRuleIdx := ruleCurr
 			originalRuleIdx := ruleCurr
 			if ruleCurr < len(ns.OriginalRules) {
 			if ruleCurr < len(ns.OriginalRules) {
@@ -130,7 +130,7 @@ func NewClient(
 			}
 			}
 			err = updateDomainRule(domainRule, originalRuleIdx, *matcherInfos)
 			err = updateDomainRule(domainRule, originalRuleIdx, *matcherInfos)
 			if err != nil {
 			if err != nil {
-				return newError("failed to create prioritized domain").Base(err).AtWarning()
+				return errors.New("failed to create prioritized domain").Base(err).AtWarning()
 			}
 			}
 		}
 		}
 
 
@@ -139,7 +139,7 @@ func NewClient(
 		for _, geoip := range ns.Geoip {
 		for _, geoip := range ns.Geoip {
 			matcher, err := container.Add(geoip)
 			matcher, err := container.Add(geoip)
 			if err != nil {
 			if err != nil {
-				return newError("failed to create ip matcher").Base(err).AtWarning()
+				return errors.New("failed to create ip matcher").Base(err).AtWarning()
 			}
 			}
 			matchers = append(matchers, matcher)
 			matchers = append(matchers, matcher)
 		}
 		}
@@ -147,9 +147,9 @@ func NewClient(
 		if len(clientIP) > 0 {
 		if len(clientIP) > 0 {
 			switch ns.Address.Address.GetAddress().(type) {
 			switch ns.Address.Address.GetAddress().(type) {
 			case *net.IPOrDomain_Domain:
 			case *net.IPOrDomain_Domain:
-				newError("DNS: client ", ns.Address.Address.GetDomain(), " uses clientIP ", clientIP.String()).AtInfo().WriteToLog()
+				errors.LogInfo(ctx, "DNS: client ", ns.Address.Address.GetDomain(), " uses clientIP ", clientIP.String())
 			case *net.IPOrDomain_Ip:
 			case *net.IPOrDomain_Ip:
-				newError("DNS: client ", ns.Address.Address.GetIp(), " uses clientIP ", clientIP.String()).AtInfo().WriteToLog()
+				errors.LogInfo(ctx, "DNS: client ", ns.Address.Address.GetIp(), " uses clientIP ", clientIP.String())
 			}
 			}
 		}
 		}
 
 
@@ -169,7 +169,7 @@ func NewSimpleClient(ctx context.Context, endpoint *net.Endpoint, clientIP net.I
 	err := core.RequireFeatures(ctx, func(dispatcher routing.Dispatcher) error {
 	err := core.RequireFeatures(ctx, func(dispatcher routing.Dispatcher) error {
 		server, err := NewServer(endpoint.AsDestination(), dispatcher, QueryStrategy_USE_IP)
 		server, err := NewServer(endpoint.AsDestination(), dispatcher, QueryStrategy_USE_IP)
 		if err != nil {
 		if err != nil {
-			return newError("failed to create nameserver").Base(err).AtWarning()
+			return errors.New("failed to create nameserver").Base(err).AtWarning()
 		}
 		}
 		client.server = server
 		client.server = server
 		client.clientIP = clientIP
 		client.clientIP = clientIP
@@ -179,9 +179,9 @@ func NewSimpleClient(ctx context.Context, endpoint *net.Endpoint, clientIP net.I
 	if len(clientIP) > 0 {
 	if len(clientIP) > 0 {
 		switch endpoint.Address.GetAddress().(type) {
 		switch endpoint.Address.GetAddress().(type) {
 		case *net.IPOrDomain_Domain:
 		case *net.IPOrDomain_Domain:
-			newError("DNS: client ", endpoint.Address.GetDomain(), " uses clientIP ", clientIP.String()).AtInfo().WriteToLog()
+			errors.LogInfo(ctx, "DNS: client ", endpoint.Address.GetDomain(), " uses clientIP ", clientIP.String())
 		case *net.IPOrDomain_Ip:
 		case *net.IPOrDomain_Ip:
-			newError("DNS: client ", endpoint.Address.GetIp(), " uses clientIP ", clientIP.String()).AtInfo().WriteToLog()
+			errors.LogInfo(ctx, "DNS: client ", endpoint.Address.GetIp(), " uses clientIP ", clientIP.String())
 		}
 		}
 	}
 	}
 
 
@@ -222,7 +222,7 @@ func (c *Client) MatchExpectedIPs(domain string, ips []net.IP) ([]net.IP, error)
 	if len(newIps) == 0 {
 	if len(newIps) == 0 {
 		return nil, errExpectedIPNonMatch
 		return nil, errExpectedIPNonMatch
 	}
 	}
-	newError("domain ", domain, " expectIPs ", newIps, " matched at server ", c.Name()).AtDebug().WriteToLog()
+	errors.LogDebug(context.Background(), "domain ", domain, " expectIPs ", newIps, " matched at server ", c.Name())
 	return newIps, nil
 	return newIps, nil
 }
 }
 
 

+ 13 - 12
app/dns/nameserver_doh.go

@@ -12,6 +12,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/log"
 	"github.com/xtls/xray-core/common/log"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net/cnc"
 	"github.com/xtls/xray-core/common/net/cnc"
@@ -43,7 +44,7 @@ type DoHNameServer struct {
 
 
 // NewDoHNameServer creates DOH server object for remote resolving.
 // NewDoHNameServer creates DOH server object for remote resolving.
 func NewDoHNameServer(url *url.URL, dispatcher routing.Dispatcher, queryStrategy QueryStrategy) (*DoHNameServer, error) {
 func NewDoHNameServer(url *url.URL, dispatcher routing.Dispatcher, queryStrategy QueryStrategy) (*DoHNameServer, error) {
-	newError("DNS: created Remote DOH client for ", url.String()).AtInfo().WriteToLog()
+	errors.LogInfo(context.Background(), "DNS: created Remote DOH client for ", url.String())
 	s := baseDOHNameServer(url, "DOH", queryStrategy)
 	s := baseDOHNameServer(url, "DOH", queryStrategy)
 
 
 	s.dispatcher = dispatcher
 	s.dispatcher = dispatcher
@@ -119,7 +120,7 @@ func NewDoHLocalNameServer(url *url.URL, queryStrategy QueryStrategy) *DoHNameSe
 		Timeout:   time.Second * 180,
 		Timeout:   time.Second * 180,
 		Transport: tr,
 		Transport: tr,
 	}
 	}
-	newError("DNS: created Local DOH client for ", url.String()).AtInfo().WriteToLog()
+	errors.LogInfo(context.Background(), "DNS: created Local DOH client for ", url.String())
 	return s
 	return s
 }
 }
 
 
@@ -150,7 +151,7 @@ func (s *DoHNameServer) Cleanup() error {
 	defer s.Unlock()
 	defer s.Unlock()
 
 
 	if len(s.ips) == 0 {
 	if len(s.ips) == 0 {
-		return newError("nothing to do. stopping...")
+		return errors.New("nothing to do. stopping...")
 	}
 	}
 
 
 	for domain, record := range s.ips {
 	for domain, record := range s.ips {
@@ -162,7 +163,7 @@ func (s *DoHNameServer) Cleanup() error {
 		}
 		}
 
 
 		if record.A == nil && record.AAAA == nil {
 		if record.A == nil && record.AAAA == nil {
-			newError(s.name, " cleanup ", domain).AtDebug().WriteToLog()
+			errors.LogDebug(context.Background(), s.name, " cleanup ", domain)
 			delete(s.ips, domain)
 			delete(s.ips, domain)
 		} else {
 		} else {
 			s.ips[domain] = record
 			s.ips[domain] = record
@@ -205,7 +206,7 @@ func (s *DoHNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) {
 			updated = true
 			updated = true
 		}
 		}
 	}
 	}
-	newError(s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed).AtInfo().WriteToLog()
+	errors.LogInfo(context.Background(), s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed)
 
 
 	if updated {
 	if updated {
 		s.ips[req.domain] = rec
 		s.ips[req.domain] = rec
@@ -225,10 +226,10 @@ func (s *DoHNameServer) newReqID() uint16 {
 }
 }
 
 
 func (s *DoHNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) {
 func (s *DoHNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) {
-	newError(s.name, " querying: ", domain).AtInfo().WriteToLog(session.ExportIDToError(ctx))
+	errors.LogInfo(ctx, s.name, " querying: ", domain)
 
 
 	if s.name+"." == "DOH//"+domain {
 	if s.name+"." == "DOH//"+domain {
-		newError(s.name, " tries to resolve itself! Use IP or set \"hosts\" instead.").AtError().WriteToLog(session.ExportIDToError(ctx))
+		errors.LogError(ctx, s.name, " tries to resolve itself! Use IP or set \"hosts\" instead.")
 		return
 		return
 	}
 	}
 
 
@@ -266,17 +267,17 @@ func (s *DoHNameServer) sendQuery(ctx context.Context, domain string, clientIP n
 
 
 			b, err := dns.PackMessage(r.msg)
 			b, err := dns.PackMessage(r.msg)
 			if err != nil {
 			if err != nil {
-				newError("failed to pack dns query for ", domain).Base(err).AtError().WriteToLog()
+				errors.LogErrorInner(ctx, err, "failed to pack dns query for ", domain)
 				return
 				return
 			}
 			}
 			resp, err := s.dohHTTPSContext(dnsCtx, b.Bytes())
 			resp, err := s.dohHTTPSContext(dnsCtx, b.Bytes())
 			if err != nil {
 			if err != nil {
-				newError("failed to retrieve response for ", domain).Base(err).AtError().WriteToLog()
+				errors.LogErrorInner(ctx, err, "failed to retrieve response for ", domain)
 				return
 				return
 			}
 			}
 			rec, err := parseResponse(resp)
 			rec, err := parseResponse(resp)
 			if err != nil {
 			if err != nil {
-				newError("failed to handle DOH response for ", domain).Base(err).AtError().WriteToLog()
+				errors.LogErrorInner(ctx, err, "failed to handle DOH response for ", domain)
 				return
 				return
 			}
 			}
 			s.updateIP(r, rec)
 			s.updateIP(r, rec)
@@ -361,11 +362,11 @@ func (s *DoHNameServer) QueryIP(ctx context.Context, domain string, clientIP net
 	}
 	}
 
 
 	if disableCache {
 	if disableCache {
-		newError("DNS cache is disabled. Querying IP for ", domain, " at ", s.name).AtDebug().WriteToLog()
+		errors.LogDebug(ctx, "DNS cache is disabled. Querying IP for ", domain, " at ", s.name)
 	} else {
 	} else {
 		ips, err := s.findIPsForDomain(fqdn, option)
 		ips, err := s.findIPsForDomain(fqdn, option)
 		if err != errRecordNotFound {
 		if err != errRecordNotFound {
-			newError(s.name, " cache HIT ", domain, " -> ", ips).Base(err).AtDebug().WriteToLog()
+			errors.LogDebugInner(ctx, err, s.name, " cache HIT ", domain, " -> ", ips)
 			log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err})
 			log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err})
 			return ips, err
 			return ips, err
 		}
 		}

+ 4 - 3
app/dns/nameserver_fakedns.go

@@ -3,6 +3,7 @@ package dns
 import (
 import (
 	"context"
 	"context"
 
 
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/features/dns"
 	"github.com/xtls/xray-core/features/dns"
@@ -25,7 +26,7 @@ func (f *FakeDNSServer) QueryIP(ctx context.Context, domain string, _ net.IP, op
 		if err := core.RequireFeatures(ctx, func(fd dns.FakeDNSEngine) {
 		if err := core.RequireFeatures(ctx, func(fd dns.FakeDNSEngine) {
 			f.fakeDNSEngine = fd
 			f.fakeDNSEngine = fd
 		}); err != nil {
 		}); err != nil {
-			return nil, newError("Unable to locate a fake DNS Engine").Base(err).AtError()
+			return nil, errors.New("Unable to locate a fake DNS Engine").Base(err).AtError()
 		}
 		}
 	}
 	}
 	var ips []net.Address
 	var ips []net.Address
@@ -37,10 +38,10 @@ func (f *FakeDNSServer) QueryIP(ctx context.Context, domain string, _ net.IP, op
 
 
 	netIP, err := toNetIP(ips)
 	netIP, err := toNetIP(ips)
 	if err != nil {
 	if err != nil {
-		return nil, newError("Unable to convert IP to net ip").Base(err).AtError()
+		return nil, errors.New("Unable to convert IP to net ip").Base(err).AtError()
 	}
 	}
 
 
-	newError(f.Name(), " got answer: ", domain, " -> ", ips).AtInfo().WriteToLog()
+	errors.LogInfo(ctx, f.Name(), " got answer: ", domain, " -> ", ips)
 
 
 	if len(netIP) > 0 {
 	if len(netIP) > 0 {
 		return netIP, nil
 		return netIP, nil

+ 4 - 3
app/dns/nameserver_local.go

@@ -5,6 +5,7 @@ import (
 	"strings"
 	"strings"
 	"time"
 	"time"
 
 
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/log"
 	"github.com/xtls/xray-core/common/log"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/features/dns"
 	"github.com/xtls/xray-core/features/dns"
@@ -19,7 +20,7 @@ type LocalNameServer struct {
 const errEmptyResponse = "No address associated with hostname"
 const errEmptyResponse = "No address associated with hostname"
 
 
 // QueryIP implements Server.
 // QueryIP implements Server.
-func (s *LocalNameServer) QueryIP(_ context.Context, domain string, _ net.IP, option dns.IPOption, _ bool) (ips []net.IP, err error) {
+func (s *LocalNameServer) QueryIP(ctx context.Context, domain string, _ net.IP, option dns.IPOption, _ bool) (ips []net.IP, err error) {
 	start := time.Now()
 	start := time.Now()
 	ips, err = s.client.LookupIP(domain, option)
 	ips, err = s.client.LookupIP(domain, option)
 
 
@@ -28,7 +29,7 @@ func (s *LocalNameServer) QueryIP(_ context.Context, domain string, _ net.IP, op
 	}
 	}
 
 
 	if len(ips) > 0 {
 	if len(ips) > 0 {
-		newError("Localhost got answer: ", domain, " -> ", ips).AtInfo().WriteToLog()
+		errors.LogInfo(ctx, "Localhost got answer: ", domain, " -> ", ips)
 		log.Record(&log.DNSLog{Server: s.Name(), Domain: domain, Result: ips, Status: log.DNSQueried, Elapsed: time.Since(start), Error: err})
 		log.Record(&log.DNSLog{Server: s.Name(), Domain: domain, Result: ips, Status: log.DNSQueried, Elapsed: time.Since(start), Error: err})
 	}
 	}
 
 
@@ -42,7 +43,7 @@ func (s *LocalNameServer) Name() string {
 
 
 // NewLocalNameServer creates localdns server object for directly lookup in system DNS.
 // NewLocalNameServer creates localdns server object for directly lookup in system DNS.
 func NewLocalNameServer() *LocalNameServer {
 func NewLocalNameServer() *LocalNameServer {
-	newError("DNS: created localhost client").AtInfo().WriteToLog()
+	errors.LogInfo(context.Background(), "DNS: created localhost client")
 	return &LocalNameServer{
 	return &LocalNameServer{
 		client: localdns.New(),
 		client: localdns.New(),
 	}
 	}

+ 15 - 14
app/dns/nameserver_quic.go

@@ -12,6 +12,7 @@ import (
 	"github.com/quic-go/quic-go"
 	"github.com/quic-go/quic-go"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common/buf"
 	"github.com/xtls/xray-core/common/buf"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/log"
 	"github.com/xtls/xray-core/common/log"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/protocol/dns"
 	"github.com/xtls/xray-core/common/protocol/dns"
@@ -45,7 +46,7 @@ type QUICNameServer struct {
 
 
 // NewQUICNameServer creates DNS-over-QUIC client object for local resolving
 // NewQUICNameServer creates DNS-over-QUIC client object for local resolving
 func NewQUICNameServer(url *url.URL, queryStrategy QueryStrategy) (*QUICNameServer, error) {
 func NewQUICNameServer(url *url.URL, queryStrategy QueryStrategy) (*QUICNameServer, error) {
-	newError("DNS: created Local DNS-over-QUIC client for ", url.String()).AtInfo().WriteToLog()
+	errors.LogInfo(context.Background(), "DNS: created Local DNS-over-QUIC client for ", url.String())
 
 
 	var err error
 	var err error
 	port := net.Port(853)
 	port := net.Port(853)
@@ -84,7 +85,7 @@ func (s *QUICNameServer) Cleanup() error {
 	defer s.Unlock()
 	defer s.Unlock()
 
 
 	if len(s.ips) == 0 {
 	if len(s.ips) == 0 {
-		return newError("nothing to do. stopping...")
+		return errors.New("nothing to do. stopping...")
 	}
 	}
 
 
 	for domain, record := range s.ips {
 	for domain, record := range s.ips {
@@ -96,7 +97,7 @@ func (s *QUICNameServer) Cleanup() error {
 		}
 		}
 
 
 		if record.A == nil && record.AAAA == nil {
 		if record.A == nil && record.AAAA == nil {
-			newError(s.name, " cleanup ", domain).AtDebug().WriteToLog()
+			errors.LogDebug(context.Background(), s.name, " cleanup ", domain)
 			delete(s.ips, domain)
 			delete(s.ips, domain)
 		} else {
 		} else {
 			s.ips[domain] = record
 			s.ips[domain] = record
@@ -139,7 +140,7 @@ func (s *QUICNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) {
 			updated = true
 			updated = true
 		}
 		}
 	}
 	}
-	newError(s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed).AtInfo().WriteToLog()
+	errors.LogInfo(context.Background(), s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed)
 
 
 	if updated {
 	if updated {
 		s.ips[req.domain] = rec
 		s.ips[req.domain] = rec
@@ -159,7 +160,7 @@ func (s *QUICNameServer) newReqID() uint16 {
 }
 }
 
 
 func (s *QUICNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) {
 func (s *QUICNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) {
-	newError(s.name, " querying: ", domain).AtInfo().WriteToLog(session.ExportIDToError(ctx))
+	errors.LogInfo(ctx, s.name, " querying: ", domain)
 
 
 	reqs := buildReqMsgs(domain, option, s.newReqID, genEDNS0Options(clientIP))
 	reqs := buildReqMsgs(domain, option, s.newReqID, genEDNS0Options(clientIP))
 
 
@@ -192,7 +193,7 @@ func (s *QUICNameServer) sendQuery(ctx context.Context, domain string, clientIP
 
 
 			b, err := dns.PackMessage(r.msg)
 			b, err := dns.PackMessage(r.msg)
 			if err != nil {
 			if err != nil {
-				newError("failed to pack dns query").Base(err).AtError().WriteToLog()
+				errors.LogErrorInner(ctx, err, "failed to pack dns query")
 				return
 				return
 			}
 			}
 
 
@@ -203,13 +204,13 @@ func (s *QUICNameServer) sendQuery(ctx context.Context, domain string, clientIP
 
 
 			conn, err := s.openStream(dnsCtx)
 			conn, err := s.openStream(dnsCtx)
 			if err != nil {
 			if err != nil {
-				newError("failed to open quic connection").Base(err).AtError().WriteToLog()
+				errors.LogErrorInner(ctx, err, "failed to open quic connection")
 				return
 				return
 			}
 			}
 
 
 			_, err = conn.Write(dnsReqBuf.Bytes())
 			_, err = conn.Write(dnsReqBuf.Bytes())
 			if err != nil {
 			if err != nil {
-				newError("failed to send query").Base(err).AtError().WriteToLog()
+				errors.LogErrorInner(ctx, err, "failed to send query")
 				return
 				return
 			}
 			}
 
 
@@ -219,25 +220,25 @@ func (s *QUICNameServer) sendQuery(ctx context.Context, domain string, clientIP
 			defer respBuf.Release()
 			defer respBuf.Release()
 			n, err := respBuf.ReadFullFrom(conn, 2)
 			n, err := respBuf.ReadFullFrom(conn, 2)
 			if err != nil && n == 0 {
 			if err != nil && n == 0 {
-				newError("failed to read response length").Base(err).AtError().WriteToLog()
+				errors.LogErrorInner(ctx, err, "failed to read response length")
 				return
 				return
 			}
 			}
 			var length int16
 			var length int16
 			err = binary.Read(bytes.NewReader(respBuf.Bytes()), binary.BigEndian, &length)
 			err = binary.Read(bytes.NewReader(respBuf.Bytes()), binary.BigEndian, &length)
 			if err != nil {
 			if err != nil {
-				newError("failed to parse response length").Base(err).AtError().WriteToLog()
+				errors.LogErrorInner(ctx, err, "failed to parse response length")
 				return
 				return
 			}
 			}
 			respBuf.Clear()
 			respBuf.Clear()
 			n, err = respBuf.ReadFullFrom(conn, int32(length))
 			n, err = respBuf.ReadFullFrom(conn, int32(length))
 			if err != nil && n == 0 {
 			if err != nil && n == 0 {
-				newError("failed to read response length").Base(err).AtError().WriteToLog()
+				errors.LogErrorInner(ctx, err, "failed to read response length")
 				return
 				return
 			}
 			}
 
 
 			rec, err := parseResponse(respBuf.Bytes())
 			rec, err := parseResponse(respBuf.Bytes())
 			if err != nil {
 			if err != nil {
-				newError("failed to handle response").Base(err).AtError().WriteToLog()
+				errors.LogErrorInner(ctx, err, "failed to handle response")
 				return
 				return
 			}
 			}
 			s.updateIP(r, rec)
 			s.updateIP(r, rec)
@@ -296,11 +297,11 @@ func (s *QUICNameServer) QueryIP(ctx context.Context, domain string, clientIP ne
 	}
 	}
 
 
 	if disableCache {
 	if disableCache {
-		newError("DNS cache is disabled. Querying IP for ", domain, " at ", s.name).AtDebug().WriteToLog()
+		errors.LogDebug(ctx, "DNS cache is disabled. Querying IP for ", domain, " at ", s.name)
 	} else {
 	} else {
 		ips, err := s.findIPsForDomain(fqdn, option)
 		ips, err := s.findIPsForDomain(fqdn, option)
 		if err != errRecordNotFound {
 		if err != errRecordNotFound {
-			newError(s.name, " cache HIT ", domain, " -> ", ips).Base(err).AtDebug().WriteToLog()
+			errors.LogDebugInner(ctx, err, s.name, " cache HIT ", domain, " -> ", ips)
 			log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err})
 			log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err})
 			return ips, err
 			return ips, err
 		}
 		}

+ 14 - 13
app/dns/nameserver_tcp.go

@@ -11,6 +11,7 @@ import (
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common/buf"
 	"github.com/xtls/xray-core/common/buf"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/log"
 	"github.com/xtls/xray-core/common/log"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net/cnc"
 	"github.com/xtls/xray-core/common/net/cnc"
@@ -114,7 +115,7 @@ func (s *TCPNameServer) Cleanup() error {
 	defer s.Unlock()
 	defer s.Unlock()
 
 
 	if len(s.ips) == 0 {
 	if len(s.ips) == 0 {
-		return newError("nothing to do. stopping...")
+		return errors.New("nothing to do. stopping...")
 	}
 	}
 
 
 	for domain, record := range s.ips {
 	for domain, record := range s.ips {
@@ -126,7 +127,7 @@ func (s *TCPNameServer) Cleanup() error {
 		}
 		}
 
 
 		if record.A == nil && record.AAAA == nil {
 		if record.A == nil && record.AAAA == nil {
-			newError(s.name, " cleanup ", domain).AtDebug().WriteToLog()
+			errors.LogDebug(context.Background(), s.name, " cleanup ", domain)
 			delete(s.ips, domain)
 			delete(s.ips, domain)
 		} else {
 		} else {
 			s.ips[domain] = record
 			s.ips[domain] = record
@@ -169,7 +170,7 @@ func (s *TCPNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) {
 			updated = true
 			updated = true
 		}
 		}
 	}
 	}
-	newError(s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed).AtInfo().WriteToLog()
+	errors.LogInfo(context.Background(), s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed)
 
 
 	if updated {
 	if updated {
 		s.ips[req.domain] = rec
 		s.ips[req.domain] = rec
@@ -189,7 +190,7 @@ func (s *TCPNameServer) newReqID() uint16 {
 }
 }
 
 
 func (s *TCPNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) {
 func (s *TCPNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) {
-	newError(s.name, " querying DNS for: ", domain).AtDebug().WriteToLog(session.ExportIDToError(ctx))
+	errors.LogDebug(ctx, s.name, " querying DNS for: ", domain)
 
 
 	reqs := buildReqMsgs(domain, option, s.newReqID, genEDNS0Options(clientIP))
 	reqs := buildReqMsgs(domain, option, s.newReqID, genEDNS0Options(clientIP))
 
 
@@ -219,13 +220,13 @@ func (s *TCPNameServer) sendQuery(ctx context.Context, domain string, clientIP n
 
 
 			b, err := dns.PackMessage(r.msg)
 			b, err := dns.PackMessage(r.msg)
 			if err != nil {
 			if err != nil {
-				newError("failed to pack dns query").Base(err).AtError().WriteToLog()
+				errors.LogErrorInner(ctx, err, "failed to pack dns query")
 				return
 				return
 			}
 			}
 
 
 			conn, err := s.dial(dnsCtx)
 			conn, err := s.dial(dnsCtx)
 			if err != nil {
 			if err != nil {
-				newError("failed to dial namesever").Base(err).AtError().WriteToLog()
+				errors.LogErrorInner(ctx, err, "failed to dial namesever")
 				return
 				return
 			}
 			}
 			defer conn.Close()
 			defer conn.Close()
@@ -236,7 +237,7 @@ func (s *TCPNameServer) sendQuery(ctx context.Context, domain string, clientIP n
 
 
 			_, err = conn.Write(dnsReqBuf.Bytes())
 			_, err = conn.Write(dnsReqBuf.Bytes())
 			if err != nil {
 			if err != nil {
-				newError("failed to send query").Base(err).AtError().WriteToLog()
+				errors.LogErrorInner(ctx, err, "failed to send query")
 				return
 				return
 			}
 			}
 			dnsReqBuf.Release()
 			dnsReqBuf.Release()
@@ -245,25 +246,25 @@ func (s *TCPNameServer) sendQuery(ctx context.Context, domain string, clientIP n
 			defer respBuf.Release()
 			defer respBuf.Release()
 			n, err := respBuf.ReadFullFrom(conn, 2)
 			n, err := respBuf.ReadFullFrom(conn, 2)
 			if err != nil && n == 0 {
 			if err != nil && n == 0 {
-				newError("failed to read response length").Base(err).AtError().WriteToLog()
+				errors.LogErrorInner(ctx, err, "failed to read response length")
 				return
 				return
 			}
 			}
 			var length int16
 			var length int16
 			err = binary.Read(bytes.NewReader(respBuf.Bytes()), binary.BigEndian, &length)
 			err = binary.Read(bytes.NewReader(respBuf.Bytes()), binary.BigEndian, &length)
 			if err != nil {
 			if err != nil {
-				newError("failed to parse response length").Base(err).AtError().WriteToLog()
+				errors.LogErrorInner(ctx, err, "failed to parse response length")
 				return
 				return
 			}
 			}
 			respBuf.Clear()
 			respBuf.Clear()
 			n, err = respBuf.ReadFullFrom(conn, int32(length))
 			n, err = respBuf.ReadFullFrom(conn, int32(length))
 			if err != nil && n == 0 {
 			if err != nil && n == 0 {
-				newError("failed to read response length").Base(err).AtError().WriteToLog()
+				errors.LogErrorInner(ctx, err, "failed to read response length")
 				return
 				return
 			}
 			}
 
 
 			rec, err := parseResponse(respBuf.Bytes())
 			rec, err := parseResponse(respBuf.Bytes())
 			if err != nil {
 			if err != nil {
-				newError("failed to parse DNS over TCP response").Base(err).AtError().WriteToLog()
+				errors.LogErrorInner(ctx, err, "failed to parse DNS over TCP response")
 				return
 				return
 			}
 			}
 
 
@@ -319,11 +320,11 @@ func (s *TCPNameServer) QueryIP(ctx context.Context, domain string, clientIP net
 	}
 	}
 
 
 	if disableCache {
 	if disableCache {
-		newError("DNS cache is disabled. Querying IP for ", domain, " at ", s.name).AtDebug().WriteToLog()
+		errors.LogDebug(ctx, "DNS cache is disabled. Querying IP for ", domain, " at ", s.name)
 	} else {
 	} else {
 		ips, err := s.findIPsForDomain(fqdn, option)
 		ips, err := s.findIPsForDomain(fqdn, option)
 		if err != errRecordNotFound {
 		if err != errRecordNotFound {
-			newError(s.name, " cache HIT ", domain, " -> ", ips).Base(err).AtDebug().WriteToLog()
+			errors.LogDebugInner(ctx, err, s.name, " cache HIT ", domain, " -> ", ips)
 			log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err})
 			log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err})
 			return ips, err
 			return ips, err
 		}
 		}

+ 11 - 11
app/dns/nameserver_udp.go

@@ -8,11 +8,11 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/log"
 	"github.com/xtls/xray-core/common/log"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/protocol/dns"
 	"github.com/xtls/xray-core/common/protocol/dns"
 	udp_proto "github.com/xtls/xray-core/common/protocol/udp"
 	udp_proto "github.com/xtls/xray-core/common/protocol/udp"
-	"github.com/xtls/xray-core/common/session"
 	"github.com/xtls/xray-core/common/signal/pubsub"
 	"github.com/xtls/xray-core/common/signal/pubsub"
 	"github.com/xtls/xray-core/common/task"
 	"github.com/xtls/xray-core/common/task"
 	dns_feature "github.com/xtls/xray-core/features/dns"
 	dns_feature "github.com/xtls/xray-core/features/dns"
@@ -53,7 +53,7 @@ func NewClassicNameServer(address net.Destination, dispatcher routing.Dispatcher
 		Execute:  s.Cleanup,
 		Execute:  s.Cleanup,
 	}
 	}
 	s.udpServer = udp.NewDispatcher(dispatcher, s.HandleResponse)
 	s.udpServer = udp.NewDispatcher(dispatcher, s.HandleResponse)
-	newError("DNS: created UDP client initialized for ", address.NetAddr()).AtInfo().WriteToLog()
+	errors.LogInfo(context.Background(), "DNS: created UDP client initialized for ", address.NetAddr())
 	return s
 	return s
 }
 }
 
 
@@ -69,7 +69,7 @@ func (s *ClassicNameServer) Cleanup() error {
 	defer s.Unlock()
 	defer s.Unlock()
 
 
 	if len(s.ips) == 0 && len(s.requests) == 0 {
 	if len(s.ips) == 0 && len(s.requests) == 0 {
-		return newError(s.name, " nothing to do. stopping...")
+		return errors.New(s.name, " nothing to do. stopping...")
 	}
 	}
 
 
 	for domain, record := range s.ips {
 	for domain, record := range s.ips {
@@ -81,7 +81,7 @@ func (s *ClassicNameServer) Cleanup() error {
 		}
 		}
 
 
 		if record.A == nil && record.AAAA == nil {
 		if record.A == nil && record.AAAA == nil {
-			newError(s.name, " cleanup ", domain).AtDebug().WriteToLog()
+			errors.LogDebug(context.Background(), s.name, " cleanup ", domain)
 			delete(s.ips, domain)
 			delete(s.ips, domain)
 		} else {
 		} else {
 			s.ips[domain] = record
 			s.ips[domain] = record
@@ -109,7 +109,7 @@ func (s *ClassicNameServer) Cleanup() error {
 func (s *ClassicNameServer) HandleResponse(ctx context.Context, packet *udp_proto.Packet) {
 func (s *ClassicNameServer) HandleResponse(ctx context.Context, packet *udp_proto.Packet) {
 	ipRec, err := parseResponse(packet.Payload.Bytes())
 	ipRec, err := parseResponse(packet.Payload.Bytes())
 	if err != nil {
 	if err != nil {
-		newError(s.name, " fail to parse responded DNS udp").AtError().WriteToLog()
+		errors.LogError(ctx, s.name, " fail to parse responded DNS udp")
 		return
 		return
 	}
 	}
 
 
@@ -122,7 +122,7 @@ func (s *ClassicNameServer) HandleResponse(ctx context.Context, packet *udp_prot
 	}
 	}
 	s.Unlock()
 	s.Unlock()
 	if !ok {
 	if !ok {
-		newError(s.name, " cannot find the pending request").AtError().WriteToLog()
+		errors.LogError(ctx, s.name, " cannot find the pending request")
 		return
 		return
 	}
 	}
 
 
@@ -135,7 +135,7 @@ func (s *ClassicNameServer) HandleResponse(ctx context.Context, packet *udp_prot
 	}
 	}
 
 
 	elapsed := time.Since(req.start)
 	elapsed := time.Since(req.start)
-	newError(s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed).AtInfo().WriteToLog()
+	errors.LogInfo(ctx, s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed)
 	if len(req.domain) > 0 && (rec.A != nil || rec.AAAA != nil) {
 	if len(req.domain) > 0 && (rec.A != nil || rec.AAAA != nil) {
 		s.updateIP(req.domain, &rec)
 		s.updateIP(req.domain, &rec)
 	}
 	}
@@ -160,7 +160,7 @@ func (s *ClassicNameServer) updateIP(domain string, newRec *record) {
 	}
 	}
 
 
 	if updated {
 	if updated {
-		newError(s.name, " updating IP records for domain:", domain).AtDebug().WriteToLog()
+		errors.LogDebug(context.Background(), s.name, " updating IP records for domain:", domain)
 		s.ips[domain] = rec
 		s.ips[domain] = rec
 	}
 	}
 	if newRec.A != nil {
 	if newRec.A != nil {
@@ -187,7 +187,7 @@ func (s *ClassicNameServer) addPendingRequest(req *dnsRequest) {
 }
 }
 
 
 func (s *ClassicNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) {
 func (s *ClassicNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) {
-	newError(s.name, " querying DNS for: ", domain).AtDebug().WriteToLog(session.ExportIDToError(ctx))
+	errors.LogDebug(ctx, s.name, " querying DNS for: ", domain)
 
 
 	reqs := buildReqMsgs(domain, option, s.newReqID, genEDNS0Options(clientIP))
 	reqs := buildReqMsgs(domain, option, s.newReqID, genEDNS0Options(clientIP))
 
 
@@ -241,11 +241,11 @@ func (s *ClassicNameServer) QueryIP(ctx context.Context, domain string, clientIP
 	fqdn := Fqdn(domain)
 	fqdn := Fqdn(domain)
 
 
 	if disableCache {
 	if disableCache {
-		newError("DNS cache is disabled. Querying IP for ", domain, " at ", s.name).AtDebug().WriteToLog()
+		errors.LogDebug(ctx, "DNS cache is disabled. Querying IP for ", domain, " at ", s.name)
 	} else {
 	} else {
 		ips, err := s.findIPsForDomain(fqdn, option)
 		ips, err := s.findIPsForDomain(fqdn, option)
 		if err != errRecordNotFound {
 		if err != errRecordNotFound {
-			newError(s.name, " cache HIT ", domain, " -> ", ips).Base(err).AtDebug().WriteToLog()
+			errors.LogDebugInner(ctx, err, s.name, " cache HIT ", domain, " -> ", ips)
 			log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err})
 			log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err})
 			return ips, err
 			return ips, err
 		}
 		}

+ 4 - 3
app/log/command/command.go

@@ -7,6 +7,7 @@ import (
 
 
 	"github.com/xtls/xray-core/app/log"
 	"github.com/xtls/xray-core/app/log"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/core"
 	grpc "google.golang.org/grpc"
 	grpc "google.golang.org/grpc"
 )
 )
@@ -19,13 +20,13 @@ type LoggerServer struct {
 func (s *LoggerServer) RestartLogger(ctx context.Context, request *RestartLoggerRequest) (*RestartLoggerResponse, error) {
 func (s *LoggerServer) RestartLogger(ctx context.Context, request *RestartLoggerRequest) (*RestartLoggerResponse, error) {
 	logger := s.V.GetFeature((*log.Instance)(nil))
 	logger := s.V.GetFeature((*log.Instance)(nil))
 	if logger == nil {
 	if logger == nil {
-		return nil, newError("unable to get logger instance")
+		return nil, errors.New("unable to get logger instance")
 	}
 	}
 	if err := logger.Close(); err != nil {
 	if err := logger.Close(); err != nil {
-		return nil, newError("failed to close logger").Base(err)
+		return nil, errors.New("failed to close logger").Base(err)
 	}
 	}
 	if err := logger.Start(); err != nil {
 	if err := logger.Start(); err != nil {
-		return nil, newError("failed to start logger").Base(err)
+		return nil, errors.New("failed to start logger").Base(err)
 	}
 	}
 	return &RestartLoggerResponse{}, nil
 	return &RestartLoggerResponse{}, nil
 }
 }

+ 0 - 9
app/log/command/errors.generated.go

@@ -1,9 +0,0 @@
-package command
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 0 - 9
app/log/errors.generated.go

@@ -1,9 +0,0 @@
-package log
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 5 - 4
app/log/log.go

@@ -7,6 +7,7 @@ import (
 	"sync"
 	"sync"
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/log"
 	"github.com/xtls/xray-core/common/log"
 )
 )
 
 
@@ -35,7 +36,7 @@ func New(ctx context.Context, config *Config) (*Instance, error) {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	newError("Logger started").AtDebug().WriteToLog()
+	errors.LogDebug(ctx, "Logger started")
 	return g, nil
 	return g, nil
 }
 }
 
 
@@ -77,10 +78,10 @@ func (g *Instance) startInternal() error {
 	g.active = true
 	g.active = true
 
 
 	if err := g.initAccessLogger(); err != nil {
 	if err := g.initAccessLogger(); err != nil {
-		return newError("failed to initialize access logger").Base(err).AtWarning()
+		return errors.New("failed to initialize access logger").Base(err).AtWarning()
 	}
 	}
 	if err := g.initErrorLogger(); err != nil {
 	if err := g.initErrorLogger(); err != nil {
-		return newError("failed to initialize error logger").Base(err).AtWarning()
+		return errors.New("failed to initialize error logger").Base(err).AtWarning()
 	}
 	}
 
 
 	return nil
 	return nil
@@ -120,7 +121,7 @@ func (g *Instance) Handle(msg log.Message) {
 
 
 // Close implements common.Closable.Close().
 // Close implements common.Closable.Close().
 func (g *Instance) Close() error {
 func (g *Instance) Close() error {
-	newError("Logger closing").AtDebug().WriteToLog()
+	errors.LogDebug(context.Background(), "Logger closing")
 
 
 	g.Lock()
 	g.Lock()
 	defer g.Unlock()
 	defer g.Unlock()

+ 3 - 2
app/log/log_creator.go

@@ -4,6 +4,7 @@ import (
 	"sync"
 	"sync"
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/log"
 	"github.com/xtls/xray-core/common/log"
 )
 )
 
 
@@ -19,7 +20,7 @@ var handlerCreatorMapLock = &sync.RWMutex{}
 
 
 func RegisterHandlerCreator(logType LogType, f HandlerCreator) error {
 func RegisterHandlerCreator(logType LogType, f HandlerCreator) error {
 	if f == nil {
 	if f == nil {
-		return newError("nil HandlerCreator")
+		return errors.New("nil HandlerCreator")
 	}
 	}
 
 
 	handlerCreatorMapLock.Lock()
 	handlerCreatorMapLock.Lock()
@@ -35,7 +36,7 @@ func createHandler(logType LogType, options HandlerCreatorOptions) (log.Handler,
 
 
 	creator, found := handlerCreatorMap[logType]
 	creator, found := handlerCreatorMap[logType]
 	if !found {
 	if !found {
-		return nil, newError("unable to create log handler for ", logType)
+		return nil, errors.New("unable to create log handler for ", logType)
 	}
 	}
 	return creator(logType, options)
 	return creator(logType, options)
 }
 }

+ 0 - 9
app/metrics/errors.generated.go

@@ -1,9 +0,0 @@
-package metrics
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 3 - 2
app/metrics/metrics.go

@@ -10,6 +10,7 @@ import (
 	"github.com/xtls/xray-core/app/observatory"
 	"github.com/xtls/xray-core/app/observatory"
 	"github.com/xtls/xray-core/app/stats"
 	"github.com/xtls/xray-core/app/stats"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/signal/done"
 	"github.com/xtls/xray-core/common/signal/done"
 	"github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/core"
@@ -93,12 +94,12 @@ func (p *MetricsHandler) Start() error {
 
 
 	go func() {
 	go func() {
 		if err := http.Serve(listener, http.DefaultServeMux); err != nil {
 		if err := http.Serve(listener, http.DefaultServeMux); err != nil {
-			newError("failed to start metrics server").Base(err).AtError().WriteToLog()
+			errors.LogErrorInner(context.Background(), err, "failed to start metrics server")
 		}
 		}
 	}()
 	}()
 
 
 	if err := p.ohm.RemoveHandler(context.Background(), p.tag); err != nil {
 	if err := p.ohm.RemoveHandler(context.Background(), p.tag); err != nil {
-		newError("failed to remove existing handler").WriteToLog()
+		errors.LogInfo(context.Background(), "failed to remove existing handler")
 	}
 	}
 
 
 	return p.ohm.AddHandler(context.Background(), &Outbound{
 	return p.ohm.AddHandler(context.Background(), &Outbound{

+ 2 - 1
app/metrics/outbound.go

@@ -5,6 +5,7 @@ import (
 	"sync"
 	"sync"
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net/cnc"
 	"github.com/xtls/xray-core/common/net/cnc"
 	"github.com/xtls/xray-core/common/signal/done"
 	"github.com/xtls/xray-core/common/signal/done"
@@ -31,7 +32,7 @@ func (l *OutboundListener) add(conn net.Conn) {
 func (l *OutboundListener) Accept() (net.Conn, error) {
 func (l *OutboundListener) Accept() (net.Conn, error) {
 	select {
 	select {
 	case <-l.done.Wait():
 	case <-l.done.Wait():
-		return nil, newError("listen closed")
+		return nil, errors.New("listen closed")
 	case c := <-l.buffer:
 	case c := <-l.buffer:
 		return c, nil
 		return c, nil
 	}
 	}

+ 7 - 5
app/observatory/burst/burstobserver.go

@@ -2,15 +2,17 @@ package burst
 
 
 import (
 import (
 	"context"
 	"context"
-	
-	"github.com/xtls/xray-core/core"
+
+	"sync"
+
 	"github.com/xtls/xray-core/app/observatory"
 	"github.com/xtls/xray-core/app/observatory"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/signal/done"
 	"github.com/xtls/xray-core/common/signal/done"
+	"github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/features/extension"
 	"github.com/xtls/xray-core/features/extension"
 	"github.com/xtls/xray-core/features/outbound"
 	"github.com/xtls/xray-core/features/outbound"
 	"google.golang.org/protobuf/proto"
 	"google.golang.org/protobuf/proto"
-	"sync"
 )
 )
 
 
 type Observer struct {
 type Observer struct {
@@ -66,7 +68,7 @@ func (o *Observer) Start() error {
 			hs, ok := o.ohm.(outbound.HandlerSelector)
 			hs, ok := o.ohm.(outbound.HandlerSelector)
 			if !ok {
 			if !ok {
 
 
-				return nil, newError("outbound.Manager is not a HandlerSelector")
+				return nil, errors.New("outbound.Manager is not a HandlerSelector")
 			}
 			}
 
 
 			outbounds := hs.Select(o.config.SubjectSelector)
 			outbounds := hs.Select(o.config.SubjectSelector)
@@ -90,7 +92,7 @@ func New(ctx context.Context, config *Config) (*Observer, error) {
 		outboundManager = om
 		outboundManager = om
 	})
 	})
 	if err != nil {
 	if err != nil {
-		return nil, newError("Cannot get depended features").Base(err)
+		return nil, errors.New("Cannot get depended features").Base(err)
 	}
 	}
 	hp := NewHealthPing(ctx, config.PingConfig)
 	hp := NewHealthPing(ctx, config.PingConfig)
 	return &Observer{
 	return &Observer{

+ 0 - 9
app/observatory/burst/errors.generated.go

@@ -1,9 +0,0 @@
-package burst
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 9 - 8
app/observatory/burst/healthping.go

@@ -8,6 +8,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/xtls/xray-core/common/dice"
 	"github.com/xtls/xray-core/common/dice"
+	"github.com/xtls/xray-core/common/errors"
 )
 )
 
 
 // HealthPingSettings holds settings for health Checker
 // HealthPingSettings holds settings for health Checker
@@ -51,7 +52,7 @@ func NewHealthPing(ctx context.Context, config *HealthPingConfig) *HealthPing {
 	if settings.Interval == 0 {
 	if settings.Interval == 0 {
 		settings.Interval = time.Duration(1) * time.Minute
 		settings.Interval = time.Duration(1) * time.Minute
 	} else if settings.Interval < 10 {
 	} else if settings.Interval < 10 {
-		newError("health check interval is too small, 10s is applied").AtWarning().WriteToLog()
+		errors.LogWarning(ctx, "health check interval is too small, 10s is applied")
 		settings.Interval = time.Duration(10) * time.Second
 		settings.Interval = time.Duration(10) * time.Second
 	}
 	}
 	if settings.SamplingCount <= 0 {
 	if settings.SamplingCount <= 0 {
@@ -82,7 +83,7 @@ func (h *HealthPing) StartScheduler(selector func() ([]string, error)) {
 	go func() {
 	go func() {
 		tags, err := selector()
 		tags, err := selector()
 		if err != nil {
 		if err != nil {
-			newError("error select outbounds for initial health check: ", err).AtWarning().WriteToLog()
+			errors.LogWarning(h.ctx, "error select outbounds for initial health check: ", err)
 			return
 			return
 		}
 		}
 		h.Check(tags)
 		h.Check(tags)
@@ -93,7 +94,7 @@ func (h *HealthPing) StartScheduler(selector func() ([]string, error)) {
 			go func() {
 			go func() {
 				tags, err := selector()
 				tags, err := selector()
 				if err != nil {
 				if err != nil {
-					newError("error select outbounds for scheduled health check: ", err).AtWarning().WriteToLog()
+					errors.LogWarning(h.ctx, "error select outbounds for scheduled health check: ", err)
 					return
 					return
 				}
 				}
 				h.doCheck(tags, interval, h.Settings.SamplingCount)
 				h.doCheck(tags, interval, h.Settings.SamplingCount)
@@ -125,7 +126,7 @@ func (h *HealthPing) Check(tags []string) error {
 	if len(tags) == 0 {
 	if len(tags) == 0 {
 		return nil
 		return nil
 	}
 	}
-	newError("perform one-time health check for tags ", tags).AtInfo().WriteToLog()
+	errors.LogInfo(h.ctx, "perform one-time health check for tags ", tags)
 	h.doCheck(tags, 0, 1)
 	h.doCheck(tags, 0, 1)
 	return nil
 	return nil
 }
 }
@@ -158,7 +159,7 @@ func (h *HealthPing) doCheck(tags []string, duration time.Duration, rounds int)
 				delay = time.Duration(dice.Roll(int(duration)))
 				delay = time.Duration(dice.Roll(int(duration)))
 			}
 			}
 			time.AfterFunc(delay, func() {
 			time.AfterFunc(delay, func() {
-				newError("checking ", handler).AtDebug().WriteToLog()
+				errors.LogDebug(h.ctx, "checking ", handler)
 				delay, err := client.MeasureDelay()
 				delay, err := client.MeasureDelay()
 				if err == nil {
 				if err == nil {
 					ch <- &rtt{
 					ch <- &rtt{
@@ -168,19 +169,19 @@ func (h *HealthPing) doCheck(tags []string, duration time.Duration, rounds int)
 					return
 					return
 				}
 				}
 				if !h.checkConnectivity() {
 				if !h.checkConnectivity() {
-					newError("network is down").AtWarning().WriteToLog()
+					errors.LogWarning(h.ctx, "network is down")
 					ch <- &rtt{
 					ch <- &rtt{
 						handler: handler,
 						handler: handler,
 						value:   0,
 						value:   0,
 					}
 					}
 					return
 					return
 				}
 				}
-				newError(fmt.Sprintf(
+				errors.LogWarning(h.ctx, fmt.Sprintf(
 					"error ping %s with %s: %s",
 					"error ping %s with %s: %s",
 					h.Settings.Destination,
 					h.Settings.Destination,
 					handler,
 					handler,
 					err,
 					err,
-				)).AtWarning().WriteToLog()
+				))
 				ch <- &rtt{
 				ch <- &rtt{
 					handler: handler,
 					handler: handler,
 					value:   rttFailed,
 					value:   rttFailed,

+ 0 - 9
app/observatory/errors.generated.go

@@ -1,9 +0,0 @@
-package observatory
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 3 - 3
app/observatory/explainErrors.go

@@ -8,10 +8,10 @@ type errorCollector struct {
 
 
 func (e *errorCollector) SubmitError(err error) {
 func (e *errorCollector) SubmitError(err error) {
 	if e.errors == nil {
 	if e.errors == nil {
-		e.errors = newError("underlying connection error").Base(err)
+		e.errors = errors.New("underlying connection error").Base(err)
 		return
 		return
 	}
 	}
-	e.errors = e.errors.Base(newError("underlying connection error").Base(err))
+	e.errors = e.errors.Base(errors.New("underlying connection error").Base(err))
 }
 }
 
 
 func newErrorCollector() *errorCollector {
 func newErrorCollector() *errorCollector {
@@ -20,7 +20,7 @@ func newErrorCollector() *errorCollector {
 
 
 func (e *errorCollector) UnderlyingError() error {
 func (e *errorCollector) UnderlyingError() error {
 	if e.errors == nil {
 	if e.errors == nil {
-		return newError("failed to produce report")
+		return errors.New("failed to produce report")
 	}
 	}
 	return e.errors
 	return e.errors
 }
 }

+ 11 - 14
app/observatory/observer.go

@@ -10,6 +10,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	v2net "github.com/xtls/xray-core/common/net"
 	v2net "github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/session"
 	"github.com/xtls/xray-core/common/session"
 	"github.com/xtls/xray-core/common/signal/done"
 	"github.com/xtls/xray-core/common/signal/done"
@@ -60,7 +61,7 @@ func (o *Observer) background() {
 	for !o.finished.Done() {
 	for !o.finished.Done() {
 		hs, ok := o.ohm.(outbound.HandlerSelector)
 		hs, ok := o.ohm.(outbound.HandlerSelector)
 		if !ok {
 		if !ok {
-			newError("outbound.Manager is not a HandlerSelector").WriteToLog()
+			errors.LogInfo(o.ctx, "outbound.Manager is not a HandlerSelector")
 			return
 			return
 		}
 		}
 
 
@@ -127,18 +128,18 @@ func (o *Observer) probe(outbound string) ProbeResult {
 				// MUST use Xray's built in context system
 				// MUST use Xray's built in context system
 				dest, err := v2net.ParseDestination(network + ":" + addr)
 				dest, err := v2net.ParseDestination(network + ":" + addr)
 				if err != nil {
 				if err != nil {
-					return newError("cannot understand address").Base(err)
+					return errors.New("cannot understand address").Base(err)
 				}
 				}
 				trackedCtx := session.TrackedConnectionError(o.ctx, errorCollectorForRequest)
 				trackedCtx := session.TrackedConnectionError(o.ctx, errorCollectorForRequest)
 				conn, err := tagged.Dialer(trackedCtx, dest, outbound)
 				conn, err := tagged.Dialer(trackedCtx, dest, outbound)
 				if err != nil {
 				if err != nil {
-					return newError("cannot dial remote address ", dest).Base(err)
+					return errors.New("cannot dial remote address ", dest).Base(err)
 				}
 				}
 				connection = conn
 				connection = conn
 				return nil
 				return nil
 			})
 			})
 			if taskErr != nil {
 			if taskErr != nil {
-				return nil, newError("cannot finish connection").Base(taskErr)
+				return nil, errors.New("cannot finish connection").Base(taskErr)
 			}
 			}
 			return connection, nil
 			return connection, nil
 		},
 		},
@@ -161,7 +162,7 @@ func (o *Observer) probe(outbound string) ProbeResult {
 		}
 		}
 		response, err := httpClient.Get(probeURL)
 		response, err := httpClient.Get(probeURL)
 		if err != nil {
 		if err != nil {
-			return newError("outbound failed to relay connection").Base(err)
+			return errors.New("outbound failed to relay connection").Base(err)
 		}
 		}
 		if response.Body != nil {
 		if response.Body != nil {
 			response.Body.Close()
 			response.Body.Close()
@@ -171,15 +172,11 @@ func (o *Observer) probe(outbound string) ProbeResult {
 		return nil
 		return nil
 	})
 	})
 	if err != nil {
 	if err != nil {
-		fullerr := newError("underlying connection failed").Base(errorCollectorForRequest.UnderlyingError())
-		fullerr = newError("with outbound handler report").Base(fullerr)
-		fullerr = newError("GET request failed:", err).Base(fullerr)
-		fullerr = newError("the outbound ", outbound, " is dead:").Base(fullerr)
-		fullerr = fullerr.AtInfo()
-		fullerr.WriteToLog()
-		return ProbeResult{Alive: false, LastErrorReason: fullerr.Error()}
+		var errorMessage = "the outbound " + outbound + " is dead: GET request failed:" + err.Error() + "with outbound handler report underlying connection failed"
+		errors.LogInfoInner(o.ctx, errorCollectorForRequest.UnderlyingError(), errorMessage)
+		return ProbeResult{Alive: false, LastErrorReason: errorMessage}
 	}
 	}
-	newError("the outbound ", outbound, " is alive:", GETTime.Seconds()).AtInfo().WriteToLog()
+	errors.LogInfo(o.ctx, "the outbound ", outbound, " is alive:", GETTime.Seconds())
 	return ProbeResult{Alive: true, Delay: GETTime.Milliseconds()}
 	return ProbeResult{Alive: true, Delay: GETTime.Milliseconds()}
 }
 }
 
 
@@ -222,7 +219,7 @@ func New(ctx context.Context, config *Config) (*Observer, error) {
 		outboundManager = om
 		outboundManager = om
 	})
 	})
 	if err != nil {
 	if err != nil {
-		return nil, newError("Cannot get depended features").Base(err)
+		return nil, errors.New("Cannot get depended features").Base(err)
 	}
 	}
 	return &Observer{
 	return &Observer{
 		config: config,
 		config: config,

+ 0 - 9
app/policy/errors.generated.go

@@ -1,9 +0,0 @@
-package policy
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 10 - 9
app/proxyman/command/command.go

@@ -4,6 +4,7 @@ import (
 	"context"
 	"context"
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/features/inbound"
 	"github.com/xtls/xray-core/features/inbound"
 	"github.com/xtls/xray-core/features/outbound"
 	"github.com/xtls/xray-core/features/outbound"
@@ -26,7 +27,7 @@ type OutboundOperation interface {
 func getInbound(handler inbound.Handler) (proxy.Inbound, error) {
 func getInbound(handler inbound.Handler) (proxy.Inbound, error) {
 	gi, ok := handler.(proxy.GetInbound)
 	gi, ok := handler.(proxy.GetInbound)
 	if !ok {
 	if !ok {
-		return nil, newError("can't get inbound proxy from handler.")
+		return nil, errors.New("can't get inbound proxy from handler.")
 	}
 	}
 	return gi.GetInbound(), nil
 	return gi.GetInbound(), nil
 }
 }
@@ -39,11 +40,11 @@ func (op *AddUserOperation) ApplyInbound(ctx context.Context, handler inbound.Ha
 	}
 	}
 	um, ok := p.(proxy.UserManager)
 	um, ok := p.(proxy.UserManager)
 	if !ok {
 	if !ok {
-		return newError("proxy is not a UserManager")
+		return errors.New("proxy is not a UserManager")
 	}
 	}
 	mUser, err := op.User.ToMemoryUser()
 	mUser, err := op.User.ToMemoryUser()
 	if err != nil {
 	if err != nil {
-		return newError("failed to parse user").Base(err)
+		return errors.New("failed to parse user").Base(err)
 	}
 	}
 	return um.AddUser(ctx, mUser)
 	return um.AddUser(ctx, mUser)
 }
 }
@@ -56,7 +57,7 @@ func (op *RemoveUserOperation) ApplyInbound(ctx context.Context, handler inbound
 	}
 	}
 	um, ok := p.(proxy.UserManager)
 	um, ok := p.(proxy.UserManager)
 	if !ok {
 	if !ok {
-		return newError("proxy is not a UserManager")
+		return errors.New("proxy is not a UserManager")
 	}
 	}
 	return um.RemoveUser(ctx, op.Email)
 	return um.RemoveUser(ctx, op.Email)
 }
 }
@@ -82,16 +83,16 @@ func (s *handlerServer) RemoveInbound(ctx context.Context, request *RemoveInboun
 func (s *handlerServer) AlterInbound(ctx context.Context, request *AlterInboundRequest) (*AlterInboundResponse, error) {
 func (s *handlerServer) AlterInbound(ctx context.Context, request *AlterInboundRequest) (*AlterInboundResponse, error) {
 	rawOperation, err := request.Operation.GetInstance()
 	rawOperation, err := request.Operation.GetInstance()
 	if err != nil {
 	if err != nil {
-		return nil, newError("unknown operation").Base(err)
+		return nil, errors.New("unknown operation").Base(err)
 	}
 	}
 	operation, ok := rawOperation.(InboundOperation)
 	operation, ok := rawOperation.(InboundOperation)
 	if !ok {
 	if !ok {
-		return nil, newError("not an inbound operation")
+		return nil, errors.New("not an inbound operation")
 	}
 	}
 
 
 	handler, err := s.ihm.GetHandler(ctx, request.Tag)
 	handler, err := s.ihm.GetHandler(ctx, request.Tag)
 	if err != nil {
 	if err != nil {
-		return nil, newError("failed to get handler: ", request.Tag).Base(err)
+		return nil, errors.New("failed to get handler: ", request.Tag).Base(err)
 	}
 	}
 
 
 	return &AlterInboundResponse{}, operation.ApplyInbound(ctx, handler)
 	return &AlterInboundResponse{}, operation.ApplyInbound(ctx, handler)
@@ -111,11 +112,11 @@ func (s *handlerServer) RemoveOutbound(ctx context.Context, request *RemoveOutbo
 func (s *handlerServer) AlterOutbound(ctx context.Context, request *AlterOutboundRequest) (*AlterOutboundResponse, error) {
 func (s *handlerServer) AlterOutbound(ctx context.Context, request *AlterOutboundRequest) (*AlterOutboundResponse, error) {
 	rawOperation, err := request.Operation.GetInstance()
 	rawOperation, err := request.Operation.GetInstance()
 	if err != nil {
 	if err != nil {
-		return nil, newError("unknown operation").Base(err)
+		return nil, errors.New("unknown operation").Base(err)
 	}
 	}
 	operation, ok := rawOperation.(OutboundOperation)
 	operation, ok := rawOperation.(OutboundOperation)
 	if !ok {
 	if !ok {
-		return nil, newError("not an outbound operation")
+		return nil, errors.New("not an outbound operation")
 	}
 	}
 
 
 	handler := s.ohm.GetHandler(request.Tag)
 	handler := s.ohm.GetHandler(request.Tag)

+ 0 - 9
app/proxyman/command/errors.generated.go

@@ -1,9 +0,0 @@
-package command
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 5 - 5
app/proxyman/inbound/always.go

@@ -55,7 +55,7 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *
 	}
 	}
 	p, ok := rawProxy.(proxy.Inbound)
 	p, ok := rawProxy.(proxy.Inbound)
 	if !ok {
 	if !ok {
-		return nil, newError("not an inbound proxy.")
+		return nil, errors.New("not an inbound proxy.")
 	}
 	}
 
 
 	h := &AlwaysOnInboundHandler{
 	h := &AlwaysOnInboundHandler{
@@ -75,7 +75,7 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *
 
 
 	mss, err := internet.ToMemoryStreamConfig(receiverConfig.StreamSettings)
 	mss, err := internet.ToMemoryStreamConfig(receiverConfig.StreamSettings)
 	if err != nil {
 	if err != nil {
-		return nil, newError("failed to parse stream config").Base(err).AtWarning()
+		return nil, errors.New("failed to parse stream config").Base(err).AtWarning()
 	}
 	}
 
 
 	if receiverConfig.ReceiveOriginalDestination {
 	if receiverConfig.ReceiveOriginalDestination {
@@ -89,7 +89,7 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *
 	}
 	}
 	if pl == nil {
 	if pl == nil {
 		if net.HasNetwork(nl, net.Network_UNIX) {
 		if net.HasNetwork(nl, net.Network_UNIX) {
-			newError("creating unix domain socket worker on ", address).AtDebug().WriteToLog()
+			errors.LogDebug(ctx, "creating unix domain socket worker on ", address)
 
 
 			worker := &dsWorker{
 			worker := &dsWorker{
 				address:         address,
 				address:         address,
@@ -109,7 +109,7 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *
 		for _, pr := range pl.Range {
 		for _, pr := range pl.Range {
 			for port := pr.From; port <= pr.To; port++ {
 			for port := pr.From; port <= pr.To; port++ {
 				if net.HasNetwork(nl, net.Network_TCP) {
 				if net.HasNetwork(nl, net.Network_TCP) {
-					newError("creating stream worker on ", address, ":", port).AtDebug().WriteToLog()
+					errors.LogDebug(ctx, "creating stream worker on ", address, ":", port)
 
 
 					worker := &tcpWorker{
 					worker := &tcpWorker{
 						address:         address,
 						address:         address,
@@ -167,7 +167,7 @@ func (h *AlwaysOnInboundHandler) Close() error {
 	}
 	}
 	errs = append(errs, h.mux.Close())
 	errs = append(errs, h.mux.Close())
 	if err := errors.Combine(errs...); err != nil {
 	if err := errors.Combine(errs...); err != nil {
-		return newError("failed to close all resources").Base(err)
+		return errors.New("failed to close all resources").Base(err)
 	}
 	}
 	return nil
 	return nil
 }
 }

+ 6 - 5
app/proxyman/inbound/dynamic.go

@@ -7,6 +7,7 @@ import (
 
 
 	"github.com/xtls/xray-core/app/proxyman"
 	"github.com/xtls/xray-core/app/proxyman"
 	"github.com/xtls/xray-core/common/dice"
 	"github.com/xtls/xray-core/common/dice"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/mux"
 	"github.com/xtls/xray-core/common/mux"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/task"
 	"github.com/xtls/xray-core/common/task"
@@ -46,7 +47,7 @@ func NewDynamicInboundHandler(ctx context.Context, tag string, receiverConfig *p
 
 
 	mss, err := internet.ToMemoryStreamConfig(receiverConfig.StreamSettings)
 	mss, err := internet.ToMemoryStreamConfig(receiverConfig.StreamSettings)
 	if err != nil {
 	if err != nil {
-		return nil, newError("failed to parse stream settings").Base(err).AtWarning()
+		return nil, errors.New("failed to parse stream settings").Base(err).AtWarning()
 	}
 	}
 	if receiverConfig.ReceiveOriginalDestination {
 	if receiverConfig.ReceiveOriginalDestination {
 		if mss.SocketSettings == nil {
 		if mss.SocketSettings == nil {
@@ -94,7 +95,7 @@ func (h *DynamicInboundHandler) closeWorkers(workers []worker) {
 	for idx, worker := range workers {
 	for idx, worker := range workers {
 		ports2Del[idx] = worker.Port()
 		ports2Del[idx] = worker.Port()
 		if err := worker.Close(); err != nil {
 		if err := worker.Close(); err != nil {
-			newError("failed to close worker").Base(err).WriteToLog()
+			errors.LogInfoInner(h.ctx, err, "failed to close worker")
 		}
 		}
 	}
 	}
 
 
@@ -123,7 +124,7 @@ func (h *DynamicInboundHandler) refresh() error {
 		port := h.allocatePort()
 		port := h.allocatePort()
 		rawProxy, err := core.CreateObject(h.v, h.proxyConfig)
 		rawProxy, err := core.CreateObject(h.v, h.proxyConfig)
 		if err != nil {
 		if err != nil {
-			newError("failed to create proxy instance").Base(err).AtWarning().WriteToLog()
+			errors.LogWarningInner(h.ctx, err, "failed to create proxy instance")
 			continue
 			continue
 		}
 		}
 		p := rawProxy.(proxy.Inbound)
 		p := rawProxy.(proxy.Inbound)
@@ -143,7 +144,7 @@ func (h *DynamicInboundHandler) refresh() error {
 				ctx:             h.ctx,
 				ctx:             h.ctx,
 			}
 			}
 			if err := worker.Start(); err != nil {
 			if err := worker.Start(); err != nil {
-				newError("failed to create TCP worker").Base(err).AtWarning().WriteToLog()
+				errors.LogWarningInner(h.ctx, err, "failed to create TCP worker")
 				continue
 				continue
 			}
 			}
 			workers = append(workers, worker)
 			workers = append(workers, worker)
@@ -163,7 +164,7 @@ func (h *DynamicInboundHandler) refresh() error {
 				ctx:             h.ctx,
 				ctx:             h.ctx,
 			}
 			}
 			if err := worker.Start(); err != nil {
 			if err := worker.Start(); err != nil {
-				newError("failed to create UDP worker").Base(err).AtWarning().WriteToLog()
+				errors.LogWarningInner(h.ctx, err, "failed to create UDP worker")
 				continue
 				continue
 			}
 			}
 			workers = append(workers, worker)
 			workers = append(workers, worker)

+ 0 - 9
app/proxyman/inbound/errors.generated.go

@@ -1,9 +0,0 @@
-package inbound
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 11 - 10
app/proxyman/inbound/inbound.go

@@ -8,6 +8,7 @@ import (
 
 
 	"github.com/xtls/xray-core/app/proxyman"
 	"github.com/xtls/xray-core/app/proxyman"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/serial"
 	"github.com/xtls/xray-core/common/serial"
 	"github.com/xtls/xray-core/common/session"
 	"github.com/xtls/xray-core/common/session"
 	"github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/core"
@@ -43,7 +44,7 @@ func (m *Manager) AddHandler(ctx context.Context, handler inbound.Handler) error
 	tag := handler.Tag()
 	tag := handler.Tag()
 	if len(tag) > 0 {
 	if len(tag) > 0 {
 		if _, found := m.taggedHandlers[tag]; found {
 		if _, found := m.taggedHandlers[tag]; found {
-			return newError("existing tag found: " + tag)
+			return errors.New("existing tag found: " + tag)
 		}
 		}
 		m.taggedHandlers[tag] = handler
 		m.taggedHandlers[tag] = handler
 	} else {
 	} else {
@@ -64,7 +65,7 @@ func (m *Manager) GetHandler(ctx context.Context, tag string) (inbound.Handler,
 
 
 	handler, found := m.taggedHandlers[tag]
 	handler, found := m.taggedHandlers[tag]
 	if !found {
 	if !found {
-		return nil, newError("handler not found: ", tag)
+		return nil, errors.New("handler not found: ", tag)
 	}
 	}
 	return handler, nil
 	return handler, nil
 }
 }
@@ -80,7 +81,7 @@ func (m *Manager) RemoveHandler(ctx context.Context, tag string) error {
 
 
 	if handler, found := m.taggedHandlers[tag]; found {
 	if handler, found := m.taggedHandlers[tag]; found {
 		if err := handler.Close(); err != nil {
 		if err := handler.Close(); err != nil {
-			newError("failed to close handler ", tag).Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx))
+			errors.LogWarningInner(ctx, err, "failed to close handler ", tag)
 		}
 		}
 		delete(m.taggedHandlers, tag)
 		delete(m.taggedHandlers, tag)
 		return nil
 		return nil
@@ -117,20 +118,20 @@ func (m *Manager) Close() error {
 
 
 	m.running = false
 	m.running = false
 
 
-	var errors []interface{}
+	var errs []interface{}
 	for _, handler := range m.taggedHandlers {
 	for _, handler := range m.taggedHandlers {
 		if err := handler.Close(); err != nil {
 		if err := handler.Close(); err != nil {
-			errors = append(errors, err)
+			errs = append(errs, err)
 		}
 		}
 	}
 	}
 	for _, handler := range m.untaggedHandler {
 	for _, handler := range m.untaggedHandler {
 		if err := handler.Close(); err != nil {
 		if err := handler.Close(); err != nil {
-			errors = append(errors, err)
+			errs = append(errs, err)
 		}
 		}
 	}
 	}
 
 
-	if len(errors) > 0 {
-		return newError("failed to close all handlers").Base(newError(serial.Concat(errors...)))
+	if len(errs) > 0 {
+		return errors.New("failed to close all handlers").Base(errors.New(serial.Concat(errs...)))
 	}
 	}
 
 
 	return nil
 	return nil
@@ -150,7 +151,7 @@ func NewHandler(ctx context.Context, config *core.InboundHandlerConfig) (inbound
 
 
 	receiverSettings, ok := rawReceiverSettings.(*proxyman.ReceiverConfig)
 	receiverSettings, ok := rawReceiverSettings.(*proxyman.ReceiverConfig)
 	if !ok {
 	if !ok {
-		return nil, newError("not a ReceiverConfig").AtError()
+		return nil, errors.New("not a ReceiverConfig").AtError()
 	}
 	}
 
 
 	streamSettings := receiverSettings.StreamSettings
 	streamSettings := receiverSettings.StreamSettings
@@ -168,7 +169,7 @@ func NewHandler(ctx context.Context, config *core.InboundHandlerConfig) (inbound
 	if allocStrategy.Type == proxyman.AllocationStrategy_Random {
 	if allocStrategy.Type == proxyman.AllocationStrategy_Random {
 		return NewDynamicInboundHandler(ctx, tag, receiverSettings, proxySettings)
 		return NewDynamicInboundHandler(ctx, tag, receiverSettings, proxySettings)
 	}
 	}
-	return nil, newError("unknown allocation strategy: ", receiverSettings.AllocationStrategy.Type).AtError()
+	return nil, errors.New("unknown allocation strategy: ", receiverSettings.AllocationStrategy.Type).AtError()
 }
 }
 
 
 func init() {
 func init() {

+ 29 - 27
app/proxyman/inbound/worker.go

@@ -9,6 +9,8 @@ import (
 	"github.com/xtls/xray-core/app/proxyman"
 	"github.com/xtls/xray-core/app/proxyman"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common/buf"
 	"github.com/xtls/xray-core/common/buf"
+	c "github.com/xtls/xray-core/common/ctx"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/serial"
 	"github.com/xtls/xray-core/common/serial"
 	"github.com/xtls/xray-core/common/session"
 	"github.com/xtls/xray-core/common/session"
@@ -58,7 +60,7 @@ func getTProxyType(s *internet.MemoryStreamConfig) internet.SocketConfig_TProxyM
 func (w *tcpWorker) callback(conn stat.Connection) {
 func (w *tcpWorker) callback(conn stat.Connection) {
 	ctx, cancel := context.WithCancel(w.ctx)
 	ctx, cancel := context.WithCancel(w.ctx)
 	sid := session.NewID()
 	sid := session.NewID()
-	ctx = session.ContextWithID(ctx, sid)
+	ctx = c.ContextWithID(ctx, sid)
 
 
 	outbounds := []*session.Outbound{{}}
 	outbounds := []*session.Outbound{{}}
 	if w.recvOrigDest {
 	if w.recvOrigDest {
@@ -67,7 +69,7 @@ func (w *tcpWorker) callback(conn stat.Connection) {
 		case internet.SocketConfig_Redirect:
 		case internet.SocketConfig_Redirect:
 			d, err := tcp.GetOriginalDestination(conn)
 			d, err := tcp.GetOriginalDestination(conn)
 			if err != nil {
 			if err != nil {
-				newError("failed to get original destination").Base(err).WriteToLog(session.ExportIDToError(ctx))
+				errors.LogInfoInner(ctx, err, "failed to get original destination")
 			} else {
 			} else {
 				dest = d
 				dest = d
 			}
 			}
@@ -105,7 +107,7 @@ func (w *tcpWorker) callback(conn stat.Connection) {
 	ctx = session.ContextWithContent(ctx, content)
 	ctx = session.ContextWithContent(ctx, content)
 
 
 	if err := w.proxy.Process(ctx, net.Network_TCP, conn, w.dispatcher); err != nil {
 	if err := w.proxy.Process(ctx, net.Network_TCP, conn, w.dispatcher); err != nil {
-		newError("connection ends").Base(err).WriteToLog(session.ExportIDToError(ctx))
+		errors.LogInfoInner(ctx, err, "connection ends")
 	}
 	}
 	cancel()
 	cancel()
 	conn.Close()
 	conn.Close()
@@ -121,24 +123,24 @@ func (w *tcpWorker) Start() error {
 		go w.callback(conn)
 		go w.callback(conn)
 	})
 	})
 	if err != nil {
 	if err != nil {
-		return newError("failed to listen TCP on ", w.port).AtWarning().Base(err)
+		return errors.New("failed to listen TCP on ", w.port).AtWarning().Base(err)
 	}
 	}
 	w.hub = hub
 	w.hub = hub
 	return nil
 	return nil
 }
 }
 
 
 func (w *tcpWorker) Close() error {
 func (w *tcpWorker) Close() error {
-	var errors []interface{}
+	var errs []interface{}
 	if w.hub != nil {
 	if w.hub != nil {
 		if err := common.Close(w.hub); err != nil {
 		if err := common.Close(w.hub); err != nil {
-			errors = append(errors, err)
+			errs = append(errs, err)
 		}
 		}
 		if err := common.Close(w.proxy); err != nil {
 		if err := common.Close(w.proxy); err != nil {
-			errors = append(errors, err)
+			errs = append(errs, err)
 		}
 		}
 	}
 	}
-	if len(errors) > 0 {
-		return newError("failed to close all resources").Base(newError(serial.Concat(errors...)))
+	if len(errs) > 0 {
+		return errors.New("failed to close all resources").Base(errors.New(serial.Concat(errs...)))
 	}
 	}
 
 
 	return nil
 	return nil
@@ -306,7 +308,7 @@ func (w *udpWorker) callback(b *buf.Buffer, source net.Destination, originalDest
 		go func() {
 		go func() {
 			ctx := w.ctx
 			ctx := w.ctx
 			sid := session.NewID()
 			sid := session.NewID()
-			ctx = session.ContextWithID(ctx, sid)
+			ctx = c.ContextWithID(ctx, sid)
 
 
 			outbounds := []*session.Outbound{{}}
 			outbounds := []*session.Outbound{{}}
 			if originalDest.IsValid() {
 			if originalDest.IsValid() {
@@ -327,7 +329,7 @@ func (w *udpWorker) callback(b *buf.Buffer, source net.Destination, originalDest
 			}
 			}
 			ctx = session.ContextWithContent(ctx, content)
 			ctx = session.ContextWithContent(ctx, content)
 			if err := w.proxy.Process(ctx, net.Network_UDP, conn, w.dispatcher); err != nil {
 			if err := w.proxy.Process(ctx, net.Network_UDP, conn, w.dispatcher); err != nil {
-				newError("connection ends").Base(err).WriteToLog(session.ExportIDToError(ctx))
+				errors.LogInfoInner(ctx, err, "connection ends")
 			}
 			}
 			conn.Close()
 			conn.Close()
 			// conn not removed by checker TODO may be lock worker here is better
 			// conn not removed by checker TODO may be lock worker here is better
@@ -358,7 +360,7 @@ func (w *udpWorker) clean() error {
 	defer w.Unlock()
 	defer w.Unlock()
 
 
 	if len(w.activeConn) == 0 {
 	if len(w.activeConn) == 0 {
-		return newError("no more connections. stopping...")
+		return errors.New("no more connections. stopping...")
 	}
 	}
 
 
 	for addr, conn := range w.activeConn {
 	for addr, conn := range w.activeConn {
@@ -402,26 +404,26 @@ func (w *udpWorker) Close() error {
 	w.Lock()
 	w.Lock()
 	defer w.Unlock()
 	defer w.Unlock()
 
 
-	var errors []interface{}
+	var errs []interface{}
 
 
 	if w.hub != nil {
 	if w.hub != nil {
 		if err := w.hub.Close(); err != nil {
 		if err := w.hub.Close(); err != nil {
-			errors = append(errors, err)
+			errs = append(errs, err)
 		}
 		}
 	}
 	}
 
 
 	if w.checker != nil {
 	if w.checker != nil {
 		if err := w.checker.Close(); err != nil {
 		if err := w.checker.Close(); err != nil {
-			errors = append(errors, err)
+			errs = append(errs, err)
 		}
 		}
 	}
 	}
 
 
 	if err := common.Close(w.proxy); err != nil {
 	if err := common.Close(w.proxy); err != nil {
-		errors = append(errors, err)
+		errs = append(errs, err)
 	}
 	}
 
 
-	if len(errors) > 0 {
-		return newError("failed to close all resources").Base(newError(serial.Concat(errors...)))
+	if len(errs) > 0 {
+		return errors.New("failed to close all resources").Base(errors.New(serial.Concat(errs...)))
 	}
 	}
 	return nil
 	return nil
 }
 }
@@ -452,7 +454,7 @@ type dsWorker struct {
 func (w *dsWorker) callback(conn stat.Connection) {
 func (w *dsWorker) callback(conn stat.Connection) {
 	ctx, cancel := context.WithCancel(w.ctx)
 	ctx, cancel := context.WithCancel(w.ctx)
 	sid := session.NewID()
 	sid := session.NewID()
-	ctx = session.ContextWithID(ctx, sid)
+	ctx = c.ContextWithID(ctx, sid)
 
 
 	if w.uplinkCounter != nil || w.downlinkCounter != nil {
 	if w.uplinkCounter != nil || w.downlinkCounter != nil {
 		conn = &stat.CounterConnection{
 		conn = &stat.CounterConnection{
@@ -479,11 +481,11 @@ func (w *dsWorker) callback(conn stat.Connection) {
 	ctx = session.ContextWithContent(ctx, content)
 	ctx = session.ContextWithContent(ctx, content)
 
 
 	if err := w.proxy.Process(ctx, net.Network_UNIX, conn, w.dispatcher); err != nil {
 	if err := w.proxy.Process(ctx, net.Network_UNIX, conn, w.dispatcher); err != nil {
-		newError("connection ends").Base(err).WriteToLog(session.ExportIDToError(ctx))
+		errors.LogInfoInner(ctx, err, "connection ends")
 	}
 	}
 	cancel()
 	cancel()
 	if err := conn.Close(); err != nil {
 	if err := conn.Close(); err != nil {
-		newError("failed to close connection").Base(err).WriteToLog(session.ExportIDToError(ctx))
+		errors.LogInfoInner(ctx, err, "failed to close connection")
 	}
 	}
 }
 }
 
 
@@ -501,24 +503,24 @@ func (w *dsWorker) Start() error {
 		go w.callback(conn)
 		go w.callback(conn)
 	})
 	})
 	if err != nil {
 	if err != nil {
-		return newError("failed to listen Unix Domain Socket on ", w.address).AtWarning().Base(err)
+		return errors.New("failed to listen Unix Domain Socket on ", w.address).AtWarning().Base(err)
 	}
 	}
 	w.hub = hub
 	w.hub = hub
 	return nil
 	return nil
 }
 }
 
 
 func (w *dsWorker) Close() error {
 func (w *dsWorker) Close() error {
-	var errors []interface{}
+	var errs []interface{}
 	if w.hub != nil {
 	if w.hub != nil {
 		if err := common.Close(w.hub); err != nil {
 		if err := common.Close(w.hub); err != nil {
-			errors = append(errors, err)
+			errs = append(errs, err)
 		}
 		}
 		if err := common.Close(w.proxy); err != nil {
 		if err := common.Close(w.proxy); err != nil {
-			errors = append(errors, err)
+			errs = append(errs, err)
 		}
 		}
 	}
 	}
-	if len(errors) > 0 {
-		return newError("failed to close all resources").Base(newError(serial.Concat(errors...)))
+	if len(errs) > 0 {
+		return errors.New("failed to close all resources").Base(errors.New(serial.Concat(errs...)))
 	}
 	}
 
 
 	return nil
 	return nil

+ 0 - 9
app/proxyman/outbound/errors.generated.go

@@ -1,9 +0,0 @@
-package outbound
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 22 - 21
app/proxyman/outbound/handler.go

@@ -3,9 +3,15 @@ package outbound
 import (
 import (
 	"context"
 	"context"
 	"crypto/rand"
 	"crypto/rand"
-	"errors"
+	goerrors "errors"
+	"io"
+	"math/big"
+	gonet "net"
+	"os"
+
 	"github.com/xtls/xray-core/app/proxyman"
 	"github.com/xtls/xray-core/app/proxyman"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/buf"
 	"github.com/xtls/xray-core/common/buf"
 	"github.com/xtls/xray-core/common/mux"
 	"github.com/xtls/xray-core/common/mux"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
@@ -21,10 +27,6 @@ import (
 	"github.com/xtls/xray-core/transport/internet/stat"
 	"github.com/xtls/xray-core/transport/internet/stat"
 	"github.com/xtls/xray-core/transport/internet/tls"
 	"github.com/xtls/xray-core/transport/internet/tls"
 	"github.com/xtls/xray-core/transport/pipe"
 	"github.com/xtls/xray-core/transport/pipe"
-	"io"
-	"math/big"
-	gonet "net"
-	"os"
 )
 )
 
 
 func getStatCounter(v *core.Instance, tag string) (stats.Counter, stats.Counter) {
 func getStatCounter(v *core.Instance, tag string) (stats.Counter, stats.Counter) {
@@ -87,11 +89,11 @@ func NewHandler(ctx context.Context, config *core.OutboundHandlerConfig) (outbou
 			h.senderSettings = s
 			h.senderSettings = s
 			mss, err := internet.ToMemoryStreamConfig(s.StreamSettings)
 			mss, err := internet.ToMemoryStreamConfig(s.StreamSettings)
 			if err != nil {
 			if err != nil {
-				return nil, newError("failed to parse stream settings").Base(err).AtWarning()
+				return nil, errors.New("failed to parse stream settings").Base(err).AtWarning()
 			}
 			}
 			h.streamSettings = mss
 			h.streamSettings = mss
 		default:
 		default:
-			return nil, newError("settings is not SenderConfig")
+			return nil, errors.New("settings is not SenderConfig")
 		}
 		}
 	}
 	}
 
 
@@ -107,7 +109,7 @@ func NewHandler(ctx context.Context, config *core.OutboundHandlerConfig) (outbou
 
 
 	proxyHandler, ok := rawProxyHandler.(proxy.Outbound)
 	proxyHandler, ok := rawProxyHandler.(proxy.Outbound)
 	if !ok {
 	if !ok {
-		return nil, newError("not an outbound handler")
+		return nil, errors.New("not an outbound handler")
 	}
 	}
 
 
 	if h.senderSettings != nil && h.senderSettings.MultiplexSettings != nil {
 	if h.senderSettings != nil && h.senderSettings.MultiplexSettings != nil {
@@ -170,7 +172,7 @@ func (h *Handler) Tag() string {
 // Dispatch implements proxy.Outbound.Dispatch.
 // Dispatch implements proxy.Outbound.Dispatch.
 func (h *Handler) Dispatch(ctx context.Context, link *transport.Link) {
 func (h *Handler) Dispatch(ctx context.Context, link *transport.Link) {
 	outbounds := session.OutboundsFromContext(ctx)
 	outbounds := session.OutboundsFromContext(ctx)
-	ob := outbounds[len(outbounds) - 1]
+	ob := outbounds[len(outbounds)-1]
 	if ob.Target.Network == net.Network_UDP && ob.OriginalTarget.Address != nil && ob.OriginalTarget.Address != ob.Target.Address {
 	if ob.Target.Network == net.Network_UDP && ob.OriginalTarget.Address != nil && ob.OriginalTarget.Address != ob.Target.Address {
 		link.Reader = &buf.EndpointOverrideReader{Reader: link.Reader, Dest: ob.Target.Address, OriginalDest: ob.OriginalTarget.Address}
 		link.Reader = &buf.EndpointOverrideReader{Reader: link.Reader, Dest: ob.Target.Address, OriginalDest: ob.OriginalTarget.Address}
 		link.Writer = &buf.EndpointOverrideWriter{Writer: link.Writer, Dest: ob.Target.Address, OriginalDest: ob.OriginalTarget.Address}
 		link.Writer = &buf.EndpointOverrideWriter{Writer: link.Writer, Dest: ob.Target.Address, OriginalDest: ob.OriginalTarget.Address}
@@ -178,16 +180,16 @@ func (h *Handler) Dispatch(ctx context.Context, link *transport.Link) {
 	if h.mux != nil {
 	if h.mux != nil {
 		test := func(err error) {
 		test := func(err error) {
 			if err != nil {
 			if err != nil {
-				err := newError("failed to process mux outbound traffic").Base(err)
+				err := errors.New("failed to process mux outbound traffic").Base(err)
 				session.SubmitOutboundErrorToOriginator(ctx, err)
 				session.SubmitOutboundErrorToOriginator(ctx, err)
-				err.WriteToLog(session.ExportIDToError(ctx))
+				errors.LogInfo(ctx, err.Error())
 				common.Interrupt(link.Writer)
 				common.Interrupt(link.Writer)
 			}
 			}
 		}
 		}
 		if ob.Target.Network == net.Network_UDP && ob.Target.Port == 443 {
 		if ob.Target.Network == net.Network_UDP && ob.Target.Port == 443 {
 			switch h.udp443 {
 			switch h.udp443 {
 			case "reject":
 			case "reject":
-				test(newError("XUDP rejected UDP/443 traffic").AtInfo())
+				test(errors.New("XUDP rejected UDP/443 traffic").AtInfo())
 				return
 				return
 			case "skip":
 			case "skip":
 				goto out
 				goto out
@@ -208,15 +210,15 @@ func (h *Handler) Dispatch(ctx context.Context, link *transport.Link) {
 out:
 out:
 	err := h.proxy.Process(ctx, link, h)
 	err := h.proxy.Process(ctx, link, h)
 	if err != nil {
 	if err != nil {
-		if errors.Is(err, io.EOF) || errors.Is(err, io.ErrClosedPipe) || errors.Is(err, context.Canceled) {
+		if goerrors.Is(err, io.EOF) || goerrors.Is(err, io.ErrClosedPipe) || goerrors.Is(err, context.Canceled) {
 			err = nil
 			err = nil
 		}
 		}
 	}
 	}
 	if err != nil {
 	if err != nil {
 		// Ensure outbound ray is properly closed.
 		// Ensure outbound ray is properly closed.
-		err := newError("failed to process outbound traffic").Base(err)
+		err := errors.New("failed to process outbound traffic").Base(err)
 		session.SubmitOutboundErrorToOriginator(ctx, err)
 		session.SubmitOutboundErrorToOriginator(ctx, err)
-		err.WriteToLog(session.ExportIDToError(ctx))
+		errors.LogInfo(ctx, err.Error())
 		common.Interrupt(link.Writer)
 		common.Interrupt(link.Writer)
 	} else {
 	} else {
 		common.Close(link.Writer)
 		common.Close(link.Writer)
@@ -243,11 +245,11 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (stat.Connecti
 			tag := h.senderSettings.ProxySettings.Tag
 			tag := h.senderSettings.ProxySettings.Tag
 			handler := h.outboundManager.GetHandler(tag)
 			handler := h.outboundManager.GetHandler(tag)
 			if handler != nil {
 			if handler != nil {
-				newError("proxying to ", tag, " for dest ", dest).AtDebug().WriteToLog(session.ExportIDToError(ctx))
+				errors.LogDebug(ctx, "proxying to ", tag, " for dest ", dest)
 				outbounds := session.OutboundsFromContext(ctx)
 				outbounds := session.OutboundsFromContext(ctx)
 				ctx = session.ContextWithOutbounds(ctx, append(outbounds, &session.Outbound{
 				ctx = session.ContextWithOutbounds(ctx, append(outbounds, &session.Outbound{
 					Target: dest,
 					Target: dest,
-					Tag: tag,
+					Tag:    tag,
 				})) // add another outbound in session ctx
 				})) // add another outbound in session ctx
 				opts := pipe.OptionsFromContext(ctx)
 				opts := pipe.OptionsFromContext(ctx)
 				uplinkReader, uplinkWriter := pipe.New(opts...)
 				uplinkReader, uplinkWriter := pipe.New(opts...)
@@ -264,12 +266,12 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (stat.Connecti
 				return h.getStatCouterConnection(conn), nil
 				return h.getStatCouterConnection(conn), nil
 			}
 			}
 
 
-			newError("failed to get outbound handler with tag: ", tag).AtWarning().WriteToLog(session.ExportIDToError(ctx))
+			errors.LogWarning(ctx, "failed to get outbound handler with tag: ", tag)
 		}
 		}
 
 
 		if h.senderSettings.Via != nil {
 		if h.senderSettings.Via != nil {
 			outbounds := session.OutboundsFromContext(ctx)
 			outbounds := session.OutboundsFromContext(ctx)
-			ob := outbounds[len(outbounds) - 1]
+			ob := outbounds[len(outbounds)-1]
 			if h.senderSettings.ViaCidr == "" {
 			if h.senderSettings.ViaCidr == "" {
 				ob.Gateway = h.senderSettings.Via.AsAddress()
 				ob.Gateway = h.senderSettings.Via.AsAddress()
 			} else { //Get a random address.
 			} else { //Get a random address.
@@ -285,7 +287,7 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (stat.Connecti
 	conn, err := internet.Dial(ctx, dest, h.streamSettings)
 	conn, err := internet.Dial(ctx, dest, h.streamSettings)
 	conn = h.getStatCouterConnection(conn)
 	conn = h.getStatCouterConnection(conn)
 	outbounds := session.OutboundsFromContext(ctx)
 	outbounds := session.OutboundsFromContext(ctx)
-	ob := outbounds[len(outbounds) - 1]
+	ob := outbounds[len(outbounds)-1]
 	ob.Conn = conn
 	ob.Conn = conn
 	return conn, err
 	return conn, err
 }
 }
@@ -317,7 +319,6 @@ func (h *Handler) Close() error {
 	return nil
 	return nil
 }
 }
 
 
-
 func ParseRandomIPv6(address net.Address, prefix string) net.Address {
 func ParseRandomIPv6(address net.Address, prefix string) net.Address {
 	_, network, _ := gonet.ParseCIDR(address.IP().String() + "/" + prefix)
 	_, network, _ := gonet.ParseCIDR(address.IP().String() + "/" + prefix)
 
 

+ 1 - 1
app/proxyman/outbound/outbound.go

@@ -115,7 +115,7 @@ func (m *Manager) AddHandler(ctx context.Context, handler outbound.Handler) erro
 	tag := handler.Tag()
 	tag := handler.Tag()
 	if len(tag) > 0 {
 	if len(tag) > 0 {
 		if _, found := m.taggedHandler[tag]; found {
 		if _, found := m.taggedHandler[tag]; found {
-			return newError("existing tag found: " + tag)
+			return errors.New("existing tag found: " + tag)
 		}
 		}
 		m.taggedHandler[tag] = handler
 		m.taggedHandler[tag] = handler
 	} else {
 	} else {

+ 3 - 2
app/proxyman/outbound/uot.go

@@ -5,6 +5,7 @@ import (
 	"os"
 	"os"
 
 
 	"github.com/sagernet/sing/common/uot"
 	"github.com/sagernet/sing/common/uot"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/transport/internet"
 	"github.com/xtls/xray-core/transport/internet"
 	"github.com/xtls/xray-core/transport/internet/stat"
 	"github.com/xtls/xray-core/transport/internet/stat"
@@ -12,7 +13,7 @@ import (
 
 
 func (h *Handler) getUoTConnection(ctx context.Context, dest net.Destination) (stat.Connection, error) {
 func (h *Handler) getUoTConnection(ctx context.Context, dest net.Destination) (stat.Connection, error) {
 	if dest.Address == nil {
 	if dest.Address == nil {
-		return nil, newError("nil destination address")
+		return nil, errors.New("nil destination address")
 	}
 	}
 	if !dest.Address.Family().IsDomain() {
 	if !dest.Address.Family().IsDomain() {
 		return nil, os.ErrInvalid
 		return nil, os.ErrInvalid
@@ -27,7 +28,7 @@ func (h *Handler) getUoTConnection(ctx context.Context, dest net.Destination) (s
 	}
 	}
 	packetConn, err := internet.ListenSystemPacket(ctx, &net.UDPAddr{IP: net.AnyIP.IP(), Port: 0}, h.streamSettings.SocketSettings)
 	packetConn, err := internet.ListenSystemPacket(ctx, &net.UDPAddr{IP: net.AnyIP.IP(), Port: 0}, h.streamSettings.SocketSettings)
 	if err != nil {
 	if err != nil {
-		return nil, newError("unable to listen socket").Base(err)
+		return nil, errors.New("unable to listen socket").Base(err)
 	}
 	}
 	conn := uot.NewServerConn(packetConn, uotVersion)
 	conn := uot.NewServerConn(packetConn, uotVersion)
 	return h.getStatCouterConnection(conn), nil
 	return h.getStatCouterConnection(conn), nil

+ 5 - 4
app/reverse/bridge.go

@@ -4,6 +4,7 @@ import (
 	"context"
 	"context"
 	"time"
 	"time"
 
 
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/mux"
 	"github.com/xtls/xray-core/common/mux"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/session"
 	"github.com/xtls/xray-core/common/session"
@@ -26,10 +27,10 @@ type Bridge struct {
 // NewBridge creates a new Bridge instance.
 // NewBridge creates a new Bridge instance.
 func NewBridge(config *BridgeConfig, dispatcher routing.Dispatcher) (*Bridge, error) {
 func NewBridge(config *BridgeConfig, dispatcher routing.Dispatcher) (*Bridge, error) {
 	if config.Tag == "" {
 	if config.Tag == "" {
-		return nil, newError("bridge tag is empty")
+		return nil, errors.New("bridge tag is empty")
 	}
 	}
 	if config.Domain == "" {
 	if config.Domain == "" {
-		return nil, newError("bridge domain is empty")
+		return nil, errors.New("bridge domain is empty")
 	}
 	}
 
 
 	b := &Bridge{
 	b := &Bridge{
@@ -74,7 +75,7 @@ func (b *Bridge) monitor() error {
 	if numWorker == 0 || numConnections/numWorker > 16 {
 	if numWorker == 0 || numConnections/numWorker > 16 {
 		worker, err := NewBridgeWorker(b.domain, b.tag, b.dispatcher)
 		worker, err := NewBridgeWorker(b.domain, b.tag, b.dispatcher)
 		if err != nil {
 		if err != nil {
-			newError("failed to create bridge worker").Base(err).AtWarning().WriteToLog()
+			errors.LogWarningInner(context.Background(), err, "failed to create bridge worker")
 			return nil
 			return nil
 		}
 		}
 		b.workers = append(b.workers, worker)
 		b.workers = append(b.workers, worker)
@@ -157,7 +158,7 @@ func (w *BridgeWorker) handleInternalConn(link *transport.Link) {
 			for _, b := range mb {
 			for _, b := range mb {
 				var ctl Control
 				var ctl Control
 				if err := proto.Unmarshal(b.Bytes(), &ctl); err != nil {
 				if err := proto.Unmarshal(b.Bytes(), &ctl); err != nil {
-					newError("failed to parse proto message").Base(err).WriteToLog()
+					errors.LogInfoInner(context.Background(), err, "failed to parse proto message")
 					break
 					break
 				}
 				}
 				if ctl.State != w.state {
 				if ctl.State != w.state {

+ 0 - 9
app/reverse/errors.generated.go

@@ -1,9 +0,0 @@
-package reverse
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 13 - 12
app/reverse/portal.go

@@ -7,6 +7,7 @@ import (
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common/buf"
 	"github.com/xtls/xray-core/common/buf"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/mux"
 	"github.com/xtls/xray-core/common/mux"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/session"
 	"github.com/xtls/xray-core/common/session"
@@ -27,11 +28,11 @@ type Portal struct {
 
 
 func NewPortal(config *PortalConfig, ohm outbound.Manager) (*Portal, error) {
 func NewPortal(config *PortalConfig, ohm outbound.Manager) (*Portal, error) {
 	if config.Tag == "" {
 	if config.Tag == "" {
-		return nil, newError("portal tag is empty")
+		return nil, errors.New("portal tag is empty")
 	}
 	}
 
 
 	if config.Domain == "" {
 	if config.Domain == "" {
-		return nil, newError("portal domain is empty")
+		return nil, errors.New("portal domain is empty")
 	}
 	}
 
 
 	picker, err := NewStaticMuxPicker()
 	picker, err := NewStaticMuxPicker()
@@ -63,20 +64,20 @@ func (p *Portal) Close() error {
 
 
 func (p *Portal) HandleConnection(ctx context.Context, link *transport.Link) error {
 func (p *Portal) HandleConnection(ctx context.Context, link *transport.Link) error {
 	outbounds := session.OutboundsFromContext(ctx)
 	outbounds := session.OutboundsFromContext(ctx)
-	ob := outbounds[len(outbounds) - 1]
+	ob := outbounds[len(outbounds)-1]
 	if ob == nil {
 	if ob == nil {
-		return newError("outbound metadata not found").AtError()
+		return errors.New("outbound metadata not found").AtError()
 	}
 	}
 
 
 	if isDomain(ob.Target, p.domain) {
 	if isDomain(ob.Target, p.domain) {
 		muxClient, err := mux.NewClientWorker(*link, mux.ClientStrategy{})
 		muxClient, err := mux.NewClientWorker(*link, mux.ClientStrategy{})
 		if err != nil {
 		if err != nil {
-			return newError("failed to create mux client worker").Base(err).AtWarning()
+			return errors.New("failed to create mux client worker").Base(err).AtWarning()
 		}
 		}
 
 
 		worker, err := NewPortalWorker(muxClient)
 		worker, err := NewPortalWorker(muxClient)
 		if err != nil {
 		if err != nil {
-			return newError("failed to create portal worker").Base(err)
+			return errors.New("failed to create portal worker").Base(err)
 		}
 		}
 
 
 		p.picker.AddWorker(worker)
 		p.picker.AddWorker(worker)
@@ -97,7 +98,7 @@ func (o *Outbound) Tag() string {
 
 
 func (o *Outbound) Dispatch(ctx context.Context, link *transport.Link) {
 func (o *Outbound) Dispatch(ctx context.Context, link *transport.Link) {
 	if err := o.portal.HandleConnection(ctx, link); err != nil {
 	if err := o.portal.HandleConnection(ctx, link); err != nil {
-		newError("failed to process reverse connection").Base(err).WriteToLog(session.ExportIDToError(ctx))
+		errors.LogInfoInner(ctx, err, "failed to process reverse connection")
 		common.Interrupt(link.Writer)
 		common.Interrupt(link.Writer)
 	}
 	}
 }
 }
@@ -149,7 +150,7 @@ func (p *StaticMuxPicker) PickAvailable() (*mux.ClientWorker, error) {
 	defer p.access.Unlock()
 	defer p.access.Unlock()
 
 
 	if len(p.workers) == 0 {
 	if len(p.workers) == 0 {
-		return nil, newError("empty worker list")
+		return nil, errors.New("empty worker list")
 	}
 	}
 
 
 	var minIdx int = -1
 	var minIdx int = -1
@@ -183,7 +184,7 @@ func (p *StaticMuxPicker) PickAvailable() (*mux.ClientWorker, error) {
 		return p.workers[minIdx].client, nil
 		return p.workers[minIdx].client, nil
 	}
 	}
 
 
-	return nil, newError("no mux client worker available")
+	return nil, errors.New("no mux client worker available")
 }
 }
 
 
 func (p *StaticMuxPicker) AddWorker(worker *PortalWorker) {
 func (p *StaticMuxPicker) AddWorker(worker *PortalWorker) {
@@ -216,7 +217,7 @@ func NewPortalWorker(client *mux.ClientWorker) (*PortalWorker, error) {
 		Writer: downlinkWriter,
 		Writer: downlinkWriter,
 	})
 	})
 	if !f {
 	if !f {
-		return nil, newError("unable to dispatch control connection")
+		return nil, errors.New("unable to dispatch control connection")
 	}
 	}
 	w := &PortalWorker{
 	w := &PortalWorker{
 		client: client,
 		client: client,
@@ -233,11 +234,11 @@ func NewPortalWorker(client *mux.ClientWorker) (*PortalWorker, error) {
 
 
 func (w *PortalWorker) heartbeat() error {
 func (w *PortalWorker) heartbeat() error {
 	if w.client.Closed() {
 	if w.client.Closed() {
-		return newError("client worker stopped")
+		return errors.New("client worker stopped")
 	}
 	}
 
 
 	if w.draining || w.writer == nil {
 	if w.draining || w.writer == nil {
-		return newError("already disposed")
+		return errors.New("already disposed")
 	}
 	}
 
 
 	msg := &Control{}
 	msg := &Control{}

+ 12 - 11
app/router/balancing.go

@@ -6,6 +6,7 @@ import (
 
 
 	"github.com/xtls/xray-core/app/observatory"
 	"github.com/xtls/xray-core/app/observatory"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/features/extension"
 	"github.com/xtls/xray-core/features/extension"
 	"github.com/xtls/xray-core/features/outbound"
 	"github.com/xtls/xray-core/features/outbound"
@@ -24,8 +25,8 @@ type RoundRobinStrategy struct {
 
 
 	ctx         context.Context
 	ctx         context.Context
 	observatory extension.Observatory
 	observatory extension.Observatory
-	mu    sync.Mutex
-	index int
+	mu          sync.Mutex
+	index       int
 }
 }
 
 
 func (s *RoundRobinStrategy) InjectContext(ctx context.Context) {
 func (s *RoundRobinStrategy) InjectContext(ctx context.Context) {
@@ -95,7 +96,7 @@ func (b *Balancer) PickOutbound() (string, error) {
 	candidates, err := b.SelectOutbounds()
 	candidates, err := b.SelectOutbounds()
 	if err != nil {
 	if err != nil {
 		if b.fallbackTag != "" {
 		if b.fallbackTag != "" {
-			newError("fallback to [", b.fallbackTag, "], due to error: ", err).AtInfo().WriteToLog()
+			errors.LogInfo(context.Background(), "fallback to [", b.fallbackTag, "], due to error: ", err)
 			return b.fallbackTag, nil
 			return b.fallbackTag, nil
 		}
 		}
 		return "", err
 		return "", err
@@ -108,11 +109,11 @@ func (b *Balancer) PickOutbound() (string, error) {
 	}
 	}
 	if tag == "" {
 	if tag == "" {
 		if b.fallbackTag != "" {
 		if b.fallbackTag != "" {
-			newError("fallback to [", b.fallbackTag, "], due to empty tag returned").AtInfo().WriteToLog()
+			errors.LogInfo(context.Background(), "fallback to [", b.fallbackTag, "], due to empty tag returned")
 			return b.fallbackTag, nil
 			return b.fallbackTag, nil
 		}
 		}
 		// will use default handler
 		// will use default handler
-		return "", newError("balancing strategy returns empty tag")
+		return "", errors.New("balancing strategy returns empty tag")
 	}
 	}
 	return tag, nil
 	return tag, nil
 }
 }
@@ -127,7 +128,7 @@ func (b *Balancer) InjectContext(ctx context.Context) {
 func (b *Balancer) SelectOutbounds() ([]string, error) {
 func (b *Balancer) SelectOutbounds() ([]string, error) {
 	hs, ok := b.ohm.(outbound.HandlerSelector)
 	hs, ok := b.ohm.(outbound.HandlerSelector)
 	if !ok {
 	if !ok {
-		return nil, newError("outbound.Manager is not a HandlerSelector")
+		return nil, errors.New("outbound.Manager is not a HandlerSelector")
 	}
 	}
 	tags := hs.Select(b.selectors)
 	tags := hs.Select(b.selectors)
 	return tags, nil
 	return tags, nil
@@ -139,13 +140,13 @@ func (r *Router) GetPrincipleTarget(tag string) ([]string, error) {
 		if s, ok := b.strategy.(BalancingPrincipleTarget); ok {
 		if s, ok := b.strategy.(BalancingPrincipleTarget); ok {
 			candidates, err := b.SelectOutbounds()
 			candidates, err := b.SelectOutbounds()
 			if err != nil {
 			if err != nil {
-				return nil, newError("unable to select outbounds").Base(err)
+				return nil, errors.New("unable to select outbounds").Base(err)
 			}
 			}
 			return s.GetPrincipleTarget(candidates), nil
 			return s.GetPrincipleTarget(candidates), nil
 		}
 		}
-		return nil, newError("unsupported GetPrincipleTarget")
+		return nil, errors.New("unsupported GetPrincipleTarget")
 	}
 	}
-	return nil, newError("cannot find tag")
+	return nil, errors.New("cannot find tag")
 }
 }
 
 
 // SetOverrideTarget implements routing.BalancerOverrider
 // SetOverrideTarget implements routing.BalancerOverrider
@@ -154,7 +155,7 @@ func (r *Router) SetOverrideTarget(tag, target string) error {
 		b.override.Put(target)
 		b.override.Put(target)
 		return nil
 		return nil
 	}
 	}
-	return newError("cannot find tag")
+	return errors.New("cannot find tag")
 }
 }
 
 
 // GetOverrideTarget implements routing.BalancerOverrider
 // GetOverrideTarget implements routing.BalancerOverrider
@@ -162,5 +163,5 @@ func (r *Router) GetOverrideTarget(tag string) (string, error) {
 	if b, ok := r.balancers[tag]; ok {
 	if b, ok := r.balancers[tag]; ok {
 		return b.override.Get(), nil
 		return b.override.Get(), nil
 	}
 	}
-	return "", newError("cannot find tag")
+	return "", errors.New("cannot find tag")
 }
 }

+ 3 - 1
app/router/balancing_override.go

@@ -2,6 +2,8 @@ package router
 
 
 import (
 import (
 	sync "sync"
 	sync "sync"
+
+	"github.com/xtls/xray-core/common/errors"
 )
 )
 
 
 func (r *Router) OverrideBalancer(balancer string, target string) error {
 func (r *Router) OverrideBalancer(balancer string, target string) error {
@@ -13,7 +15,7 @@ func (r *Router) OverrideBalancer(balancer string, target string) error {
 		}
 		}
 	}
 	}
 	if b == nil {
 	if b == nil {
-		return newError("balancer '", balancer, "' not found")
+		return errors.New("balancer '", balancer, "' not found")
 	}
 	}
 	b.override.Put(target)
 	b.override.Put(target)
 	return nil
 	return nil

+ 9 - 8
app/router/command/command.go

@@ -7,6 +7,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/features/routing"
 	"github.com/xtls/xray-core/features/routing"
 	"github.com/xtls/xray-core/features/stats"
 	"github.com/xtls/xray-core/features/stats"
@@ -38,7 +39,7 @@ func (s *routingServer) GetBalancerInfo(ctx context.Context, request *GetBalance
 		{
 		{
 			res, err := pt.GetPrincipleTarget(request.GetTag())
 			res, err := pt.GetPrincipleTarget(request.GetTag())
 			if err != nil {
 			if err != nil {
-				newError("unable to obtain principle target").Base(err).AtInfo().WriteToLog()
+				errors.LogInfoInner(ctx, err, "unable to obtain principle target")
 			} else {
 			} else {
 				ret.Balancer.PrincipleTarget = &PrincipleTargetInfo{Tag: res}
 				ret.Balancer.PrincipleTarget = &PrincipleTargetInfo{Tag: res}
 			}
 			}
@@ -51,21 +52,21 @@ func (s *routingServer) OverrideBalancerTarget(ctx context.Context, request *Ove
 	if bo, ok := s.router.(routing.BalancerOverrider); ok {
 	if bo, ok := s.router.(routing.BalancerOverrider); ok {
 		return &OverrideBalancerTargetResponse{}, bo.SetOverrideTarget(request.BalancerTag, request.Target)
 		return &OverrideBalancerTargetResponse{}, bo.SetOverrideTarget(request.BalancerTag, request.Target)
 	}
 	}
-	return nil, newError("unsupported router implementation")
+	return nil, errors.New("unsupported router implementation")
 }
 }
 
 
 func (s *routingServer) AddRule(ctx context.Context, request *AddRuleRequest) (*AddRuleResponse, error) {
 func (s *routingServer) AddRule(ctx context.Context, request *AddRuleRequest) (*AddRuleResponse, error) {
 	if bo, ok := s.router.(routing.Router); ok {
 	if bo, ok := s.router.(routing.Router); ok {
 		return &AddRuleResponse{}, bo.AddRule(request.Config, request.ShouldAppend)
 		return &AddRuleResponse{}, bo.AddRule(request.Config, request.ShouldAppend)
 	}
 	}
-	return nil, newError("unsupported router implementation")
+	return nil, errors.New("unsupported router implementation")
 
 
 }
 }
 func (s *routingServer) RemoveRule(ctx context.Context, request *RemoveRuleRequest) (*RemoveRuleResponse, error) {
 func (s *routingServer) RemoveRule(ctx context.Context, request *RemoveRuleRequest) (*RemoveRuleResponse, error) {
 	if bo, ok := s.router.(routing.Router); ok {
 	if bo, ok := s.router.(routing.Router); ok {
 		return &RemoveRuleResponse{}, bo.RemoveRule(request.RuleTag)
 		return &RemoveRuleResponse{}, bo.RemoveRule(request.RuleTag)
 	}
 	}
-	return nil, newError("unsupported router implementation")
+	return nil, errors.New("unsupported router implementation")
 }
 }
 
 
 // NewRoutingServer creates a statistics service with statistics manager.
 // NewRoutingServer creates a statistics service with statistics manager.
@@ -78,7 +79,7 @@ func NewRoutingServer(router routing.Router, routingStats stats.Channel) Routing
 
 
 func (s *routingServer) TestRoute(ctx context.Context, request *TestRouteRequest) (*RoutingContext, error) {
 func (s *routingServer) TestRoute(ctx context.Context, request *TestRouteRequest) (*RoutingContext, error) {
 	if request.RoutingContext == nil {
 	if request.RoutingContext == nil {
-		return nil, newError("Invalid routing request.")
+		return nil, errors.New("Invalid routing request.")
 	}
 	}
 	route, err := s.router.PickRoute(AsRoutingContext(request.RoutingContext))
 	route, err := s.router.PickRoute(AsRoutingContext(request.RoutingContext))
 	if err != nil {
 	if err != nil {
@@ -93,7 +94,7 @@ func (s *routingServer) TestRoute(ctx context.Context, request *TestRouteRequest
 
 
 func (s *routingServer) SubscribeRoutingStats(request *SubscribeRoutingStatsRequest, stream RoutingService_SubscribeRoutingStatsServer) error {
 func (s *routingServer) SubscribeRoutingStats(request *SubscribeRoutingStatsRequest, stream RoutingService_SubscribeRoutingStatsServer) error {
 	if s.routingStats == nil {
 	if s.routingStats == nil {
-		return newError("Routing statistics not enabled.")
+		return errors.New("Routing statistics not enabled.")
 	}
 	}
 	genMessage := AsProtobufMessage(request.FieldSelectors)
 	genMessage := AsProtobufMessage(request.FieldSelectors)
 	subscriber, err := stats.SubscribeRunnableChannel(s.routingStats)
 	subscriber, err := stats.SubscribeRunnableChannel(s.routingStats)
@@ -105,11 +106,11 @@ func (s *routingServer) SubscribeRoutingStats(request *SubscribeRoutingStatsRequ
 		select {
 		select {
 		case value, ok := <-subscriber:
 		case value, ok := <-subscriber:
 			if !ok {
 			if !ok {
-				return newError("Upstream closed the subscriber channel.")
+				return errors.New("Upstream closed the subscriber channel.")
 			}
 			}
 			route, ok := value.(routing.Route)
 			route, ok := value.(routing.Route)
 			if !ok {
 			if !ok {
-				return newError("Upstream sent malformed statistics.")
+				return errors.New("Upstream sent malformed statistics.")
 			}
 			}
 			err := stream.Send(genMessage(route))
 			err := stream.Send(genMessage(route))
 			if err != nil {
 			if err != nil {

+ 0 - 9
app/router/command/errors.generated.go

@@ -1,9 +0,0 @@
-package command
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 4 - 3
app/router/condition.go

@@ -4,6 +4,7 @@ import (
 	"regexp"
 	"regexp"
 	"strings"
 	"strings"
 
 
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/strmatcher"
 	"github.com/xtls/xray-core/common/strmatcher"
 	"github.com/xtls/xray-core/features/routing"
 	"github.com/xtls/xray-core/features/routing"
@@ -49,12 +50,12 @@ var matcherTypeMap = map[Domain_Type]strmatcher.Type{
 func domainToMatcher(domain *Domain) (strmatcher.Matcher, error) {
 func domainToMatcher(domain *Domain) (strmatcher.Matcher, error) {
 	matcherType, f := matcherTypeMap[domain.Type]
 	matcherType, f := matcherTypeMap[domain.Type]
 	if !f {
 	if !f {
-		return nil, newError("unsupported domain type", domain.Type)
+		return nil, errors.New("unsupported domain type", domain.Type)
 	}
 	}
 
 
 	matcher, err := matcherType.New(domain.Value)
 	matcher, err := matcherType.New(domain.Value)
 	if err != nil {
 	if err != nil {
-		return nil, newError("failed to create domain matcher").Base(err)
+		return nil, errors.New("failed to create domain matcher").Base(err)
 	}
 	}
 
 
 	return matcher, nil
 	return matcher, nil
@@ -69,7 +70,7 @@ func NewMphMatcherGroup(domains []*Domain) (*DomainMatcher, error) {
 	for _, d := range domains {
 	for _, d := range domains {
 		matcherType, f := matcherTypeMap[d.Type]
 		matcherType, f := matcherTypeMap[d.Type]
 		if !f {
 		if !f {
-			return nil, newError("unsupported domain type", d.Type)
+			return nil, errors.New("unsupported domain type", d.Type)
 		}
 		}
 		_, err := g.AddPattern(d.Value, matcherType)
 		_, err := g.AddPattern(d.Value, matcherType)
 		if err != nil {
 		if err != nil {

+ 8 - 6
app/router/config.go

@@ -1,9 +1,11 @@
 package router
 package router
 
 
 import (
 import (
+	"context"
 	"regexp"
 	"regexp"
 	"strings"
 	"strings"
 
 
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/features/outbound"
 	"github.com/xtls/xray-core/features/outbound"
 	"github.com/xtls/xray-core/features/routing"
 	"github.com/xtls/xray-core/features/routing"
@@ -36,7 +38,7 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) {
 		case "linear":
 		case "linear":
 			matcher, err := NewDomainMatcher(rr.Domain)
 			matcher, err := NewDomainMatcher(rr.Domain)
 			if err != nil {
 			if err != nil {
-				return nil, newError("failed to build domain condition").Base(err)
+				return nil, errors.New("failed to build domain condition").Base(err)
 			}
 			}
 			conds.Add(matcher)
 			conds.Add(matcher)
 		case "mph", "hybrid":
 		case "mph", "hybrid":
@@ -44,9 +46,9 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) {
 		default:
 		default:
 			matcher, err := NewMphMatcherGroup(rr.Domain)
 			matcher, err := NewMphMatcherGroup(rr.Domain)
 			if err != nil {
 			if err != nil {
-				return nil, newError("failed to build domain condition with MphDomainMatcher").Base(err)
+				return nil, errors.New("failed to build domain condition with MphDomainMatcher").Base(err)
 			}
 			}
-			newError("MphDomainMatcher is enabled for ", len(rr.Domain), " domain rule(s)").AtDebug().WriteToLog()
+			errors.LogDebug(context.Background(), "MphDomainMatcher is enabled for ", len(rr.Domain), " domain rule(s)")
 			conds.Add(matcher)
 			conds.Add(matcher)
 		}
 		}
 	}
 	}
@@ -116,7 +118,7 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) {
 	}
 	}
 
 
 	if conds.Len() == 0 {
 	if conds.Len() == 0 {
-		return nil, newError("this rule has no effective fields").AtWarning()
+		return nil, errors.New("this rule has no effective fields").AtWarning()
 	}
 	}
 
 
 	return conds, nil
 	return conds, nil
@@ -146,7 +148,7 @@ func (br *BalancingRule) Build(ohm outbound.Manager, dispatcher routing.Dispatch
 		}
 		}
 		s, ok := i.(*StrategyLeastLoadConfig)
 		s, ok := i.(*StrategyLeastLoadConfig)
 		if !ok {
 		if !ok {
-			return nil, newError("not a StrategyLeastLoadConfig").AtError()
+			return nil, errors.New("not a StrategyLeastLoadConfig").AtError()
 		}
 		}
 		leastLoadStrategy := NewLeastLoadStrategy(s)
 		leastLoadStrategy := NewLeastLoadStrategy(s)
 		return &Balancer{
 		return &Balancer{
@@ -165,6 +167,6 @@ func (br *BalancingRule) Build(ohm outbound.Manager, dispatcher routing.Dispatch
 			strategy:    &RandomStrategy{FallbackTag: br.FallbackTag},
 			strategy:    &RandomStrategy{FallbackTag: br.FallbackTag},
 		}, nil
 		}, nil
 	default:
 	default:
-		return nil, newError("unrecognized balancer type")
+		return nil, errors.New("unrecognized balancer type")
 	}
 	}
 }
 }

+ 0 - 9
app/router/errors.generated.go

@@ -1,9 +0,0 @@
-package router
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 7 - 6
app/router/router.go

@@ -7,6 +7,7 @@ import (
 	sync "sync"
 	sync "sync"
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/serial"
 	"github.com/xtls/xray-core/common/serial"
 	"github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/features/dns"
 	"github.com/xtls/xray-core/features/dns"
@@ -68,7 +69,7 @@ func (r *Router) Init(ctx context.Context, config *Config, d dns.Client, ohm out
 		if len(btag) > 0 {
 		if len(btag) > 0 {
 			brule, found := r.balancers[btag]
 			brule, found := r.balancers[btag]
 			if !found {
 			if !found {
-				return newError("balancer ", btag, " not found")
+				return errors.New("balancer ", btag, " not found")
 			}
 			}
 			rr.Balancer = brule
 			rr.Balancer = brule
 		}
 		}
@@ -101,7 +102,7 @@ func (r *Router) AddRule(config *serial.TypedMessage, shouldAppend bool) error {
 	if c, ok := inst.(*Config); ok {
 	if c, ok := inst.(*Config); ok {
 		return r.ReloadRules(c, shouldAppend)
 		return r.ReloadRules(c, shouldAppend)
 	}
 	}
-	return newError("AddRule: config type error")
+	return errors.New("AddRule: config type error")
 }
 }
 
 
 func (r *Router) ReloadRules(config *Config, shouldAppend bool) error {
 func (r *Router) ReloadRules(config *Config, shouldAppend bool) error {
@@ -115,7 +116,7 @@ func (r *Router) ReloadRules(config *Config, shouldAppend bool) error {
 	for _, rule := range config.BalancingRule {
 	for _, rule := range config.BalancingRule {
 		_, found := r.balancers[rule.Tag]
 		_, found := r.balancers[rule.Tag]
 		if found {
 		if found {
-			return newError("duplicate balancer tag")
+			return errors.New("duplicate balancer tag")
 		}
 		}
 		balancer, err := rule.Build(r.ohm, r.dispatcher)
 		balancer, err := rule.Build(r.ohm, r.dispatcher)
 		if err != nil {
 		if err != nil {
@@ -127,7 +128,7 @@ func (r *Router) ReloadRules(config *Config, shouldAppend bool) error {
 
 
 	for _, rule := range config.Rule {
 	for _, rule := range config.Rule {
 		if r.RuleExists(rule.GetRuleTag()) {
 		if r.RuleExists(rule.GetRuleTag()) {
-			return newError("duplicate ruleTag ", rule.GetRuleTag())
+			return errors.New("duplicate ruleTag ", rule.GetRuleTag())
 		}
 		}
 		cond, err := rule.BuildCondition()
 		cond, err := rule.BuildCondition()
 		if err != nil {
 		if err != nil {
@@ -142,7 +143,7 @@ func (r *Router) ReloadRules(config *Config, shouldAppend bool) error {
 		if len(btag) > 0 {
 		if len(btag) > 0 {
 			brule, found := r.balancers[btag]
 			brule, found := r.balancers[btag]
 			if !found {
 			if !found {
-				return newError("balancer ", btag, " not found")
+				return errors.New("balancer ", btag, " not found")
 			}
 			}
 			rr.Balancer = brule
 			rr.Balancer = brule
 		}
 		}
@@ -178,7 +179,7 @@ func (r *Router) RemoveRule(tag string) error {
 		r.rules = newRules
 		r.rules = newRules
 		return nil
 		return nil
 	}
 	}
-	return newError("empty tag name!")
+	return errors.New("empty tag name!")
 
 
 }
 }
 func (r *Router) pickRouteInternal(ctx routing.Context) (*Rule, routing.Context, error) {
 func (r *Router) pickRouteInternal(ctx routing.Context) (*Rule, routing.Context, error) {

+ 4 - 3
app/router/strategy_leastload.go

@@ -9,6 +9,7 @@ import (
 	"github.com/xtls/xray-core/app/observatory"
 	"github.com/xtls/xray-core/app/observatory"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common/dice"
 	"github.com/xtls/xray-core/common/dice"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/features/extension"
 	"github.com/xtls/xray-core/features/extension"
 )
 )
@@ -95,7 +96,7 @@ func (s *LeastLoadStrategy) pickOutbounds(candidates []string) []*node {
 // with 'balancer.fallbackTag', it means: selects qualified nodes or use the fallback.
 // with 'balancer.fallbackTag', it means: selects qualified nodes or use the fallback.
 func (s *LeastLoadStrategy) selectLeastLoad(nodes []*node) []*node {
 func (s *LeastLoadStrategy) selectLeastLoad(nodes []*node) []*node {
 	if len(nodes) == 0 {
 	if len(nodes) == 0 {
-		newError("least load: no qualified outbound").AtInfo().WriteToLog()
+		errors.LogInfo(s.ctx, "least load: no qualified outbound")
 		return nil
 		return nil
 	}
 	}
 	expected := int(s.settings.Expected)
 	expected := int(s.settings.Expected)
@@ -123,7 +124,7 @@ func (s *LeastLoadStrategy) selectLeastLoad(nodes []*node) []*node {
 		}
 		}
 		// don't continue if find expected selects
 		// don't continue if find expected selects
 		if count >= expected {
 		if count >= expected {
-			newError("applied baseline: ", baseline).AtDebug().WriteToLog()
+			errors.LogDebug(s.ctx, "applied baseline: ", baseline)
 			break
 			break
 		}
 		}
 	}
 	}
@@ -142,7 +143,7 @@ func (s *LeastLoadStrategy) getNodes(candidates []string, maxRTT time.Duration)
 	}
 	}
 	observeResult, err := s.observer.GetObservation(s.ctx)
 	observeResult, err := s.observer.GetObservation(s.ctx)
 	if err != nil {
 	if err != nil {
-		newError("cannot get observation").Base(err).WriteToLog()
+		errors.LogInfoInner(s.ctx, err, "cannot get observation")
 		return make([]*node, 0)
 		return make([]*node, 0)
 	}
 	}
 
 

+ 2 - 1
app/router/strategy_leastping.go

@@ -5,6 +5,7 @@ import (
 
 
 	"github.com/xtls/xray-core/app/observatory"
 	"github.com/xtls/xray-core/app/observatory"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/features/extension"
 	"github.com/xtls/xray-core/features/extension"
 )
 )
@@ -32,7 +33,7 @@ func (l *LeastPingStrategy) PickOutbound(strings []string) string {
 
 
 	observeReport, err := l.observatory.GetObservation(l.ctx)
 	observeReport, err := l.observatory.GetObservation(l.ctx)
 	if err != nil {
 	if err != nil {
-		newError("cannot get observe report").Base(err).WriteToLog()
+		errors.LogInfoInner(l.ctx, err, "cannot get observe report")
 		return ""
 		return ""
 	}
 	}
 	outboundsList := outboundList(strings)
 	outboundsList := outboundList(strings)

+ 5 - 2
app/router/weight.go

@@ -1,10 +1,13 @@
 package router
 package router
 
 
 import (
 import (
+	"context"
 	"regexp"
 	"regexp"
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
 	"sync"
 	"sync"
+
+	"github.com/xtls/xray-core/common/errors"
 )
 )
 
 
 type weightScaler func(value, weight float64) float64
 type weightScaler func(value, weight float64) float64
@@ -64,7 +67,7 @@ func (s *WeightManager) findValue(tag string) float64 {
 		}
 		}
 		weight, err := strconv.ParseFloat(numStr, 64)
 		weight, err := strconv.ParseFloat(numStr, 64)
 		if err != nil {
 		if err != nil {
-			newError("unexpected error from ParseFloat: ", err).AtError().WriteToLog()
+			errors.LogError(context.Background(), "unexpected error from ParseFloat: ", err)
 			return s.defaultWeight
 			return s.defaultWeight
 		}
 		}
 		return weight
 		return weight
@@ -82,7 +85,7 @@ func (s *WeightManager) getMatch(tag, find string, isRegexp bool) string {
 	}
 	}
 	r, err := regexp.Compile(find)
 	r, err := regexp.Compile(find)
 	if err != nil {
 	if err != nil {
-		newError("invalid regexp: ", find, "err: ", err).AtError().WriteToLog()
+		errors.LogError(context.Background(), "invalid regexp: ", find, "err: ", err)
 		return ""
 		return ""
 	}
 	}
 	return r.FindString(tag)
 	return r.FindString(tag)

+ 2 - 1
app/stats/channel.go

@@ -5,6 +5,7 @@ import (
 	"sync"
 	"sync"
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 )
 )
 
 
 // Channel is an implementation of stats.Channel.
 // Channel is an implementation of stats.Channel.
@@ -44,7 +45,7 @@ func (c *Channel) Subscribe() (chan interface{}, error) {
 	c.access.Lock()
 	c.access.Lock()
 	defer c.access.Unlock()
 	defer c.access.Unlock()
 	if c.subsLimit > 0 && len(c.subscribers) >= c.subsLimit {
 	if c.subsLimit > 0 && len(c.subscribers) >= c.subsLimit {
-		return nil, newError("Number of subscribers has reached limit")
+		return nil, errors.New("Number of subscribers has reached limit")
 	}
 	}
 	subscriber := make(chan interface{}, c.bufferSize)
 	subscriber := make(chan interface{}, c.bufferSize)
 	c.subscribers = append(c.subscribers, subscriber)
 	c.subscribers = append(c.subscribers, subscriber)

+ 3 - 2
app/stats/command/command.go

@@ -9,6 +9,7 @@ import (
 
 
 	"github.com/xtls/xray-core/app/stats"
 	"github.com/xtls/xray-core/app/stats"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/strmatcher"
 	"github.com/xtls/xray-core/common/strmatcher"
 	"github.com/xtls/xray-core/core"
 	"github.com/xtls/xray-core/core"
 	feature_stats "github.com/xtls/xray-core/features/stats"
 	feature_stats "github.com/xtls/xray-core/features/stats"
@@ -31,7 +32,7 @@ func NewStatsServer(manager feature_stats.Manager) StatsServiceServer {
 func (s *statsServer) GetStats(ctx context.Context, request *GetStatsRequest) (*GetStatsResponse, error) {
 func (s *statsServer) GetStats(ctx context.Context, request *GetStatsRequest) (*GetStatsResponse, error) {
 	c := s.stats.GetCounter(request.Name)
 	c := s.stats.GetCounter(request.Name)
 	if c == nil {
 	if c == nil {
-		return nil, newError(request.Name, " not found.")
+		return nil, errors.New(request.Name, " not found.")
 	}
 	}
 	var value int64
 	var value int64
 	if request.Reset_ {
 	if request.Reset_ {
@@ -57,7 +58,7 @@ func (s *statsServer) QueryStats(ctx context.Context, request *QueryStatsRequest
 
 
 	manager, ok := s.stats.(*stats.Manager)
 	manager, ok := s.stats.(*stats.Manager)
 	if !ok {
 	if !ok {
-		return nil, newError("QueryStats only works its own stats.Manager.")
+		return nil, errors.New("QueryStats only works its own stats.Manager.")
 	}
 	}
 
 
 	manager.VisitCounters(func(name string, c feature_stats.Counter) bool {
 	manager.VisitCounters(func(name string, c feature_stats.Counter) bool {

+ 0 - 9
app/stats/command/errors.generated.go

@@ -1,9 +0,0 @@
-package command
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 0 - 9
app/stats/errors.generated.go

@@ -1,9 +0,0 @@
-package stats
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 7 - 7
app/stats/stats.go

@@ -40,9 +40,9 @@ func (m *Manager) RegisterCounter(name string) (stats.Counter, error) {
 	defer m.access.Unlock()
 	defer m.access.Unlock()
 
 
 	if _, found := m.counters[name]; found {
 	if _, found := m.counters[name]; found {
-		return nil, newError("Counter ", name, " already registered.")
+		return nil, errors.New("Counter ", name, " already registered.")
 	}
 	}
-	newError("create new counter ", name).AtDebug().WriteToLog()
+	errors.LogDebug(context.Background(), "create new counter ", name)
 	c := new(Counter)
 	c := new(Counter)
 	m.counters[name] = c
 	m.counters[name] = c
 	return c, nil
 	return c, nil
@@ -54,7 +54,7 @@ func (m *Manager) UnregisterCounter(name string) error {
 	defer m.access.Unlock()
 	defer m.access.Unlock()
 
 
 	if _, found := m.counters[name]; found {
 	if _, found := m.counters[name]; found {
-		newError("remove counter ", name).AtDebug().WriteToLog()
+		errors.LogDebug(context.Background(), "remove counter ", name)
 		delete(m.counters, name)
 		delete(m.counters, name)
 	}
 	}
 	return nil
 	return nil
@@ -89,9 +89,9 @@ func (m *Manager) RegisterChannel(name string) (stats.Channel, error) {
 	defer m.access.Unlock()
 	defer m.access.Unlock()
 
 
 	if _, found := m.channels[name]; found {
 	if _, found := m.channels[name]; found {
-		return nil, newError("Channel ", name, " already registered.")
+		return nil, errors.New("Channel ", name, " already registered.")
 	}
 	}
-	newError("create new channel ", name).AtDebug().WriteToLog()
+	errors.LogDebug(context.Background(), "create new channel ", name)
 	c := NewChannel(&ChannelConfig{BufferSize: 64, Blocking: false})
 	c := NewChannel(&ChannelConfig{BufferSize: 64, Blocking: false})
 	m.channels[name] = c
 	m.channels[name] = c
 	if m.running {
 	if m.running {
@@ -106,7 +106,7 @@ func (m *Manager) UnregisterChannel(name string) error {
 	defer m.access.Unlock()
 	defer m.access.Unlock()
 
 
 	if c, found := m.channels[name]; found {
 	if c, found := m.channels[name]; found {
-		newError("remove channel ", name).AtDebug().WriteToLog()
+		errors.LogDebug(context.Background(), "remove channel ", name)
 		delete(m.channels, name)
 		delete(m.channels, name)
 		return c.Close()
 		return c.Close()
 	}
 	}
@@ -148,7 +148,7 @@ func (m *Manager) Close() error {
 	m.running = false
 	m.running = false
 	errs := []error{}
 	errs := []error{}
 	for name, channel := range m.channels {
 	for name, channel := range m.channels {
-		newError("remove channel ", name).AtDebug().WriteToLog()
+		errors.LogDebug(context.Background(), "remove channel ", name)
 		delete(m.channels, name)
 		delete(m.channels, name)
 		if err := channel.Close(); err != nil {
 		if err := channel.Close(); err != nil {
 			errs = append(errs, err)
 			errs = append(errs, err)

+ 3 - 2
common/buf/buffer.go

@@ -4,6 +4,7 @@ import (
 	"io"
 	"io"
 
 
 	"github.com/xtls/xray-core/common/bytespool"
 	"github.com/xtls/xray-core/common/bytespool"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 )
 )
 
 
@@ -226,7 +227,7 @@ func (b *Buffer) Write(data []byte) (int, error) {
 // WriteByte writes a single byte into the buffer.
 // WriteByte writes a single byte into the buffer.
 func (b *Buffer) WriteByte(v byte) error {
 func (b *Buffer) WriteByte(v byte) error {
 	if b.IsFull() {
 	if b.IsFull() {
-		return newError("buffer full")
+		return errors.New("buffer full")
 	}
 	}
 	b.v[b.end] = v
 	b.v[b.end] = v
 	b.end++
 	b.end++
@@ -286,7 +287,7 @@ func (b *Buffer) ReadFullFrom(reader io.Reader, size int32) (int64, error) {
 	end := b.end + size
 	end := b.end + size
 	if end > int32(len(b.v)) {
 	if end > int32(len(b.v)) {
 		v := end
 		v := end
-		return 0, newError("out of bound: ", v)
+		return 0, errors.New("out of bound: ", v)
 	}
 	}
 	n, err := io.ReadFull(reader, b.v[b.end:end])
 	n, err := io.ReadFull(reader, b.v[b.end:end])
 	b.end += int32(n)
 	b.end += int32(n)

+ 1 - 1
common/buf/copy.go

@@ -120,7 +120,7 @@ func Copy(reader Reader, writer Writer, options ...CopyOption) error {
 	return nil
 	return nil
 }
 }
 
 
-var ErrNotTimeoutReader = newError("not a TimeoutReader")
+var ErrNotTimeoutReader = errors.New("not a TimeoutReader")
 
 
 func CopyOnceTimeout(reader Reader, writer Writer, timeout time.Duration) error {
 func CopyOnceTimeout(reader Reader, writer Writer, timeout time.Duration) error {
 	timeoutReader, ok := reader.(TimeoutReader)
 	timeoutReader, ok := reader.(TimeoutReader)

+ 2 - 2
common/buf/copy_test.go

@@ -27,7 +27,7 @@ func TestReadError(t *testing.T) {
 		t.Error("expected to be ReadError, but not")
 		t.Error("expected to be ReadError, but not")
 	}
 	}
 
 
-	if err.Error() != "error" {
+	if err.Error() != "common/buf_test: error" {
 		t.Fatal("unexpected error message: ", err.Error())
 		t.Fatal("unexpected error message: ", err.Error())
 	}
 	}
 }
 }
@@ -48,7 +48,7 @@ func TestWriteError(t *testing.T) {
 		t.Error("expected to be WriteError, but not")
 		t.Error("expected to be WriteError, but not")
 	}
 	}
 
 
-	if err.Error() != "error" {
+	if err.Error() != "common/buf_test: error" {
 		t.Fatal("unexpected error message: ", err.Error())
 		t.Fatal("unexpected error message: ", err.Error())
 	}
 	}
 }
 }

+ 0 - 9
common/buf/errors.generated.go

@@ -1,9 +0,0 @@
-package buf
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 4 - 2
common/buf/io.go

@@ -1,12 +1,14 @@
 package buf
 package buf
 
 
 import (
 import (
+	"context"
 	"io"
 	"io"
 	"net"
 	"net"
 	"os"
 	"os"
 	"syscall"
 	"syscall"
 	"time"
 	"time"
 
 
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/features/stats"
 	"github.com/xtls/xray-core/features/stats"
 	"github.com/xtls/xray-core/transport/internet/stat"
 	"github.com/xtls/xray-core/transport/internet/stat"
 )
 )
@@ -18,7 +20,7 @@ type Reader interface {
 }
 }
 
 
 // ErrReadTimeout is an error that happens with IO timeout.
 // ErrReadTimeout is an error that happens with IO timeout.
-var ErrReadTimeout = newError("IO timeout")
+var ErrReadTimeout = errors.New("IO timeout")
 
 
 // TimeoutReader is a reader that returns error if Read() operation takes longer than the given timeout.
 // TimeoutReader is a reader that returns error if Read() operation takes longer than the given timeout.
 type TimeoutReader interface {
 type TimeoutReader interface {
@@ -74,7 +76,7 @@ func NewReader(reader io.Reader) Reader {
 		if sc, ok := reader.(syscall.Conn); ok {
 		if sc, ok := reader.(syscall.Conn); ok {
 			rawConn, err := sc.SyscallConn()
 			rawConn, err := sc.SyscallConn()
 			if err != nil {
 			if err != nil {
-				newError("failed to get sysconn").Base(err).WriteToLog()
+				errors.LogInfoInner(context.Background(), err, "failed to get sysconn")
 			} else {
 			} else {
 				var counter stats.Counter
 				var counter stats.Counter
 
 

+ 1 - 1
common/buf/reader.go

@@ -21,7 +21,7 @@ func readOneUDP(r io.Reader) (*Buffer, error) {
 	}
 	}
 
 
 	b.Release()
 	b.Release()
-	return nil, newError("Reader returns too many empty payloads.")
+	return nil, errors.New("Reader returns too many empty payloads.")
 }
 }
 
 
 // ReadBuffer reads a Buffer from the given reader.
 // ReadBuffer reads a Buffer from the given reader.

+ 5 - 4
common/crypto/auth.go

@@ -8,6 +8,7 @@ import (
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common/buf"
 	"github.com/xtls/xray-core/common/buf"
 	"github.com/xtls/xray-core/common/bytespool"
 	"github.com/xtls/xray-core/common/bytespool"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/protocol"
 	"github.com/xtls/xray-core/common/protocol"
 )
 )
 
 
@@ -63,7 +64,7 @@ type AEADAuthenticator struct {
 func (v *AEADAuthenticator) Open(dst, cipherText []byte) ([]byte, error) {
 func (v *AEADAuthenticator) Open(dst, cipherText []byte) ([]byte, error) {
 	iv := v.NonceGenerator()
 	iv := v.NonceGenerator()
 	if len(iv) != v.AEAD.NonceSize() {
 	if len(iv) != v.AEAD.NonceSize() {
-		return nil, newError("invalid AEAD nonce size: ", len(iv))
+		return nil, errors.New("invalid AEAD nonce size: ", len(iv))
 	}
 	}
 
 
 	var additionalData []byte
 	var additionalData []byte
@@ -76,7 +77,7 @@ func (v *AEADAuthenticator) Open(dst, cipherText []byte) ([]byte, error) {
 func (v *AEADAuthenticator) Seal(dst, plainText []byte) ([]byte, error) {
 func (v *AEADAuthenticator) Seal(dst, plainText []byte) ([]byte, error) {
 	iv := v.NonceGenerator()
 	iv := v.NonceGenerator()
 	if len(iv) != v.AEAD.NonceSize() {
 	if len(iv) != v.AEAD.NonceSize() {
-		return nil, newError("invalid AEAD nonce size: ", len(iv))
+		return nil, errors.New("invalid AEAD nonce size: ", len(iv))
 	}
 	}
 
 
 	var additionalData []byte
 	var additionalData []byte
@@ -131,7 +132,7 @@ func (r *AuthenticationReader) readSize() (uint16, uint16, error) {
 	return size, padding, err
 	return size, padding, err
 }
 }
 
 
-var errSoft = newError("waiting for more data")
+var errSoft = errors.New("waiting for more data")
 
 
 func (r *AuthenticationReader) readBuffer(size int32, padding int32) (*buf.Buffer, error) {
 func (r *AuthenticationReader) readBuffer(size int32, padding int32) (*buf.Buffer, error) {
 	b := buf.New()
 	b := buf.New()
@@ -255,7 +256,7 @@ func (w *AuthenticationWriter) seal(b []byte) (*buf.Buffer, error) {
 	sizeBytes := w.sizeParser.SizeBytes()
 	sizeBytes := w.sizeParser.SizeBytes()
 	totalSize := sizeBytes + encryptedSize + paddingSize
 	totalSize := sizeBytes + encryptedSize + paddingSize
 	if totalSize > buf.Size {
 	if totalSize > buf.Size {
-		return nil, newError("size too large: ", totalSize)
+		return nil, errors.New("size too large: ", totalSize)
 	}
 	}
 
 
 	eb := buf.New()
 	eb := buf.New()

+ 0 - 9
common/crypto/errors.generated.go

@@ -1,9 +0,0 @@
-package crypto
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 25 - 0
common/ctx/context.go

@@ -0,0 +1,25 @@
+package ctx
+
+import "context"
+
+type SessionKey int
+
+// ID of a session.
+type ID uint32
+
+const(
+	idSessionKey SessionKey = 0
+)
+
+// ContextWithID returns a new context with the given ID.
+func ContextWithID(ctx context.Context, id ID) context.Context {
+	return context.WithValue(ctx, idSessionKey, id)
+}
+
+// IDFromContext returns ID in this context, or 0 if not contained.
+func IDFromContext(ctx context.Context) ID {
+	if id, ok := ctx.Value(idSessionKey).(ID); ok {
+		return id
+	}
+	return 0
+}

+ 4 - 3
common/drain/drainer.go

@@ -4,6 +4,7 @@ import (
 	"io"
 	"io"
 
 
 	"github.com/xtls/xray-core/common/dice"
 	"github.com/xtls/xray-core/common/dice"
+	"github.com/xtls/xray-core/common/errors"
 )
 )
 
 
 type BehaviorSeedLimitedDrainer struct {
 type BehaviorSeedLimitedDrainer struct {
@@ -27,9 +28,9 @@ func (d *BehaviorSeedLimitedDrainer) Drain(reader io.Reader) error {
 	if d.DrainSize > 0 {
 	if d.DrainSize > 0 {
 		err := drainReadN(reader, d.DrainSize)
 		err := drainReadN(reader, d.DrainSize)
 		if err == nil {
 		if err == nil {
-			return newError("drained connection")
+			return errors.New("drained connection")
 		}
 		}
-		return newError("unable to drain connection").Base(err)
+		return errors.New("unable to drain connection").Base(err)
 	}
 	}
 	return nil
 	return nil
 }
 }
@@ -44,7 +45,7 @@ func WithError(drainer Drainer, reader io.Reader, err error) error {
 	if drainErr == nil {
 	if drainErr == nil {
 		return err
 		return err
 	}
 	}
-	return newError(drainErr).Base(err)
+	return errors.New(drainErr).Base(err)
 }
 }
 
 
 type NopDrainer struct{}
 type NopDrainer struct{}

+ 0 - 9
common/drain/errors.generated.go

@@ -1,9 +0,0 @@
-package drain
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 0 - 9
common/errors.generated.go

@@ -1,9 +0,0 @@
-package common
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 0 - 37
common/errors/errorgen/main.go

@@ -1,37 +0,0 @@
-package main
-
-import (
-	"fmt"
-	"os"
-	"path/filepath"
-)
-
-func main() {
-	pwd, err := os.Getwd()
-	if err != nil {
-		fmt.Println("can not get current working directory")
-		os.Exit(1)
-	}
-	pkg := filepath.Base(pwd)
-	if pkg == "xray-core" {
-		pkg = "core"
-	}
-
-	file, err := os.OpenFile("errors.generated.go", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0o644)
-	if err != nil {
-		fmt.Printf("Failed to generate errors.generated.go: %v", err)
-		os.Exit(1)
-	}
-	defer file.Close()
-
-	fmt.Fprintf(file, `package %s
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}
-`, pkg)
-}

+ 76 - 39
common/errors/errors.go

@@ -2,9 +2,11 @@
 package errors // import "github.com/xtls/xray-core/common/errors"
 package errors // import "github.com/xtls/xray-core/common/errors"
 
 
 import (
 import (
-	"reflect"
+	"context"
+	"runtime"
 	"strings"
 	"strings"
 
 
+	c "github.com/xtls/xray-core/common/ctx"
 	"github.com/xtls/xray-core/common/log"
 	"github.com/xtls/xray-core/common/log"
 	"github.com/xtls/xray-core/common/serial"
 	"github.com/xtls/xray-core/common/serial"
 )
 )
@@ -22,29 +24,13 @@ type hasSeverity interface {
 
 
 // Error is an error object with underlying error.
 // Error is an error object with underlying error.
 type Error struct {
 type Error struct {
-	pathObj  interface{}
 	prefix   []interface{}
 	prefix   []interface{}
 	message  []interface{}
 	message  []interface{}
+	caller   string
 	inner    error
 	inner    error
 	severity log.Severity
 	severity log.Severity
 }
 }
 
 
-func (err *Error) WithPathObj(obj interface{}) *Error {
-	err.pathObj = obj
-	return err
-}
-
-func (err *Error) pkgPath() string {
-	if err.pathObj == nil {
-		return ""
-	}
-	path := reflect.TypeOf(err.pathObj).PkgPath()
-	if len(path) >= trim {
-		return path[trim:]
-	}
-	return path
-}
-
 // Error implements error.Error().
 // Error implements error.Error().
 func (err *Error) Error() string {
 func (err *Error) Error() string {
 	builder := strings.Builder{}
 	builder := strings.Builder{}
@@ -54,9 +40,8 @@ func (err *Error) Error() string {
 		builder.WriteString("] ")
 		builder.WriteString("] ")
 	}
 	}
 
 
-	path := err.pkgPath()
-	if len(path) > 0 {
-		builder.WriteString(path)
+	if len(err.caller) > 0 {
+		builder.WriteString(err.caller)
 		builder.WriteString(": ")
 		builder.WriteString(": ")
 	}
 	}
 
 
@@ -129,24 +114,6 @@ func (err *Error) String() string {
 	return err.Error()
 	return err.Error()
 }
 }
 
 
-// WriteToLog writes current error into log.
-func (err *Error) WriteToLog(opts ...ExportOption) {
-	var holder ExportOptionHolder
-
-	for _, opt := range opts {
-		opt(&holder)
-	}
-
-	if holder.SessionID > 0 {
-		err.prefix = append(err.prefix, holder.SessionID)
-	}
-
-	log.Record(&log.GeneralMessage{
-		Severity: GetSeverity(err),
-		Content:  err,
-	})
-}
-
 type ExportOptionHolder struct {
 type ExportOptionHolder struct {
 	SessionID uint32
 	SessionID uint32
 }
 }
@@ -155,10 +122,80 @@ type ExportOption func(*ExportOptionHolder)
 
 
 // New returns a new error object with message formed from given arguments.
 // New returns a new error object with message formed from given arguments.
 func New(msg ...interface{}) *Error {
 func New(msg ...interface{}) *Error {
+	pc, _, _, _ := runtime.Caller(1)
+	details := runtime.FuncForPC(pc).Name()
+	if len(details) >= trim {
+		details = details[trim:]
+	}
+	i := strings.Index(details, ".")
+	if i > 0 {
+		details = details[:i]
+	}
 	return &Error{
 	return &Error{
 		message:  msg,
 		message:  msg,
 		severity: log.Severity_Info,
 		severity: log.Severity_Info,
+		caller:   details,
+	}
+}
+
+func LogDebug(ctx context.Context, msg ...interface{}) {
+	doLog(ctx, nil, log.Severity_Debug, msg...)
+}
+
+func LogDebugInner(ctx context.Context, inner error, msg ...interface{}) {
+	doLog(ctx, inner, log.Severity_Debug, msg...)
+}
+
+func LogInfo(ctx context.Context, msg ...interface{}) {
+	doLog(ctx, nil, log.Severity_Info, msg...)
+}
+
+func LogInfoInner(ctx context.Context, inner error, msg ...interface{}) {
+	doLog(ctx, inner, log.Severity_Debug, msg...)
+}
+
+func LogWarning(ctx context.Context, msg ...interface{}) {
+	doLog(ctx, nil, log.Severity_Warning, msg...)
+}
+
+func LogWarningInner(ctx context.Context, inner error, msg ...interface{}) {
+	doLog(ctx, inner, log.Severity_Debug, msg...)
+}
+
+func LogError(ctx context.Context, msg ...interface{}) {
+	doLog(ctx, nil, log.Severity_Error, msg...)
+}
+
+func LogErrorInner(ctx context.Context, inner error, msg ...interface{}) {
+	doLog(ctx, inner, log.Severity_Debug, msg...)
+}
+
+func doLog(ctx context.Context, inner error, severity log.Severity, msg ...interface{}) {
+	pc, _, _, _ := runtime.Caller(2)
+	details := runtime.FuncForPC(pc).Name()
+	if len(details) >= trim {
+		details = details[trim:]
+	}
+	i := strings.Index(details, ".")
+	if i > 0 {
+		details = details[:i]
+	}
+	err := &Error{
+		message:  msg,
+		severity: severity,
+		caller:   details,
+		inner:    inner,
 	}
 	}
+	if ctx != nil && ctx != context.Background() {
+		id := uint32(c.IDFromContext(ctx))
+		if id > 0 {
+			err.prefix = append(err.prefix, id)
+		}
+	}
+	log.Record(&log.GeneralMessage{
+		Severity: GetSeverity(err),
+		Content:  err,
+	})
 }
 }
 
 
 // Cause returns the root cause of this error.
 // Cause returns the root cause of this error.

+ 2 - 8
common/errors/errors_test.go

@@ -36,20 +36,14 @@ func TestError(t *testing.T) {
 	}
 	}
 }
 }
 
 
-type e struct{}
-
 func TestErrorMessage(t *testing.T) {
 func TestErrorMessage(t *testing.T) {
 	data := []struct {
 	data := []struct {
 		err error
 		err error
 		msg string
 		msg string
 	}{
 	}{
 		{
 		{
-			err: New("a").Base(New("b")).WithPathObj(e{}),
-			msg: "common/errors_test: a > b",
-		},
-		{
-			err: New("a").Base(New("b").WithPathObj(e{})),
-			msg: "a > common/errors_test: b",
+			err: New("a").Base(New("b")),
+			msg: "common/errors_test: a > common/errors_test: b",
 		},
 		},
 	}
 	}
 
 

+ 11 - 11
common/mux/client.go

@@ -37,7 +37,7 @@ func (m *ClientManager) Dispatch(ctx context.Context, link *transport.Link) erro
 		}
 		}
 	}
 	}
 
 
-	return newError("unable to find an available mux client").AtWarning()
+	return errors.New("unable to find an available mux client").AtWarning()
 }
 }
 
 
 type WorkerPicker interface {
 type WorkerPicker interface {
@@ -57,7 +57,7 @@ func (p *IncrementalWorkerPicker) cleanupFunc() error {
 	defer p.access.Unlock()
 	defer p.access.Unlock()
 
 
 	if len(p.workers) == 0 {
 	if len(p.workers) == 0 {
-		return newError("no worker")
+		return errors.New("no worker")
 	}
 	}
 
 
 	p.cleanup()
 	p.cleanup()
@@ -155,7 +155,7 @@ func (f *DialingWorkerFactory) Create() (*ClientWorker, error) {
 		ctx, cancel := context.WithCancel(ctx)
 		ctx, cancel := context.WithCancel(ctx)
 
 
 		if err := p.Process(ctx, &transport.Link{Reader: uplinkReader, Writer: downlinkWriter}, d); err != nil {
 		if err := p.Process(ctx, &transport.Link{Reader: uplinkReader, Writer: downlinkWriter}, d); err != nil {
-			errors.New("failed to handler mux client connection").Base(err).WriteToLog()
+			errors.LogInfoInner(ctx, err, "failed to handler mux client connection")
 		}
 		}
 		common.Must(c.Close())
 		common.Must(c.Close())
 		cancel()
 		cancel()
@@ -244,7 +244,7 @@ func writeFirstPayload(reader buf.Reader, writer *Writer) error {
 
 
 func fetchInput(ctx context.Context, s *Session, output buf.Writer) {
 func fetchInput(ctx context.Context, s *Session, output buf.Writer) {
 	outbounds := session.OutboundsFromContext(ctx)
 	outbounds := session.OutboundsFromContext(ctx)
-	ob := outbounds[len(outbounds) - 1]
+	ob := outbounds[len(outbounds)-1]
 	transferType := protocol.TransferTypeStream
 	transferType := protocol.TransferTypeStream
 	if ob.Target.Network == net.Network_UDP {
 	if ob.Target.Network == net.Network_UDP {
 		transferType = protocol.TransferTypePacket
 		transferType = protocol.TransferTypePacket
@@ -254,15 +254,15 @@ func fetchInput(ctx context.Context, s *Session, output buf.Writer) {
 	defer s.Close(false)
 	defer s.Close(false)
 	defer writer.Close()
 	defer writer.Close()
 
 
-	newError("dispatching request to ", ob.Target).WriteToLog(session.ExportIDToError(ctx))
+	errors.LogInfo(ctx, "dispatching request to ", ob.Target)
 	if err := writeFirstPayload(s.input, writer); err != nil {
 	if err := writeFirstPayload(s.input, writer); err != nil {
-		newError("failed to write first payload").Base(err).WriteToLog(session.ExportIDToError(ctx))
+		errors.LogInfoInner(ctx, err, "failed to write first payload")
 		writer.hasError = true
 		writer.hasError = true
 		return
 		return
 	}
 	}
 
 
 	if err := buf.Copy(s.input, writer); err != nil {
 	if err := buf.Copy(s.input, writer); err != nil {
-		newError("failed to fetch all input").Base(err).WriteToLog(session.ExportIDToError(ctx))
+		errors.LogInfoInner(ctx, err, "failed to fetch all input")
 		writer.hasError = true
 		writer.hasError = true
 		return
 		return
 	}
 	}
@@ -335,7 +335,7 @@ func (m *ClientWorker) handleStatusKeep(meta *FrameMetadata, reader *buf.Buffere
 	rr := s.NewReader(reader, &meta.Target)
 	rr := s.NewReader(reader, &meta.Target)
 	err := buf.Copy(rr, s.output)
 	err := buf.Copy(rr, s.output)
 	if err != nil && buf.IsWriteError(err) {
 	if err != nil && buf.IsWriteError(err) {
-		newError("failed to write to downstream. closing session ", s.ID).Base(err).WriteToLog()
+		errors.LogInfoInner(context.Background(), err, "failed to write to downstream. closing session ", s.ID)
 		s.Close(false)
 		s.Close(false)
 		return buf.Copy(rr, buf.Discard)
 		return buf.Copy(rr, buf.Discard)
 	}
 	}
@@ -365,7 +365,7 @@ func (m *ClientWorker) fetchOutput() {
 		err := meta.Unmarshal(reader)
 		err := meta.Unmarshal(reader)
 		if err != nil {
 		if err != nil {
 			if errors.Cause(err) != io.EOF {
 			if errors.Cause(err) != io.EOF {
-				newError("failed to read metadata").Base(err).WriteToLog()
+				errors.LogInfoInner(context.Background(), err, "failed to read metadata")
 			}
 			}
 			break
 			break
 		}
 		}
@@ -381,12 +381,12 @@ func (m *ClientWorker) fetchOutput() {
 			err = m.handleStatusKeep(&meta, reader)
 			err = m.handleStatusKeep(&meta, reader)
 		default:
 		default:
 			status := meta.SessionStatus
 			status := meta.SessionStatus
-			newError("unknown status: ", status).AtError().WriteToLog()
+			errors.LogError(context.Background(), "unknown status: ", status)
 			return
 			return
 		}
 		}
 
 
 		if err != nil {
 		if err != nil {
-			newError("failed to process data").Base(err).WriteToLog()
+			errors.LogInfoInner(context.Background(), err, "failed to process data")
 			return
 			return
 		}
 		}
 	}
 	}

+ 0 - 9
common/mux/errors.generated.go

@@ -1,9 +0,0 @@
-package mux
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 6 - 5
common/mux/frame.go

@@ -7,6 +7,7 @@ import (
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common/bitmask"
 	"github.com/xtls/xray-core/common/bitmask"
 	"github.com/xtls/xray-core/common/buf"
 	"github.com/xtls/xray-core/common/buf"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/protocol"
 	"github.com/xtls/xray-core/common/protocol"
 	"github.com/xtls/xray-core/common/serial"
 	"github.com/xtls/xray-core/common/serial"
@@ -102,7 +103,7 @@ func (f *FrameMetadata) Unmarshal(reader io.Reader) error {
 		return err
 		return err
 	}
 	}
 	if metaLen > 512 {
 	if metaLen > 512 {
-		return newError("invalid metalen ", metaLen).AtError()
+		return errors.New("invalid metalen ", metaLen).AtError()
 	}
 	}
 
 
 	b := buf.New()
 	b := buf.New()
@@ -118,7 +119,7 @@ func (f *FrameMetadata) Unmarshal(reader io.Reader) error {
 // Visible for testing only.
 // Visible for testing only.
 func (f *FrameMetadata) UnmarshalFromBuffer(b *buf.Buffer) error {
 func (f *FrameMetadata) UnmarshalFromBuffer(b *buf.Buffer) error {
 	if b.Len() < 4 {
 	if b.Len() < 4 {
-		return newError("insufficient buffer: ", b.Len())
+		return errors.New("insufficient buffer: ", b.Len())
 	}
 	}
 
 
 	f.SessionID = binary.BigEndian.Uint16(b.BytesTo(2))
 	f.SessionID = binary.BigEndian.Uint16(b.BytesTo(2))
@@ -129,14 +130,14 @@ func (f *FrameMetadata) UnmarshalFromBuffer(b *buf.Buffer) error {
 	if f.SessionStatus == SessionStatusNew || (f.SessionStatus == SessionStatusKeep && b.Len() > 4 &&
 	if f.SessionStatus == SessionStatusNew || (f.SessionStatus == SessionStatusKeep && b.Len() > 4 &&
 		TargetNetwork(b.Byte(4)) == TargetNetworkUDP) { // MUST check the flag first
 		TargetNetwork(b.Byte(4)) == TargetNetworkUDP) { // MUST check the flag first
 		if b.Len() < 8 {
 		if b.Len() < 8 {
-			return newError("insufficient buffer: ", b.Len())
+			return errors.New("insufficient buffer: ", b.Len())
 		}
 		}
 		network := TargetNetwork(b.Byte(4))
 		network := TargetNetwork(b.Byte(4))
 		b.Advance(5)
 		b.Advance(5)
 
 
 		addr, port, err := addrParser.ReadAddressPort(nil, b)
 		addr, port, err := addrParser.ReadAddressPort(nil, b)
 		if err != nil {
 		if err != nil {
-			return newError("failed to parse address and port").Base(err)
+			return errors.New("failed to parse address and port").Base(err)
 		}
 		}
 
 
 		switch network {
 		switch network {
@@ -145,7 +146,7 @@ func (f *FrameMetadata) UnmarshalFromBuffer(b *buf.Buffer) error {
 		case TargetNetworkUDP:
 		case TargetNetworkUDP:
 			f.Target = net.UDPDestination(addr, port)
 			f.Target = net.UDPDestination(addr, port)
 		default:
 		default:
-			return newError("unknown network type: ", network)
+			return errors.New("unknown network type: ", network)
 		}
 		}
 	}
 	}
 
 

+ 2 - 1
common/mux/reader.go

@@ -5,6 +5,7 @@ import (
 
 
 	"github.com/xtls/xray-core/common/buf"
 	"github.com/xtls/xray-core/common/buf"
 	"github.com/xtls/xray-core/common/crypto"
 	"github.com/xtls/xray-core/common/crypto"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/serial"
 	"github.com/xtls/xray-core/common/serial"
 )
 )
@@ -37,7 +38,7 @@ func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
 	}
 	}
 
 
 	if size > buf.Size {
 	if size > buf.Size {
-		return nil, newError("packet size too large: ", size)
+		return nil, errors.New("packet size too large: ", size)
 	}
 	}
 
 
 	b := buf.New()
 	b := buf.New()

+ 13 - 13
common/mux/server.go

@@ -94,7 +94,7 @@ func NewServerWorker(ctx context.Context, d routing.Dispatcher, link *transport.
 func handle(ctx context.Context, s *Session, output buf.Writer) {
 func handle(ctx context.Context, s *Session, output buf.Writer) {
 	writer := NewResponseWriter(s.ID, output, s.transferType)
 	writer := NewResponseWriter(s.ID, output, s.transferType)
 	if err := buf.Copy(s.input, writer); err != nil {
 	if err := buf.Copy(s.input, writer); err != nil {
-		newError("session ", s.ID, " ends.").Base(err).WriteToLog(session.ExportIDToError(ctx))
+		errors.LogInfoInner(ctx, err, "session ", s.ID, " ends.")
 		writer.hasError = true
 		writer.hasError = true
 	}
 	}
 
 
@@ -118,7 +118,7 @@ func (w *ServerWorker) handleStatusKeepAlive(meta *FrameMetadata, reader *buf.Bu
 }
 }
 
 
 func (w *ServerWorker) handleStatusNew(ctx context.Context, meta *FrameMetadata, reader *buf.BufferedReader) error {
 func (w *ServerWorker) handleStatusNew(ctx context.Context, meta *FrameMetadata, reader *buf.BufferedReader) error {
-	newError("received request for ", meta.Target).WriteToLog(session.ExportIDToError(ctx))
+	errors.LogInfo(ctx, "received request for ", meta.Target)
 	{
 	{
 		msg := &log.AccessMessage{
 		msg := &log.AccessMessage{
 			To:     meta.Target,
 			To:     meta.Target,
@@ -134,7 +134,7 @@ func (w *ServerWorker) handleStatusNew(ctx context.Context, meta *FrameMetadata,
 
 
 	if network := session.AllowedNetworkFromContext(ctx); network != net.Network_Unknown {
 	if network := session.AllowedNetworkFromContext(ctx); network != net.Network_Unknown {
 		if meta.Target.Network != network {
 		if meta.Target.Network != network {
-			return newError("unexpected network ", meta.Target.Network) // it will break the whole Mux connection
+			return errors.New("unexpected network ", meta.Target.Network) // it will break the whole Mux connection
 		}
 		}
 	}
 	}
 
 
@@ -152,7 +152,7 @@ func (w *ServerWorker) handleStatusNew(ctx context.Context, meta *FrameMetadata,
 		} else {
 		} else {
 			if x.Status == Initializing { // nearly impossible
 			if x.Status == Initializing { // nearly impossible
 				XUDPManager.Unlock()
 				XUDPManager.Unlock()
-				newError("XUDP hit ", meta.GlobalID).Base(errors.New("conflict")).AtWarning().WriteToLog(session.ExportIDToError(ctx))
+				errors.LogWarningInner(ctx, errors.New("conflict"), "XUDP hit ", meta.GlobalID)
 				// It's not a good idea to return an err here, so just let client wait.
 				// It's not a good idea to return an err here, so just let client wait.
 				// Client will receive an End frame after sending a Keep frame.
 				// Client will receive an End frame after sending a Keep frame.
 				return nil
 				return nil
@@ -170,7 +170,7 @@ func (w *ServerWorker) handleStatusNew(ctx context.Context, meta *FrameMetadata,
 				b.Release()
 				b.Release()
 				mb = nil
 				mb = nil
 			}
 			}
-			newError("XUDP hit ", meta.GlobalID).Base(err).WriteToLog(session.ExportIDToError(ctx))
+			errors.LogInfoInner(ctx, err,"XUDP hit ", meta.GlobalID)
 		}
 		}
 		if mb != nil {
 		if mb != nil {
 			ctx = session.ContextWithTimeoutOnly(ctx, true)
 			ctx = session.ContextWithTimeoutOnly(ctx, true)
@@ -180,7 +180,7 @@ func (w *ServerWorker) handleStatusNew(ctx context.Context, meta *FrameMetadata,
 				XUDPManager.Lock()
 				XUDPManager.Lock()
 				delete(XUDPManager.Map, x.GlobalID)
 				delete(XUDPManager.Map, x.GlobalID)
 				XUDPManager.Unlock()
 				XUDPManager.Unlock()
-				err = newError("XUDP new ", meta.GlobalID).Base(errors.New("failed to dispatch request to ", meta.Target).Base(err))
+				err = errors.New("XUDP new ", meta.GlobalID).Base(errors.New("failed to dispatch request to ", meta.Target).Base(err))
 				return err // it will break the whole Mux connection
 				return err // it will break the whole Mux connection
 			}
 			}
 			link.Writer.WriteMultiBuffer(mb) // it's meaningless to test a new pipe
 			link.Writer.WriteMultiBuffer(mb) // it's meaningless to test a new pipe
@@ -188,7 +188,7 @@ func (w *ServerWorker) handleStatusNew(ctx context.Context, meta *FrameMetadata,
 				input:  link.Reader,
 				input:  link.Reader,
 				output: link.Writer,
 				output: link.Writer,
 			}
 			}
-			newError("XUDP new ", meta.GlobalID).Base(err).WriteToLog(session.ExportIDToError(ctx))
+			errors.LogInfoInner(ctx, err, "XUDP new ", meta.GlobalID)
 		}
 		}
 		x.Mux = &Session{
 		x.Mux = &Session{
 			input:        x.Mux.input,
 			input:        x.Mux.input,
@@ -211,7 +211,7 @@ func (w *ServerWorker) handleStatusNew(ctx context.Context, meta *FrameMetadata,
 		if meta.Option.Has(OptionData) {
 		if meta.Option.Has(OptionData) {
 			buf.Copy(NewStreamReader(reader), buf.Discard)
 			buf.Copy(NewStreamReader(reader), buf.Discard)
 		}
 		}
-		return newError("failed to dispatch request.").Base(err)
+		return errors.New("failed to dispatch request.").Base(err)
 	}
 	}
 	s := &Session{
 	s := &Session{
 		input:        link.Reader,
 		input:        link.Reader,
@@ -255,7 +255,7 @@ func (w *ServerWorker) handleStatusKeep(meta *FrameMetadata, reader *buf.Buffere
 	err := buf.Copy(rr, s.output)
 	err := buf.Copy(rr, s.output)
 
 
 	if err != nil && buf.IsWriteError(err) {
 	if err != nil && buf.IsWriteError(err) {
-		newError("failed to write to downstream writer. closing session ", s.ID).Base(err).WriteToLog()
+		errors.LogInfoInner(context.Background(), err, "failed to write to downstream writer. closing session ", s.ID)
 		s.Close(false)
 		s.Close(false)
 		return buf.Copy(rr, buf.Discard)
 		return buf.Copy(rr, buf.Discard)
 	}
 	}
@@ -277,7 +277,7 @@ func (w *ServerWorker) handleFrame(ctx context.Context, reader *buf.BufferedRead
 	var meta FrameMetadata
 	var meta FrameMetadata
 	err := meta.Unmarshal(reader)
 	err := meta.Unmarshal(reader)
 	if err != nil {
 	if err != nil {
-		return newError("failed to read metadata").Base(err)
+		return errors.New("failed to read metadata").Base(err)
 	}
 	}
 
 
 	switch meta.SessionStatus {
 	switch meta.SessionStatus {
@@ -291,11 +291,11 @@ func (w *ServerWorker) handleFrame(ctx context.Context, reader *buf.BufferedRead
 		err = w.handleStatusKeep(&meta, reader)
 		err = w.handleStatusKeep(&meta, reader)
 	default:
 	default:
 		status := meta.SessionStatus
 		status := meta.SessionStatus
-		return newError("unknown status: ", status).AtError()
+		return errors.New("unknown status: ", status).AtError()
 	}
 	}
 
 
 	if err != nil {
 	if err != nil {
-		return newError("failed to process data").Base(err)
+		return errors.New("failed to process data").Base(err)
 	}
 	}
 	return nil
 	return nil
 }
 }
@@ -314,7 +314,7 @@ func (w *ServerWorker) run(ctx context.Context) {
 			err := w.handleFrame(ctx, reader)
 			err := w.handleFrame(ctx, reader)
 			if err != nil {
 			if err != nil {
 				if errors.Cause(err) != io.EOF {
 				if errors.Cause(err) != io.EOF {
-					newError("unexpected EOF").Base(err).WriteToLog(session.ExportIDToError(ctx))
+					errors.LogInfoInner(ctx, err, "unexpected EOF")
 					common.Interrupt(input)
 					common.Interrupt(input)
 				}
 				}
 				return
 				return

+ 4 - 2
common/mux/session.go

@@ -1,6 +1,7 @@
 package mux
 package mux
 
 
 import (
 import (
+	"context"
 	"io"
 	"io"
 	"runtime"
 	"runtime"
 	"sync"
 	"sync"
@@ -8,6 +9,7 @@ import (
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common/buf"
 	"github.com/xtls/xray-core/common/buf"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/protocol"
 	"github.com/xtls/xray-core/common/protocol"
 	"github.com/xtls/xray-core/transport/pipe"
 	"github.com/xtls/xray-core/transport/pipe"
@@ -180,7 +182,7 @@ func (s *Session) Close(locked bool) error {
 		if s.XUDP.Status == Active {
 		if s.XUDP.Status == Active {
 			s.XUDP.Expire = time.Now().Add(time.Minute)
 			s.XUDP.Expire = time.Now().Add(time.Minute)
 			s.XUDP.Status = Expiring
 			s.XUDP.Status = Expiring
-			newError("XUDP put ", s.XUDP.GlobalID).AtDebug().WriteToLog()
+			errors.LogDebug(context.Background(), "XUDP put ", s.XUDP.GlobalID)
 		}
 		}
 		XUDPManager.Unlock()
 		XUDPManager.Unlock()
 	}
 	}
@@ -230,7 +232,7 @@ func init() {
 				if x.Status == Expiring && now.After(x.Expire) {
 				if x.Status == Expiring && now.After(x.Expire) {
 					x.Interrupt()
 					x.Interrupt()
 					delete(XUDPManager.Map, id)
 					delete(XUDPManager.Map, id)
-					newError("XUDP del ", id).AtDebug().WriteToLog()
+					errors.LogDebug(context.Background(), "XUDP del ", id)
 				}
 				}
 			}
 			}
 			XUDPManager.Unlock()
 			XUDPManager.Unlock()

+ 4 - 1
common/net/address.go

@@ -2,8 +2,11 @@ package net
 
 
 import (
 import (
 	"bytes"
 	"bytes"
+	"context"
 	"net"
 	"net"
 	"strings"
 	"strings"
+
+	"github.com/xtls/xray-core/common/errors"
 )
 )
 
 
 var (
 var (
@@ -112,7 +115,7 @@ func IPAddress(ip []byte) Address {
 		}
 		}
 		return addr
 		return addr
 	default:
 	default:
-		newError("invalid IP format: ", ip).AtError().WriteToLog()
+		errors.LogError(context.Background(), "invalid IP format: ", ip)
 		return nil
 		return nil
 	}
 	}
 }
 }

+ 0 - 9
common/net/errors.generated.go

@@ -1,9 +0,0 @@
-package net
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 4 - 2
common/net/port.go

@@ -3,6 +3,8 @@ package net
 import (
 import (
 	"encoding/binary"
 	"encoding/binary"
 	"strconv"
 	"strconv"
+
+	"github.com/xtls/xray-core/common/errors"
 )
 )
 
 
 // Port represents a network port in TCP and UDP protocol.
 // Port represents a network port in TCP and UDP protocol.
@@ -18,7 +20,7 @@ func PortFromBytes(port []byte) Port {
 // @error when the integer is not positive or larger then 65535
 // @error when the integer is not positive or larger then 65535
 func PortFromInt(val uint32) (Port, error) {
 func PortFromInt(val uint32) (Port, error) {
 	if val > 65535 {
 	if val > 65535 {
-		return Port(0), newError("invalid port range: ", val)
+		return Port(0), errors.New("invalid port range: ", val)
 	}
 	}
 	return Port(val), nil
 	return Port(val), nil
 }
 }
@@ -28,7 +30,7 @@ func PortFromInt(val uint32) (Port, error) {
 func PortFromString(s string) (Port, error) {
 func PortFromString(s string) (Port, error) {
 	val, err := strconv.ParseUint(s, 10, 32)
 	val, err := strconv.ParseUint(s, 10, 32)
 	if err != nil {
 	if err != nil {
-		return Port(0), newError("invalid port range: ", s)
+		return Port(0), errors.New("invalid port range: ", s)
 	}
 	}
 	return PortFromInt(uint32(val))
 	return PortFromInt(uint32(val))
 }
 }

+ 0 - 9
common/ocsp/errors.generated.go

@@ -1,9 +0,0 @@
-package ocsp
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 9 - 8
common/ocsp/ocsp.go

@@ -8,6 +8,7 @@ import (
 	"net/http"
 	"net/http"
 	"os"
 	"os"
 
 
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/platform/filesystem"
 	"github.com/xtls/xray-core/common/platform/filesystem"
 	"golang.org/x/crypto/ocsp"
 	"golang.org/x/crypto/ocsp"
 )
 )
@@ -63,26 +64,26 @@ func GetOCSPForCert(cert [][]byte) ([]byte, error) {
 	}
 	}
 	issuedCert := certificates[0]
 	issuedCert := certificates[0]
 	if len(issuedCert.OCSPServer) == 0 {
 	if len(issuedCert.OCSPServer) == 0 {
-		return nil, newError("no OCSP server specified in cert")
+		return nil, errors.New("no OCSP server specified in cert")
 	}
 	}
 	if len(certificates) == 1 {
 	if len(certificates) == 1 {
 		if len(issuedCert.IssuingCertificateURL) == 0 {
 		if len(issuedCert.IssuingCertificateURL) == 0 {
-			return nil, newError("no issuing certificate URL")
+			return nil, errors.New("no issuing certificate URL")
 		}
 		}
 		resp, errC := http.Get(issuedCert.IssuingCertificateURL[0])
 		resp, errC := http.Get(issuedCert.IssuingCertificateURL[0])
 		if errC != nil {
 		if errC != nil {
-			return nil, newError("no issuing certificate URL")
+			return nil, errors.New("no issuing certificate URL")
 		}
 		}
 		defer resp.Body.Close()
 		defer resp.Body.Close()
 
 
 		issuerBytes, errC := io.ReadAll(resp.Body)
 		issuerBytes, errC := io.ReadAll(resp.Body)
 		if errC != nil {
 		if errC != nil {
-			return nil, newError(errC)
+			return nil, errors.New(errC)
 		}
 		}
 
 
 		issuerCert, errC := x509.ParseCertificate(issuerBytes)
 		issuerCert, errC := x509.ParseCertificate(issuerBytes)
 		if errC != nil {
 		if errC != nil {
-			return nil, newError(errC)
+			return nil, errors.New(errC)
 		}
 		}
 
 
 		certificates = append(certificates, issuerCert)
 		certificates = append(certificates, issuerCert)
@@ -96,12 +97,12 @@ func GetOCSPForCert(cert [][]byte) ([]byte, error) {
 	reader := bytes.NewReader(ocspReq)
 	reader := bytes.NewReader(ocspReq)
 	req, err := http.Post(issuedCert.OCSPServer[0], "application/ocsp-request", reader)
 	req, err := http.Post(issuedCert.OCSPServer[0], "application/ocsp-request", reader)
 	if err != nil {
 	if err != nil {
-		return nil, newError(err)
+		return nil, errors.New(err)
 	}
 	}
 	defer req.Body.Close()
 	defer req.Body.Close()
 	ocspResBytes, err := io.ReadAll(req.Body)
 	ocspResBytes, err := io.ReadAll(req.Body)
 	if err != nil {
 	if err != nil {
-		return nil, newError(err)
+		return nil, errors.New(err)
 	}
 	}
 	return ocspResBytes, nil
 	return ocspResBytes, nil
 }
 }
@@ -128,7 +129,7 @@ func parsePEMBundle(bundle []byte) ([]*x509.Certificate, error) {
 	}
 	}
 
 
 	if len(certificates) == 0 {
 	if len(certificates) == 0 {
-		return nil, newError("no certificates were found while parsing the bundle")
+		return nil, errors.New("no certificates were found while parsing the bundle")
 	}
 	}
 
 
 	return certificates, nil
 	return certificates, nil

+ 6 - 4
common/platform/ctlcmd/ctlcmd.go

@@ -1,12 +1,14 @@
 package ctlcmd
 package ctlcmd
 
 
 import (
 import (
+	"context"
 	"io"
 	"io"
 	"os"
 	"os"
 	"os/exec"
 	"os/exec"
 	"strings"
 	"strings"
 
 
 	"github.com/xtls/xray-core/common/buf"
 	"github.com/xtls/xray-core/common/buf"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/platform"
 	"github.com/xtls/xray-core/common/platform"
 )
 )
 
 
@@ -15,7 +17,7 @@ import (
 func Run(args []string, input io.Reader) (buf.MultiBuffer, error) {
 func Run(args []string, input io.Reader) (buf.MultiBuffer, error) {
 	xctl := platform.GetToolLocation("xctl")
 	xctl := platform.GetToolLocation("xctl")
 	if _, err := os.Stat(xctl); err != nil {
 	if _, err := os.Stat(xctl); err != nil {
-		return nil, newError("xctl doesn't exist").Base(err)
+		return nil, errors.New("xctl doesn't exist").Base(err)
 	}
 	}
 
 
 	var errBuffer buf.MultiBufferContainer
 	var errBuffer buf.MultiBufferContainer
@@ -30,7 +32,7 @@ func Run(args []string, input io.Reader) (buf.MultiBuffer, error) {
 	}
 	}
 
 
 	if err := cmd.Start(); err != nil {
 	if err := cmd.Start(); err != nil {
-		return nil, newError("failed to start xctl").Base(err)
+		return nil, errors.New("failed to start xctl").Base(err)
 	}
 	}
 
 
 	if err := cmd.Wait(); err != nil {
 	if err := cmd.Wait(); err != nil {
@@ -38,12 +40,12 @@ func Run(args []string, input io.Reader) (buf.MultiBuffer, error) {
 		if errBuffer.Len() > 0 {
 		if errBuffer.Len() > 0 {
 			msg += ": \n" + strings.TrimSpace(errBuffer.MultiBuffer.String())
 			msg += ": \n" + strings.TrimSpace(errBuffer.MultiBuffer.String())
 		}
 		}
-		return nil, newError(msg).Base(err)
+		return nil, errors.New(msg).Base(err)
 	}
 	}
 
 
 	// log stderr, info message
 	// log stderr, info message
 	if !errBuffer.IsEmpty() {
 	if !errBuffer.IsEmpty() {
-		newError("<xctl message> \n", strings.TrimSpace(errBuffer.MultiBuffer.String())).AtInfo().WriteToLog()
+		errors.LogInfo(context.Background(), "<xctl message> \n", strings.TrimSpace(errBuffer.MultiBuffer.String()))
 	}
 	}
 
 
 	return outBuffer.MultiBuffer, nil
 	return outBuffer.MultiBuffer, nil

+ 0 - 9
common/platform/ctlcmd/errors.generated.go

@@ -1,9 +0,0 @@
-package ctlcmd
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 6 - 5
common/protocol/address.go

@@ -5,6 +5,7 @@ import (
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common/buf"
 	"github.com/xtls/xray-core/common/buf"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/common/serial"
 	"github.com/xtls/xray-core/common/serial"
 )
 )
@@ -181,12 +182,12 @@ func (p *addressParser) readAddress(b *buf.Buffer, reader io.Reader) (net.Addres
 	}
 	}
 
 
 	if addrType >= 16 {
 	if addrType >= 16 {
-		return nil, newError("unknown address type: ", addrType)
+		return nil, errors.New("unknown address type: ", addrType)
 	}
 	}
 
 
 	addrFamily := p.addrTypeMap[addrType]
 	addrFamily := p.addrTypeMap[addrType]
 	if addrFamily == net.AddressFamily(afInvalid) {
 	if addrFamily == net.AddressFamily(afInvalid) {
-		return nil, newError("unknown address type: ", addrType)
+		return nil, errors.New("unknown address type: ", addrType)
 	}
 	}
 
 
 	switch addrFamily {
 	switch addrFamily {
@@ -216,7 +217,7 @@ func (p *addressParser) readAddress(b *buf.Buffer, reader io.Reader) (net.Addres
 			}
 			}
 		}
 		}
 		if !isValidDomain(domain) {
 		if !isValidDomain(domain) {
-			return nil, newError("invalid domain name: ", domain)
+			return nil, errors.New("invalid domain name: ", domain)
 		}
 		}
 		return net.DomainAddress(domain), nil
 		return net.DomainAddress(domain), nil
 	default:
 	default:
@@ -227,7 +228,7 @@ func (p *addressParser) readAddress(b *buf.Buffer, reader io.Reader) (net.Addres
 func (p *addressParser) writeAddress(writer io.Writer, address net.Address) error {
 func (p *addressParser) writeAddress(writer io.Writer, address net.Address) error {
 	tb := p.addrByteMap[address.Family()]
 	tb := p.addrByteMap[address.Family()]
 	if tb == afInvalid {
 	if tb == afInvalid {
-		return newError("unknown address family", address.Family())
+		return errors.New("unknown address family", address.Family())
 	}
 	}
 
 
 	switch address.Family() {
 	switch address.Family() {
@@ -241,7 +242,7 @@ func (p *addressParser) writeAddress(writer io.Writer, address net.Address) erro
 	case net.AddressFamilyDomain:
 	case net.AddressFamilyDomain:
 		domain := address.Domain()
 		domain := address.Domain()
 		if isDomainTooLong(domain) {
 		if isDomainTooLong(domain) {
-			return newError("Super long domain is not supported: ", domain)
+			return errors.New("Super long domain is not supported: ", domain)
 		}
 		}
 
 
 		if _, err := writer.Write([]byte{tb, byte(len(domain))}); err != nil {
 		if _, err := writer.Write([]byte{tb, byte(len(domain))}); err != nil {

+ 0 - 9
common/protocol/dns/errors.generated.go

@@ -1,9 +0,0 @@
-package dns
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 2 - 1
common/protocol/dns/io.go

@@ -6,6 +6,7 @@ import (
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common/buf"
 	"github.com/xtls/xray-core/common/buf"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/serial"
 	"github.com/xtls/xray-core/common/serial"
 	"golang.org/x/net/dns/dnsmessage"
 	"golang.org/x/net/dns/dnsmessage"
 )
 )
@@ -96,7 +97,7 @@ func (r *TCPReader) ReadMessage() (*buf.Buffer, error) {
 		return nil, err
 		return nil, err
 	}
 	}
 	if size > buf.Size {
 	if size > buf.Size {
-		return nil, newError("message size too large: ", size)
+		return nil, errors.New("message size too large: ", size)
 	}
 	}
 	b := buf.New()
 	b := buf.New()
 	if _, err := b.ReadFullFrom(r.reader, int32(size)); err != nil {
 	if _, err := b.ReadFullFrom(r.reader, int32(size)); err != nil {

+ 0 - 9
common/protocol/errors.generated.go

@@ -1,9 +0,0 @@
-package protocol
-
-import "github.com/xtls/xray-core/common/errors"
-
-type errPathObjHolder struct{}
-
-func newError(values ...interface{}) *errors.Error {
-	return errors.New(values...).WithPathObj(errPathObjHolder{})
-}

+ 9 - 8
common/protocol/tls/cert/cert.go

@@ -13,6 +13,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 )
 )
 
 
 //go:generate go run github.com/xtls/xray-core/common/errors/errorgen
 //go:generate go run github.com/xtls/xray-core/common/errors/errorgen
@@ -27,11 +28,11 @@ type Certificate struct {
 func ParseCertificate(certPEM []byte, keyPEM []byte) (*Certificate, error) {
 func ParseCertificate(certPEM []byte, keyPEM []byte) (*Certificate, error) {
 	certBlock, _ := pem.Decode(certPEM)
 	certBlock, _ := pem.Decode(certPEM)
 	if certBlock == nil {
 	if certBlock == nil {
-		return nil, newError("failed to decode certificate")
+		return nil, errors.New("failed to decode certificate")
 	}
 	}
 	keyBlock, _ := pem.Decode(keyPEM)
 	keyBlock, _ := pem.Decode(keyPEM)
 	if keyBlock == nil {
 	if keyBlock == nil {
-		return nil, newError("failed to decode key")
+		return nil, errors.New("failed to decode key")
 	}
 	}
 	return &Certificate{
 	return &Certificate{
 		Certificate: certBlock.Bytes,
 		Certificate: certBlock.Bytes,
@@ -116,7 +117,7 @@ func Generate(parent *Certificate, opts ...Option) (*Certificate, error) {
 	// higher signing performance than RSA2048
 	// higher signing performance than RSA2048
 	selfKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
 	selfKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
 	if err != nil {
 	if err != nil {
-		return nil, newError("failed to generate self private key").Base(err)
+		return nil, errors.New("failed to generate self private key").Base(err)
 	}
 	}
 	parentKey = selfKey
 	parentKey = selfKey
 	if parent != nil {
 	if parent != nil {
@@ -128,7 +129,7 @@ func Generate(parent *Certificate, opts ...Option) (*Certificate, error) {
 			pKey, err = x509.ParsePKCS1PrivateKey(parent.PrivateKey)
 			pKey, err = x509.ParsePKCS1PrivateKey(parent.PrivateKey)
 		}
 		}
 		if err != nil {
 		if err != nil {
-			return nil, newError("failed to parse parent private key").Base(err)
+			return nil, errors.New("failed to parse parent private key").Base(err)
 		}
 		}
 		parentKey = pKey
 		parentKey = pKey
 	}
 	}
@@ -136,7 +137,7 @@ func Generate(parent *Certificate, opts ...Option) (*Certificate, error) {
 	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
 	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
 	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
 	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
 	if err != nil {
 	if err != nil {
-		return nil, newError("failed to generate serial number").Base(err)
+		return nil, errors.New("failed to generate serial number").Base(err)
 	}
 	}
 
 
 	template := &x509.Certificate{
 	template := &x509.Certificate{
@@ -156,19 +157,19 @@ func Generate(parent *Certificate, opts ...Option) (*Certificate, error) {
 	if parent != nil {
 	if parent != nil {
 		pCert, err := x509.ParseCertificate(parent.Certificate)
 		pCert, err := x509.ParseCertificate(parent.Certificate)
 		if err != nil {
 		if err != nil {
-			return nil, newError("failed to parse parent certificate").Base(err)
+			return nil, errors.New("failed to parse parent certificate").Base(err)
 		}
 		}
 		parentCert = pCert
 		parentCert = pCert
 	}
 	}
 
 
 	derBytes, err := x509.CreateCertificate(rand.Reader, template, parentCert, publicKey(selfKey), parentKey)
 	derBytes, err := x509.CreateCertificate(rand.Reader, template, parentCert, publicKey(selfKey), parentKey)
 	if err != nil {
 	if err != nil {
-		return nil, newError("failed to create certificate").Base(err)
+		return nil, errors.New("failed to create certificate").Base(err)
 	}
 	}
 
 
 	privateKey, err := x509.MarshalPKCS8PrivateKey(selfKey)
 	privateKey, err := x509.MarshalPKCS8PrivateKey(selfKey)
 	if err != nil {
 	if err != nil {
-		return nil, newError("Unable to marshal private key").Base(err)
+		return nil, errors.New("Unable to marshal private key").Base(err)
 	}
 	}
 
 
 	return &Certificate{
 	return &Certificate{

+ 2 - 1
common/protocol/tls/cert/cert_test.go

@@ -10,6 +10,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common"
+	"github.com/xtls/xray-core/common/errors"
 	"github.com/xtls/xray-core/common/task"
 	"github.com/xtls/xray-core/common/task"
 )
 )
 
 
@@ -41,7 +42,7 @@ func generate(domainNames []string, isCA bool, jsonOutput bool, fileOutput strin
 
 
 	cert, err := Generate(nil, opts...)
 	cert, err := Generate(nil, opts...)
 	if err != nil {
 	if err != nil {
-		return newError("failed to generate TLS certificate").Base(err)
+		return errors.New("failed to generate TLS certificate").Base(err)
 	}
 	}
 
 
 	if jsonOutput {
 	if jsonOutput {

部分文件因为文件数量过多而无法显示