Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ft/add logger #17

Merged
merged 9 commits into from
May 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
)

type Config struct {
Environment string `mapstrucutre:"ENVIRONMENT"`
DatabaseDriver string `mapstructure:"DATABASE_DRIVER"`
DatabaseSource string `mapstructure:"DATABASE_SOURCE"`
HTTPServerHost string `mapstructure:"HTTP_SERVER_HOST"`
Expand Down
1 change: 1 addition & 0 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ func TestLoadConfig(t *testing.T) {
require.Equal(t, "source", config.DatabaseSource)
require.Equal(t, "driver", config.DatabaseDriver)
require.Equal(t, "key", config.TokenSymmetricKey)
require.Equal(t, "environment", config.Environment)
require.Equal(t, 1*time.Minute, config.TokenAccessTokenDuration)
}
1 change: 1 addition & 0 deletions config/config_test.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"ENVIRONMENT": "environment",
"DATABASE_DRIVER": "driver",
"DATABASE_SOURCE": "source",
"HTTP_SERVER_HOST": "http host",
Expand Down
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ require (
github.com/jackc/pgx/v5 v5.4.3
github.com/o1egl/paseto v1.0.0
github.com/pkg/errors v0.9.1
github.com/rs/zerolog v1.32.0
github.com/spf13/viper v1.18.2
github.com/stretchr/testify v1.9.0
go.uber.org/mock v0.4.0
golang.org/x/crypto v0.22.0
google.golang.org/genproto/googleapis/api v0.0.0-20240125205218-1f4bbc51befe
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe
google.golang.org/grpc v1.61.0
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0
google.golang.org/protobuf v1.33.0
Expand Down Expand Up @@ -47,6 +49,7 @@ require (
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/leodido/go-urn v1.4.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
Expand All @@ -70,7 +73,6 @@ require (
golang.org/x/sys v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
11 changes: 11 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,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=
Expand All @@ -42,6 +43,7 @@ github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn
github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
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/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
Expand Down Expand Up @@ -79,6 +81,10 @@ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
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=
Expand All @@ -100,6 +106,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.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
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=
Expand Down Expand Up @@ -148,8 +157,10 @@ golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSO
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
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.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
Expand Down
92 changes: 92 additions & 0 deletions grpc_api/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package grpc_api

import (
"context"
"github.com/rs/zerolog/log"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"net/http"
"time"
)

// GrpcLogger logs information about gRPC requests and responses.
// It logs details such as protocol, method, duration, status code, and status text.
func GrpcLogger(
ctx context.Context,
req any,
info *grpc.UnaryServerInfo,
handler grpc.UnaryHandler,
) (resp any, err error) {

start := time.Now()
resp, err = handler(ctx, req)
duration := time.Since(start)

statusCode := codes.Unknown
if st, ok := status.FromError(err); ok {
statusCode = st.Code()
}

logger := log.Info()
if err != nil {
logger = log.Error().Err(err)
}

logger.
Str("protocol", "grpc").
Str("method", info.FullMethod).
Dur("duration", duration).
Int("status_code", int(statusCode)).
Str("status_text", statusCode.String()).
Msg("received a gRPC request")

return resp, err
}

// ResponseRecorder implements http.ResponseWriter and records information about HTTP responses.
type ResponseRecorder struct {
http.ResponseWriter
StatusCode int
Body []byte
}

// WriteHeader records the status code of the HTTP response.
func (rec *ResponseRecorder) WriteHeader(statusCode int) {
rec.StatusCode = statusCode
rec.ResponseWriter.WriteHeader(statusCode)
}

// Write records the body of the HTTP response into the ResponseRecorder.Body.
func (rec *ResponseRecorder) Write(body []byte) (int, error) {
rec.Body = body
return rec.ResponseWriter.Write(body)
}

// HttpLogger logs information about HTTP requests and responses.
// It logs details such as protocol, method, path, status code, status text, duration, and response body (in case of non-200 status codes).
func HttpLogger(handler http.Handler) http.Handler {
return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
startTime := time.Now()
rec := &ResponseRecorder{
ResponseWriter: res,
StatusCode: http.StatusOK,
}
handler.ServeHTTP(rec, req)
duration := time.Since(startTime)

logger := log.Info()
if rec.StatusCode != http.StatusOK {
logger = log.Error().Bytes("body", rec.Body)
}

logger.
Str("protocol", "http").
Str("method", req.Method).
Str("path", req.RequestURI).
Int("status_code", rec.StatusCode).
Str("status_text", http.StatusText(rec.StatusCode)).
Dur("duration", duration).
Msg("received a HTTP request")
})
}
41 changes: 25 additions & 16 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,37 +11,43 @@ import (
"context"
"database/sql"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
"google.golang.org/protobuf/encoding/protojson"
"gorm.io/gorm"
"log"
"net"
"net/http"
"os"
)

func main() {
configs, err := config.LoadConfig("./config", "config")
if err != nil {
log.Fatalln(err)
log.Fatal().Err(err).Msg("cannot load configs")
}

if configs.Environment == "development" {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
}

db.Init(configs.DatabaseSource)
db := db.GetDB()
DB, err := db.DB()
if err != nil {
log.Fatalln(err)
log.Fatal().Err(err).Msg("cannot get *sql.DB object")
}
defer func(DB *sql.DB) {
err := DB.Close()
if err != nil {
log.Fatalln(err)
log.Fatal().Err(err).Msg("cannot close db connection")
}
}(DB)

tokenMaker, err := token.NewPasetoMaker(configs.TokenSymmetricKey)
if err != nil {
log.Fatalf("cannot create token maker: %v", err)
log.Fatal().Err(err).Msg("cannot create token maker")
}

//runGinServer(configs, tokenMaker, db)
Expand All @@ -52,31 +58,32 @@ func main() {
func runGinServer(config config.Config, tokenMaker token.Maker, db *gorm.DB) {
server, err := api.NewServer(&config, services.NewSQLServices(db), tokenMaker)
if err != nil {
log.Fatalln("cannot create server: ", err)
log.Fatal().Err(err).Msg("cannot create server")
}

if err = server.Start(config.HTTPServerHost + ":" + config.HTTPServerPort); err != nil {
log.Fatalln("cannot start server: ", err)
log.Fatal().Err(err).Msg("cannot start server")
}
}

func runGrpcServer(config config.Config, tokenMaker token.Maker, db *gorm.DB) {
server := grpc_api.NewServer(&config, services.NewSQLServices(db), tokenMaker)

grpcServer := grpc.NewServer()
grpcLogger := grpc.UnaryInterceptor(grpc_api.GrpcLogger)
grpcServer := grpc.NewServer(grpcLogger)
pb.RegisterSimpleBankServer(grpcServer, server)
reflection.Register(grpcServer)

serverAddress := config.GrpcServerHost + ":" + config.GrpcServerPort
listener, err := net.Listen("tcp", serverAddress)
if err != nil {
log.Fatalln("cannot create listener: ", err)
log.Fatal().Err(err).Msg("cannot create listener")
}

log.Println("grpc server started at " + listener.Addr().String())
log.Info().Msg("grpc server started at " + listener.Addr().String())
err = grpcServer.Serve(listener)
if err != nil {
log.Fatalln("cannot create grpc server ", err)
log.Fatal().Err(err).Msg("cannot create grpc server")
}
}

Expand All @@ -97,7 +104,7 @@ func runGrpcGatewayServer(config config.Config, tokenMaker token.Maker, db *gorm

err := pb.RegisterSimpleBankHandlerServer(ctx, grpcMux, server)
if err != nil {
log.Fatalln("cannot register handler server")
log.Fatal().Err(err).Msg("cannot register handler server")
}

mux := http.NewServeMux()
Expand All @@ -109,12 +116,14 @@ func runGrpcGatewayServer(config config.Config, tokenMaker token.Maker, db *gorm
serverAddress := config.HTTPServerHost + ":" + config.HTTPServerPort
listener, err := net.Listen("tcp", serverAddress)
if err != nil {
log.Fatalln("cannot create listener: ", err)
log.Fatal().Err(err).Msg("cannot create listener")
}

log.Println("http gateway server started at " + listener.Addr().String())
err = http.Serve(listener, mux)
log.Info().Msg("http gateway server started at " + listener.Addr().String())

handler := grpc_api.HttpLogger(mux)
err = http.Serve(listener, handler)
if err != nil {
log.Fatalln("cannot start HTTP gateway server ", err)
log.Fatal().Err(err).Msg("cannot start HTTP gateway server")
}
}
Loading