From 85e779a38301230b0f98b8b82f7f92479671de41 Mon Sep 17 00:00:00 2001 From: Minoru Osuka Date: Fri, 5 Jul 2019 16:48:25 +0900 Subject: [PATCH] Add gRPC access logger --- cmd/blastd/dispatcher.go | 19 +++++++++- cmd/blastd/indexer.go | 19 +++++++++- cmd/blastd/main.go | 29 +++++++++++++++ cmd/blastd/manager.go | 19 +++++++++- dispatcher/server.go | 6 ++- indexer/server.go | 6 ++- indexer/server_test.go | 7 +++- logutils/grpc_logger.go | 80 ++++++++++++++++++++++++++++++++++++++++ manager/server.go | 6 ++- manager/server_test.go | 18 ++++++--- 10 files changed, 192 insertions(+), 17 deletions(-) create mode 100644 logutils/grpc_logger.go diff --git a/cmd/blastd/dispatcher.go b/cmd/blastd/dispatcher.go index 5b272c2..99e9133 100644 --- a/cmd/blastd/dispatcher.go +++ b/cmd/blastd/dispatcher.go @@ -32,6 +32,13 @@ func startDispatcher(c *cli.Context) error { logMaxAge := c.GlobalInt("log-max-age") logCompress := c.GlobalBool("log-compress") + grpcLogLevel := c.GlobalString("grpc-log-level") + grpcLogFilename := c.GlobalString("grpc-log-file") + grpcLogMaxSize := c.GlobalInt("grpc-log-max-size") + grpcLogMaxBackups := c.GlobalInt("grpc-log-max-backups") + grpcLogMaxAge := c.GlobalInt("grpc-log-max-age") + grpcLogCompress := c.GlobalBool("grpc-log-compress") + httpAccessLogFilename := c.GlobalString("http-access-log-file") httpAccessLogMaxSize := c.GlobalInt("http-access-log-max-size") httpAccessLogMaxBackups := c.GlobalInt("http-access-log-max-backups") @@ -53,6 +60,16 @@ func startDispatcher(c *cli.Context) error { logCompress, ) + // create logger + grpcLogger := logutils.NewGRPCLogger( + grpcLogLevel, + grpcLogFilename, + grpcLogMaxSize, + grpcLogMaxBackups, + grpcLogMaxAge, + grpcLogCompress, + ) + // create HTTP access logger httpAccessLogger := logutils.NewApacheCombinedLogger( httpAccessLogFilename, @@ -62,7 +79,7 @@ func startDispatcher(c *cli.Context) error { httpAccessLogCompress, ) - svr, err := dispatcher.NewServer(managerAddr, grpcAddr, httpAddr, logger, httpAccessLogger) + svr, err := dispatcher.NewServer(managerAddr, grpcAddr, httpAddr, logger, grpcLogger, httpAccessLogger) if err != nil { return err } diff --git a/cmd/blastd/indexer.go b/cmd/blastd/indexer.go index 8d2f7cb..b5732b6 100644 --- a/cmd/blastd/indexer.go +++ b/cmd/blastd/indexer.go @@ -35,6 +35,13 @@ func startIndexer(c *cli.Context) error { logMaxAge := c.GlobalInt("log-max-age") logCompress := c.GlobalBool("log-compress") + grpcLogLevel := c.GlobalString("grpc-log-level") + grpcLogFilename := c.GlobalString("grpc-log-file") + grpcLogMaxSize := c.GlobalInt("grpc-log-max-size") + grpcLogMaxBackups := c.GlobalInt("grpc-log-max-backups") + grpcLogMaxAge := c.GlobalInt("grpc-log-max-age") + grpcLogCompress := c.GlobalBool("grpc-log-compress") + httpAccessLogFilename := c.GlobalString("http-access-log-file") httpAccessLogMaxSize := c.GlobalInt("http-access-log-max-size") httpAccessLogMaxBackups := c.GlobalInt("http-access-log-max-backups") @@ -66,6 +73,16 @@ func startIndexer(c *cli.Context) error { logCompress, ) + // create logger + grpcLogger := logutils.NewGRPCLogger( + grpcLogLevel, + grpcLogFilename, + grpcLogMaxSize, + grpcLogMaxBackups, + grpcLogMaxAge, + grpcLogCompress, + ) + // create HTTP access logger httpAccessLogger := logutils.NewApacheCombinedLogger( httpAccessLogFilename, @@ -133,7 +150,7 @@ func startIndexer(c *cli.Context) error { "index_storage_type": indexStorageType, } - svr, err := indexer.NewServer(managerAddr, clusterId, nodeId, metadata, raftStorageType, peerAddr, indexConfig, logger.Named(nodeId), httpAccessLogger) + svr, err := indexer.NewServer(managerAddr, clusterId, nodeId, metadata, raftStorageType, peerAddr, indexConfig, logger.Named(nodeId), grpcLogger.Named(nodeId), httpAccessLogger) if err != nil { return err } diff --git a/cmd/blastd/main.go b/cmd/blastd/main.go index 27788f1..bb869fb 100644 --- a/cmd/blastd/main.go +++ b/cmd/blastd/main.go @@ -59,6 +59,35 @@ func main() { Name: "log-compress", Usage: "Compress a log file", }, + cli.StringFlag{ + Name: "grpc-log-level", + Value: "INFO", + Usage: "gRPC log level", + }, + cli.StringFlag{ + Name: "grpc-log-file", + Value: os.Stderr.Name(), + Usage: "gRPC log file", + }, + cli.IntFlag{ + Name: "grpc-log-max-size", + Value: 500, + Usage: "Max size of a log file (megabytes)", + }, + cli.IntFlag{ + Name: "grpc-log-max-backups", + Value: 3, + Usage: "Max backup count of log files", + }, + cli.IntFlag{ + Name: "grpc-log-max-age", + Value: 30, + Usage: "Max age of a log file (days)", + }, + cli.BoolFlag{ + Name: "grpc-log-compress", + Usage: "Compress a log file", + }, cli.StringFlag{ Name: "http-access-log-file", Value: os.Stderr.Name(), diff --git a/cmd/blastd/manager.go b/cmd/blastd/manager.go index 6e48b27..22c2041 100644 --- a/cmd/blastd/manager.go +++ b/cmd/blastd/manager.go @@ -35,6 +35,13 @@ func startManager(c *cli.Context) error { logMaxAge := c.GlobalInt("log-max-age") logCompress := c.GlobalBool("log-compress") + grpcLogLevel := c.GlobalString("grpc-log-level") + grpcLogFilename := c.GlobalString("grpc-log-file") + grpcLogMaxSize := c.GlobalInt("grpc-log-max-size") + grpcLogMaxBackups := c.GlobalInt("grpc-log-max-backups") + grpcLogMaxAge := c.GlobalInt("grpc-log-max-age") + grpcLogCompress := c.GlobalBool("grpc-log-compress") + httpAccessLogFilename := c.GlobalString("http-access-log-file") httpAccessLogMaxSize := c.GlobalInt("http-access-log-max-size") httpAccessLogMaxBackups := c.GlobalInt("http-access-log-max-backups") @@ -63,6 +70,16 @@ func startManager(c *cli.Context) error { logCompress, ) + // create logger + grpcLogger := logutils.NewGRPCLogger( + grpcLogLevel, + grpcLogFilename, + grpcLogMaxSize, + grpcLogMaxBackups, + grpcLogMaxAge, + grpcLogCompress, + ) + // create HTTP access logger httpAccessLogger := logutils.NewApacheCombinedLogger( httpAccessLogFilename, @@ -130,7 +147,7 @@ func startManager(c *cli.Context) error { "index_storage_type": indexStorageType, } - svr, err := manager.NewServer(nodeId, metadata, raftStorageType, peerAddr, indexConfig, logger.Named(nodeId), httpAccessLogger) + svr, err := manager.NewServer(nodeId, metadata, raftStorageType, peerAddr, indexConfig, logger.Named(nodeId), grpcLogger.Named(nodeId), httpAccessLogger) if err != nil { return err } diff --git a/dispatcher/server.go b/dispatcher/server.go index e1a7e19..3f01b32 100644 --- a/dispatcher/server.go +++ b/dispatcher/server.go @@ -34,10 +34,11 @@ type Server struct { httpServer *http.Server logger *zap.Logger + grpcLogger *zap.Logger httpLogger accesslog.Logger } -func NewServer(managerAddr string, grpcAddr string, httpAddr string, logger *zap.Logger, httpLogger accesslog.Logger) (*Server, error) { +func NewServer(managerAddr string, grpcAddr string, httpAddr string, logger *zap.Logger, grpcLogger *zap.Logger, httpLogger accesslog.Logger) (*Server, error) { return &Server{ managerAddr: managerAddr, @@ -45,6 +46,7 @@ func NewServer(managerAddr string, grpcAddr string, httpAddr string, logger *zap httpAddr: httpAddr, logger: logger, + grpcLogger: grpcLogger, httpLogger: httpLogger, }, nil } @@ -60,7 +62,7 @@ func (s *Server) Start() { } // create gRPC server - s.grpcServer, err = grpc.NewServer(s.grpcAddr, s.grpcService, s.logger) + s.grpcServer, err = grpc.NewServer(s.grpcAddr, s.grpcService, s.grpcLogger) if err != nil { s.logger.Fatal(err.Error()) return diff --git a/indexer/server.go b/indexer/server.go index 9f6fc65..1a79359 100644 --- a/indexer/server.go +++ b/indexer/server.go @@ -42,10 +42,11 @@ type Server struct { httpServer *http.Server logger *zap.Logger + grpcLogger *zap.Logger httpLogger accesslog.Logger } -func NewServer(managerAddr string, clusterId string, id string, metadata map[string]interface{}, raftStorageType, peerAddr string, indexConfig map[string]interface{}, logger *zap.Logger, httpLogger accesslog.Logger) (*Server, error) { +func NewServer(managerAddr string, clusterId string, id string, metadata map[string]interface{}, raftStorageType, peerAddr string, indexConfig map[string]interface{}, logger *zap.Logger, grpcLogger *zap.Logger, httpLogger accesslog.Logger) (*Server, error) { return &Server{ managerAddr: managerAddr, clusterId: clusterId, @@ -58,6 +59,7 @@ func NewServer(managerAddr string, clusterId string, id string, metadata map[str indexConfig: indexConfig, logger: logger, + grpcLogger: grpcLogger, httpLogger: httpLogger, }, nil } @@ -193,7 +195,7 @@ func (s *Server) Start() { } // create gRPC server - s.grpcServer, err = grpc.NewServer(grpcAddr, s.grpcService, s.logger) + s.grpcServer, err = grpc.NewServer(grpcAddr, s.grpcService, s.grpcLogger) if err != nil { s.logger.Fatal(err.Error()) return diff --git a/indexer/server_test.go b/indexer/server_test.go index 38fb242..a7de09d 100644 --- a/indexer/server_test.go +++ b/indexer/server_test.go @@ -87,7 +87,10 @@ func TestIndexserStandalone(t *testing.T) { } // create logger - logger := logutils.NewLogger("WARN", "", 500, 3, 30, false) + logger := logutils.NewLogger("DEBUG", "", 500, 3, 30, false) + + // create logger + grpcLogger := logutils.NewLogger("WARN", "", 500, 3, 30, false) // create HTTP access logger httpAccessLogger := logutils.NewApacheCombinedLogger("", 500, 3, 30, false) @@ -133,7 +136,7 @@ func TestIndexserStandalone(t *testing.T) { "data_dir": dataDir, } - server, err := NewServer("", "", nodeId, metadata, "boltdb", peerAddr, indexConfig, logger, httpAccessLogger) + server, err := NewServer("", "", nodeId, metadata, "boltdb", peerAddr, indexConfig, logger, grpcLogger, httpAccessLogger) defer func() { server.Stop() }() diff --git a/logutils/grpc_logger.go b/logutils/grpc_logger.go new file mode 100644 index 0000000..85d6fa9 --- /dev/null +++ b/logutils/grpc_logger.go @@ -0,0 +1,80 @@ +// Copyright (c) 2019 Minoru Osuka +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package logutils + +import ( + "os" + + "github.com/natefinch/lumberjack" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +func NewGRPCLogger(logLevel string, logFilename string, logMaxSize int, logMaxBackups int, logMaxAge int, logCompress bool) *zap.Logger { + var ll zapcore.Level + switch logLevel { + case "DEBUG": + ll = zap.DebugLevel + case "INFO": + ll = zap.InfoLevel + case "WARN", "WARNING": + ll = zap.WarnLevel + case "ERR", "ERROR": + ll = zap.WarnLevel + case "DPANIC": + ll = zap.DPanicLevel + case "PANIC": + ll = zap.PanicLevel + case "FATAL": + ll = zap.FatalLevel + } + + var ws zapcore.WriteSyncer + if logFilename == "" { + ws = zapcore.AddSync(os.Stderr) + } else { + ws = zapcore.AddSync( + &lumberjack.Logger{ + Filename: logFilename, + MaxSize: logMaxSize, // megabytes + MaxBackups: logMaxBackups, + MaxAge: logMaxAge, // days + Compress: logCompress, + }, + ) + } + + ec := zap.NewProductionEncoderConfig() + ec.TimeKey = "_timestamp_" + ec.LevelKey = "_level_" + ec.NameKey = "_name_" + ec.CallerKey = "_caller_" + ec.MessageKey = "_message_" + ec.StacktraceKey = "_stacktrace_" + ec.EncodeTime = zapcore.ISO8601TimeEncoder + ec.EncodeCaller = zapcore.ShortCallerEncoder + + logger := zap.New( + zapcore.NewCore( + zapcore.NewJSONEncoder(ec), + ws, + ll, + ), + //zap.AddCaller(), + //zap.AddStacktrace(ll), + ) + + return logger +} diff --git a/manager/server.go b/manager/server.go index 76ca672..03d423d 100644 --- a/manager/server.go +++ b/manager/server.go @@ -36,10 +36,11 @@ type Server struct { httpServer *http.Server logger *zap.Logger + grpcLogger *zap.Logger httpLogger accesslog.Logger } -func NewServer(id string, metadata map[string]interface{}, raftStorageType string, peerAddr string, indexConfig map[string]interface{}, logger *zap.Logger, httpLogger accesslog.Logger) (*Server, error) { +func NewServer(id string, metadata map[string]interface{}, raftStorageType string, peerAddr string, indexConfig map[string]interface{}, logger *zap.Logger, grpcLogger *zap.Logger, httpLogger accesslog.Logger) (*Server, error) { return &Server{ id: id, metadata: metadata, @@ -47,6 +48,7 @@ func NewServer(id string, metadata map[string]interface{}, raftStorageType strin peerAddr: peerAddr, indexConfig: indexConfig, logger: logger, + grpcLogger: grpcLogger, httpLogger: httpLogger, }, nil } @@ -73,7 +75,7 @@ func (s *Server) Start() { } // create gRPC server - s.grpcServer, err = grpc.NewServer(s.metadata["grpc_addr"].(string), s.grpcService, s.logger) + s.grpcServer, err = grpc.NewServer(s.metadata["grpc_addr"].(string), s.grpcService, s.grpcLogger) if err != nil { s.logger.Fatal(err.Error()) return diff --git a/manager/server_test.go b/manager/server_test.go index 4abe102..99480c0 100644 --- a/manager/server_test.go +++ b/manager/server_test.go @@ -87,7 +87,10 @@ func TestManagerStandalone(t *testing.T) { } // create logger - logger := logutils.NewLogger("WARN", "", 500, 3, 30, false) + logger := logutils.NewLogger("DEBUG", "", 500, 3, 30, false) + + // create gRPC logger + grpcLogger := logutils.NewLogger("WARN", "", 500, 3, 30, false) // create HTTP access logger httpAccessLogger := logutils.NewApacheCombinedLogger("", 500, 3, 30, false) @@ -135,7 +138,7 @@ func TestManagerStandalone(t *testing.T) { "data_dir": dataDir, } - server, err := NewServer(nodeId, metadata, "boltdb", peerAddr, indexConfig, logger.Named(nodeId), httpAccessLogger) + server, err := NewServer(nodeId, metadata, "boltdb", peerAddr, indexConfig, logger.Named(nodeId), grpcLogger.Named(nodeId), httpAccessLogger) defer func() { server.Stop() }() @@ -341,7 +344,10 @@ func TestManagerCluster(t *testing.T) { } // create logger - logger := logutils.NewLogger("WARN", "", 500, 3, 30, false) + logger := logutils.NewLogger("DEBUG", "", 500, 3, 30, false) + + // create logger + grpcLogger := logutils.NewLogger("WARN", "", 500, 3, 30, false) // create HTTP access logger httpAccessLogger := logutils.NewApacheCombinedLogger("", 500, 3, 30, false) @@ -380,7 +386,7 @@ func TestManagerCluster(t *testing.T) { "http_addr": manager1HttpAddr, "data_dir": manager1DataDir, } - manager1, err := NewServer(manager1NodeId, manager1Metadata, "boltdb", manager1PeerAddr, indexConfig, logger.Named(manager1NodeId), httpAccessLogger) + manager1, err := NewServer(manager1NodeId, manager1Metadata, "boltdb", manager1PeerAddr, indexConfig, logger.Named(manager1NodeId), grpcLogger.Named(manager1NodeId), httpAccessLogger) defer func() { manager1.Stop() }() @@ -422,7 +428,7 @@ func TestManagerCluster(t *testing.T) { "http_addr": manager2HttpAddr, "data_dir": manager2DataDir, } - manager2, err := NewServer(manager2NodeId, manager2Metadata, "boltdb", manager2PeerAddr, nil, logger.Named(manager2NodeId), httpAccessLogger) + manager2, err := NewServer(manager2NodeId, manager2Metadata, "boltdb", manager2PeerAddr, nil, logger.Named(manager2NodeId), grpcLogger.Named(manager1NodeId), httpAccessLogger) defer func() { manager2.Stop() }() @@ -464,7 +470,7 @@ func TestManagerCluster(t *testing.T) { "http_addr": manager3HttpAddr, "data_dir": manager3DataDir, } - manager3, err := NewServer(manager3NodeId, manager3Metadata, "boltdb", manager3PeerAddr, nil, logger.Named(manager3NodeId), httpAccessLogger) + manager3, err := NewServer(manager3NodeId, manager3Metadata, "boltdb", manager3PeerAddr, nil, logger.Named(manager3NodeId), grpcLogger.Named(manager1NodeId), httpAccessLogger) defer func() { manager3.Stop() }()