diff --git a/go.mod b/go.mod index 2b9a1b1..ef8d908 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 github.com/lib/pq v1.10.9 github.com/o1egl/paseto v1.0.0 + github.com/rs/zerolog v1.32.0 github.com/spf13/viper v1.18.2 github.com/stretchr/testify v1.8.4 golang.org/x/crypto v0.18.0 @@ -46,6 +47,7 @@ require ( github.com/klauspost/cpuid/v2 v2.2.6 // indirect github.com/leodido/go-urn v1.3.0 // indirect github.com/magiconair/properties v1.8.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -68,7 +70,7 @@ require ( golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect golang.org/x/net v0.20.0 // indirect golang.org/x/oauth2 v0.16.0 // indirect - golang.org/x/sys v0.16.0 // indirect + golang.org/x/sys v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac // indirect diff --git a/go.sum b/go.sum index 26ebd52..637efbb 100644 --- a/go.sum +++ b/go.sum @@ -20,6 +20,7 @@ github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpV github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0= github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -54,6 +55,7 @@ github.com/go-playground/validator/v10 v10.17.0 h1:SmVVlfAOtlZncTxRuinDPomC2DkXJ github.com/go-playground/validator/v10 v10.17.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= @@ -105,6 +107,10 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -134,6 +140,9 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= +github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= @@ -210,10 +219,12 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/internal/app/app.go b/internal/app/app.go index 26e151a..05cc14e 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -10,19 +10,19 @@ import ( _ "github.com/golang-migrate/migrate/v4/source/file" _ "github.com/golang-migrate/migrate/v4/source/github" _ "github.com/lib/pq" - "log" + "github.com/rs/zerolog/log" ) // Run will run simple bank app func Run(config utils.Config) { conn, err := sql.Open(config.DBDriver, config.DBSource) if err != nil { - log.Fatal("The open connection to database process was encountered an error", err) + log.Fatal().Err(err).Msg("The open connection to database process was encountered an error") } driver, err := postgres.WithInstance(conn, &postgres.Config{}) if err != nil { - log.Fatal("Error when create postgres driver instance: ", err) + log.Fatal().Err(err).Msg("Error when create postgres driver instance: ") } RunDBMigration(config.MigrationURL, config.PostgresDB, driver) diff --git a/internal/app/migration.go b/internal/app/migration.go index ff5fda9..1d39dab 100644 --- a/internal/app/migration.go +++ b/internal/app/migration.go @@ -3,18 +3,18 @@ package app import ( "github.com/golang-migrate/migrate/v4" "github.com/golang-migrate/migrate/v4/database" - "log" + "github.com/rs/zerolog/log" ) func RunDBMigration(sourceURL string, databaseName string, databaseInstance database.Driver) { migration, err := migrate.NewWithDatabaseInstance(sourceURL, databaseName, databaseInstance) if err != nil { - log.Fatal("fail to create migration instance: ", err) + log.Fatal().Err(err).Msg("fail to create migration instance: ") } if err = migration.Up(); err != nil && err.Error() != "no change" { - log.Fatal("fail to run migrate up: ", err) + log.Fatal().Err(err).Msg("fail to run migrate up: ") } - log.Println("migration is successfully") + log.Info().Msg("migration is successfully") } diff --git a/internal/delivery/grpc/gapi/logger.go b/internal/delivery/grpc/gapi/logger.go new file mode 100644 index 0000000..bf50463 --- /dev/null +++ b/internal/delivery/grpc/gapi/logger.go @@ -0,0 +1,35 @@ +package gapi + +import ( + "context" + "github.com/rs/zerolog/log" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "time" +) + +func GrpcLogger(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) { + startTime := time.Now() + result, err := handler(ctx, req) + duration := time.Since(startTime) + + statusCode := codes.Unknown + if st, ok := status.FromError(err); ok { + statusCode = st.Code() + } + + logger := log.Info() + if err != nil { + logger = log.Error() + } + + logger. + Str("protocol", "grpc"). + Str("method", info.FullMethod). + Int("status_code", int(statusCode)). + Str("status_text", statusCode.String()). + Dur("duration", duration). + Msg("sending protocol") + return result, err +} diff --git a/pkg/grpc/server.go b/pkg/grpc/server.go index d5a9eaf..35714b8 100644 --- a/pkg/grpc/server.go +++ b/pkg/grpc/server.go @@ -8,10 +8,10 @@ import ( token2 "github.com/cukhoaimon/SimpleBank/pkg/token" "github.com/cukhoaimon/SimpleBank/utils" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/rs/zerolog/log" "google.golang.org/grpc" "google.golang.org/grpc/reflection" "google.golang.org/protobuf/encoding/protojson" - "log" "net" "net/http" ) @@ -41,22 +41,23 @@ func NewServer(store db.Store, config utils.Config) (*Server, error) { func Run(store db.Store, config utils.Config) { server, err := NewServer(store, config) if err != nil { - log.Fatalf("Cannot create gRPC server: %s", err) + log.Fatal().Err(err).Msg("Cannot create gRPC server: ") } - gRPCServer := grpc.NewServer() + grpcLogger := grpc.UnaryInterceptor(gapi.GrpcLogger) + gRPCServer := grpc.NewServer(grpcLogger) pb.RegisterSimpleBankServer(gRPCServer, server.Handler) // allow client to know what RPCs currently available in server reflection.Register(gRPCServer) listener, err := net.Listen("tcp", config.GrpcServerAddress) if err != nil { - log.Fatalf("Cannot create tcp-listener for gRPC server: %s", err) + log.Fatal().Err(err).Msg("Cannot create tcp-listener for gRPC server: ") } log.Printf("start gRPC server at: %s", listener.Addr().String()) if err = gRPCServer.Serve(listener); err != nil { - log.Fatalf("Cannot serve gRPC server: %s", err) + log.Fatal().Err(err).Msg("Cannot serve gRPC server: ") } } @@ -65,7 +66,7 @@ func Run(store db.Store, config utils.Config) { func RunGatewayServer(store db.Store, config utils.Config) { server, err := NewServer(store, config) if err != nil { - log.Fatalf("Cannot create gRPC server: %s", err) + log.Fatal().Err(err).Msg("Cannot create gRPC server: ") } jsonOpts := runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{ @@ -83,7 +84,7 @@ func RunGatewayServer(store db.Store, config utils.Config) { defer cancel() if err = pb.RegisterSimpleBankHandlerServer(ctx, grpcMux, server.Handler); err != nil { - log.Fatalf("Cannot register handler server: %s", err) + log.Fatal().Err(err).Msg("Cannot register handler server: ") } mux := http.NewServeMux() @@ -94,11 +95,11 @@ func RunGatewayServer(store db.Store, config utils.Config) { listener, err := net.Listen("tcp", config.HttpServerAddress) if err != nil { - log.Fatalf("Cannot create tcp-listener for gateway server: %s", err) + log.Fatal().Err(err).Msg("Cannot create tcp-listener for gateway server: ") } - log.Printf("start HTTP gateway server at: %s", listener.Addr().String()) + log.Printf("start HTTP gateway server at: %s ", listener.Addr().String()) if err = http.Serve(listener, mux); err != nil { - log.Fatalf("cannot HTTP gateway server: %s", err) + log.Fatal().Err(err).Msg("cannot HTTP gateway server: ") } }