From eee1caacbf42cebc70d5b7fc150e1244b375a851 Mon Sep 17 00:00:00 2001 From: kercylan98 Date: Sat, 22 Apr 2023 14:23:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=9A=E7=BD=91=E7=BB=9C=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E5=99=A8=E5=90=AF=E5=8A=A8=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 11 +++-- go.sum | 14 ++++++ main.go | 11 ++++- server/event.go | 9 +++- server/{gserver.go => gnet.go} | 18 ++++---- server/multiple.go | 68 ++++++++++++++++++++++++++++ server/network.go | 1 + server/server.go | 81 ++++++++++++++++++++++------------ 8 files changed, 168 insertions(+), 45 deletions(-) rename server/{gserver.go => gnet.go} (58%) create mode 100644 server/multiple.go diff --git a/go.mod b/go.mod index 82d039f..c853ad5 100644 --- a/go.mod +++ b/go.mod @@ -30,6 +30,7 @@ require ( github.com/goccy/go-json v0.10.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/mock v1.6.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect github.com/google/pprof v0.0.0-20221203041831-ce31453925ec // indirect github.com/jonboulle/clockwork v0.3.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -63,11 +64,13 @@ require ( golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect golang.org/x/crypto v0.5.0 // indirect golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect - golang.org/x/mod v0.7.0 // indirect - golang.org/x/net v0.7.0 // indirect + golang.org/x/mod v0.8.0 // indirect + golang.org/x/net v0.8.0 // indirect golang.org/x/sys v0.7.0 // indirect - golang.org/x/text v0.7.0 // indirect - golang.org/x/tools v0.4.0 // indirect + golang.org/x/text v0.8.0 // indirect + golang.org/x/tools v0.6.0 // indirect + google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect + google.golang.org/grpc v1.54.0 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 3af84d9..5a2cfcd 100644 --- a/go.sum +++ b/go.sum @@ -75,6 +75,8 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -235,6 +237,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -250,6 +254,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -284,6 +290,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -298,6 +306,7 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.4.0 h1:7mTAgkunk3fr4GAloyyCasadO6h9zSsQZbwvcaIciV4= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= @@ -307,10 +316,14 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -318,6 +331,7 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= diff --git a/main.go b/main.go index caca767..2b360e0 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,13 @@ import ( ) func main() { - s := server.New(server.NetworkKcp) - s.Run(":9999") + ms := server.NewMultipleServer( + func() (addr string, srv *server.Server) { + return ":9999", server.New(server.NetworkTCP) + }, + func() (addr string, srv *server.Server) { + return ":19999", server.New(server.NetworkGRPC) + }, + ) + ms.Run() } diff --git a/server/event.go b/server/event.go index 3b70bb7..a4a04ed 100644 --- a/server/event.go +++ b/server/event.go @@ -64,7 +64,12 @@ func (slf *event) OnConnectionReceivePacketEvent(conn *Conn, packet []byte) { } func (slf *event) check() { - if slf.network != NetworkHttp && len(slf.connectionReceivePacketEventHandles) == 0 { - log.Warn("Server", zap.String("ConnectionReceivePacketEvent", "Invalid server, no packets processed")) + switch slf.network { + case NetworkHttp, NetworkGRPC: + default: + if len(slf.connectionReceivePacketEventHandles) == 0 { + log.Warn("Server", zap.String("ConnectionReceivePacketEvent", "Invalid server, no packets processed")) + } } + } diff --git a/server/gserver.go b/server/gnet.go similarity index 58% rename from server/gserver.go rename to server/gnet.go index 2e2e15d..7d926a0 100644 --- a/server/gserver.go +++ b/server/gnet.go @@ -6,17 +6,17 @@ import ( "time" ) -type gServer struct { +type gNet struct { *Server connections *synchronization.Map[string, *Conn] } -func (slf *gServer) OnInitComplete(server gnet.Server) (action gnet.Action) { +func (slf *gNet) OnInitComplete(server gnet.Server) (action gnet.Action) { slf.connections = synchronization.NewMap[string, *Conn]() return } -func (slf *gServer) OnShutdown(server gnet.Server) { +func (slf *gNet) OnShutdown(server gnet.Server) { for k := range slf.connections.Map() { slf.connections.Delete(k) } @@ -24,27 +24,27 @@ func (slf *gServer) OnShutdown(server gnet.Server) { return } -func (slf *gServer) OnOpened(c gnet.Conn) (out []byte, action gnet.Action) { +func (slf *gNet) OnOpened(c gnet.Conn) (out []byte, action gnet.Action) { conn := newGNetConn(c) slf.connections.Set(c.RemoteAddr().String(), conn) slf.OnConnectionOpenedEvent(conn) return } -func (slf *gServer) OnClosed(c gnet.Conn, err error) (action gnet.Action) { +func (slf *gNet) OnClosed(c gnet.Conn, err error) (action gnet.Action) { slf.OnConnectionClosedEvent(slf.connections.DeleteGet(c.RemoteAddr().String())) return } -func (slf *gServer) PreWrite(c gnet.Conn) { +func (slf *gNet) PreWrite(c gnet.Conn) { return } -func (slf *gServer) AfterWrite(c gnet.Conn, b []byte) { +func (slf *gNet) AfterWrite(c gnet.Conn, b []byte) { return } -func (slf *gServer) React(packet []byte, c gnet.Conn) (out []byte, action gnet.Action) { +func (slf *gNet) React(packet []byte, c gnet.Conn) (out []byte, action gnet.Action) { if conn, exist := slf.connections.GetExist(c.RemoteAddr().String()); exist { slf.Server.PushMessage(MessageTypePacket, conn, packet) return nil, gnet.None @@ -53,6 +53,6 @@ func (slf *gServer) React(packet []byte, c gnet.Conn) (out []byte, action gnet.A } } -func (slf *gServer) Tick() (delay time.Duration, action gnet.Action) { +func (slf *gNet) Tick() (delay time.Duration, action gnet.Action) { return } diff --git a/server/multiple.go b/server/multiple.go new file mode 100644 index 0000000..debaefc --- /dev/null +++ b/server/multiple.go @@ -0,0 +1,68 @@ +package server + +import ( + "go.uber.org/zap" + "minotaur/utils/log" + "os" + "os/signal" + "syscall" + "time" +) + +func NewMultipleServer(serverHandle ...func() (addr string, srv *Server)) *MultipleServer { + ms := &MultipleServer{ + servers: make([]*Server, len(serverHandle), len(serverHandle)), + addresses: make([]string, len(serverHandle), len(serverHandle)), + } + for i := 0; i < len(serverHandle); i++ { + ms.addresses[i], ms.servers[i] = serverHandle[i]() + } + return ms +} + +type MultipleServer struct { + servers []*Server + addresses []string +} + +func (slf *MultipleServer) Run() { + var exceptionChannel = make(chan error, 1) + defer close(exceptionChannel) + var running = make([]*Server, 0, len(slf.servers)) + for i := 0; i < len(slf.servers); i++ { + go func(address string, server *Server) { + server.multiple = true + if err := server.Run(address); err != nil { + exceptionChannel <- err + } else { + running = append(running, server) + } + }(slf.addresses[i], slf.servers[i]) + } + + time.Sleep(time.Second) + + log.Info("Server", zap.String("Minotaur Multiple Server", "====================================================================")) + for _, server := range slf.servers { + log.Info("Server", zap.String("Minotaur Multiple Server", "RunningInfo"), + zap.Any("network", server.network), + zap.String("listen", server.addr), + ) + } + log.Info("Server", zap.String("Minotaur Multiple Server", "====================================================================")) + + systemSignal := make(chan os.Signal, 1) + signal.Notify(systemSignal, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT) + select { + case err := <-exceptionChannel: + for _, server := range slf.servers { + server.Shutdown(err) + } + return + case <-systemSignal: + for _, server := range slf.servers { + server.Shutdown(nil) + } + return + } +} diff --git a/server/network.go b/server/network.go index a390183..c0dffe1 100644 --- a/server/network.go +++ b/server/network.go @@ -13,4 +13,5 @@ const ( NetworkHttp Network = "http" NetworkWebsocket Network = "websocket" NetworkKcp Network = "kcp" + NetworkGRPC Network = "grpc" ) diff --git a/server/server.go b/server/server.go index 4cb6d60..c673533 100644 --- a/server/server.go +++ b/server/server.go @@ -7,7 +7,9 @@ import ( "github.com/panjf2000/gnet" "github.com/xtaci/kcp-go/v5" "go.uber.org/zap" + "google.golang.org/grpc" "minotaur/utils/log" + "net" "net/http" "os" "os/signal" @@ -32,11 +34,14 @@ func New(network Network) *Server { // Server 网络服务器 type Server struct { *event - network Network - addr string - httpServer *gin.Engine - gServer *gServer - messageChannel chan *message + network Network + addr string + httpServer *gin.Engine + grpcServer *grpc.Server + gServer *gNet + messageChannel chan *message + initMessageChannel bool + multiple bool } // Run 使用特定地址运行服务器 @@ -58,10 +63,14 @@ func (slf *Server) Run(addr string) error { slf.event.check() slf.addr = addr var protoAddr = fmt.Sprintf("%s://%s", slf.network, slf.addr) - var connectionInitHandle = func() { + var connectionInitHandle = func(callback func()) { + slf.initMessageChannel = true slf.messageChannel = make(chan *message, 4096*1000) if slf.network != NetworkHttp && slf.network != NetworkWebsocket { - slf.gServer = &gServer{Server: slf} + slf.gServer = &gNet{Server: slf} + } + if callback != nil { + go callback() } for message := range slf.messageChannel { slf.dispatchMessage(message) @@ -69,20 +78,29 @@ func (slf *Server) Run(addr string) error { } switch slf.network { - case NetworkTCP, NetworkTCP4, NetworkTCP6, NetworkUdp, NetworkUdp4, NetworkUdp6, NetworkUnix: - go connectionInitHandle() + case NetworkGRPC: + listener, err := net.Listen(string(NetworkTCP), slf.addr) + if err != nil { + return err + } + slf.grpcServer = grpc.NewServer() go func() { - if err := gnet.Serve(slf.gServer, protoAddr); err != nil { + if err := slf.grpcServer.Serve(listener); err != nil { slf.PushMessage(MessageTypeError, err, MessageErrorActionShutdown) } }() + case NetworkTCP, NetworkTCP4, NetworkTCP6, NetworkUdp, NetworkUdp4, NetworkUdp6, NetworkUnix: + go connectionInitHandle(func() { + if err := gnet.Serve(slf.gServer, protoAddr); err != nil { + slf.PushMessage(MessageTypeError, err, MessageErrorActionShutdown) + } + }) case NetworkKcp: listener, err := kcp.ListenWithOptions(slf.addr, nil, 0, 0) if err != nil { return err } - go connectionInitHandle() - go func() { + go connectionInitHandle(func() { for { session, err := listener.AcceptKCP() if err != nil { @@ -110,7 +128,7 @@ func (slf *Server) Run(addr string) error { } }(conn) } - }() + }) case NetworkHttp: go func() { if err := slf.httpServer.Run(addr); err != nil { @@ -118,7 +136,7 @@ func (slf *Server) Run(addr string) error { } }() case NetworkWebsocket: - go connectionInitHandle() + go connectionInitHandle(nil) var pattern string var index = strings.Index(addr, "/") if index == -1 { @@ -178,29 +196,36 @@ func (slf *Server) Run(addr string) error { return ErrCanNotSupportNetwork } - log.Info("Server", zap.String("Minotaur Server", "====================================================================")) - log.Info("Server", zap.String("Minotaur Server", "RunningInfo"), - zap.Any("network", slf.network), - zap.String("listen", slf.addr), - ) - log.Info("Server", zap.String("Minotaur Server", "====================================================================")) + if !slf.multiple { + log.Info("Server", zap.String("Minotaur Server", "====================================================================")) + log.Info("Server", zap.String("Minotaur Server", "RunningInfo"), + zap.Any("network", slf.network), + zap.String("listen", slf.addr), + ) + log.Info("Server", zap.String("Minotaur Server", "====================================================================")) - systemSignal := make(chan os.Signal, 1) - signal.Notify(systemSignal, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT) - select { - case <-systemSignal: - slf.Shutdown(nil) + systemSignal := make(chan os.Signal, 1) + signal.Notify(systemSignal, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT) + select { + case <-systemSignal: + slf.Shutdown(nil) + } } + return nil } // Shutdown 停止运行服务器 func (slf *Server) Shutdown(err error) { - close(slf.messageChannel) + if slf.initMessageChannel { + close(slf.messageChannel) + } if err != nil { - log.Error("Server", zap.String("action", "shutdown"), zap.String("state", "exception"), zap.Error(err)) + log.Error("Server", zap.Any("network", slf.network), zap.String("listen", slf.addr), + zap.String("action", "shutdown"), zap.String("state", "exception"), zap.Error(err)) } else { - log.Info("Server", zap.String("action", "shutdown"), zap.String("state", "normal")) + log.Info("Server", zap.Any("network", slf.network), zap.String("listen", slf.addr), + zap.String("action", "shutdown"), zap.String("state", "normal")) } }