From 003870922fbb303e7cf7de5b83f535de444e872e Mon Sep 17 00:00:00 2001 From: Tucker Gary Siegel <tgsiegel@terpmail.umd.edu> Date: Wed, 18 Aug 2021 15:12:34 -0400 Subject: [PATCH] custom logging --- config/local | 3 +- errors/dawn_errors.go | 43 +++++++++++-- logger/logger.go | 103 ++++++++++++++++++++++++++++++ main.go | 36 ++++++++--- models/csv.go | 8 --- services/data_download_service.go | 2 +- 6 files changed, 169 insertions(+), 26 deletions(-) create mode 100644 logger/logger.go diff --git a/config/local b/config/local index 87ecead..a0d3588 100644 --- a/config/local +++ b/config/local @@ -1,5 +1,6 @@ app: name: dawn-server + # logType: json server: host: "localhost" @@ -8,4 +9,4 @@ server: db: uri: "mongodb://127.0.0.1:27017/" - database: "weather-service" \ No newline at end of file + database: "weather-service" diff --git a/errors/dawn_errors.go b/errors/dawn_errors.go index a20d95d..adbb0c3 100644 --- a/errors/dawn_errors.go +++ b/errors/dawn_errors.go @@ -1,8 +1,8 @@ package errors import ( + "encoding/json" "fmt" - "log" "os" "strconv" @@ -17,7 +17,7 @@ type BaseError interface { type DawnError struct { Name string `json:"name"` Description string `json:"description"` - LogDetails string `json:"log_details,omitempty"` + LogDetails string `json:"log_details"` Code int `json:"code"` } @@ -33,7 +33,11 @@ type StandardError struct { } func (err *DawnError) Error() string { - return err.Name + ": " + err.Description + str := err.Name + ": " + err.Description + if err.LogDetails != "" { + str += " - " + err.LogDetails + } + return str } func (err *DawnError) BuildStandardError(ctx *fiber.Ctx) StandardError { @@ -47,13 +51,27 @@ func (err *DawnError) AddLogDetails(logDetails string) *DawnError { return err } -func (err *StandardError) LogJson() { - log.Println(err) +func Build(err error) *DawnError { + return &DawnError{ + Name: "INTERNAL_SERVER_ERROR", + Description: err.Error(), + Code: 500, + } +} + +func (err *DawnError) LogJson(c *fiber.Ctx) { + jsonErrBytes, _ := json.Marshal(err) + fmt.Println(string(jsonErrBytes)) } func (err *DawnError) LogString(c *fiber.Ctx) { requestId := c.Locals("requestId") - output := strconv.Itoa(os.Getpid()) + " " + fmt.Sprintf("%s", requestId) + " " + strconv.Itoa(err.Code) + " - " + c.Method() + " " + c.Route().Path + " - " + err.Error() + " - " + err.LogDetails + // requestBody := c.Request() + // requestBodyStr, _ := json.Marshal(requestBody) + output := strconv.Itoa(os.Getpid()) + " " + fmt.Sprintf("%s", requestId) + " " + strconv.Itoa(err.Code) + " - " + c.Method() + " " + c.Route().Path + " - " + err.Error() + if err.LogDetails != "" { + output += " - " + err.LogDetails + } fmt.Println(output) } @@ -78,8 +96,21 @@ var NO_DATA_FOUND = &DawnError{ } // 500s + +var INTERNAL_SERVER_STANDARD_ERROR = &DawnError{ + Name: "INTERNAL_SERVER_ERROR", + Description: "Unkown internal server error occurred", + Code: 500, +} + var DATE_PARSE_FAILURE = &DawnError{ Name: "DATE_PARSE_FAILURE", Description: "Date parse failure", Code: 500, } + +var FILE_CREATION_ERROR = &DawnError{ + Name: "FILE_CREATION_ERROR", + Description: "Could not create file", + Code: 500, +} diff --git a/logger/logger.go b/logger/logger.go new file mode 100644 index 0000000..883308d --- /dev/null +++ b/logger/logger.go @@ -0,0 +1,103 @@ +package logger + +import ( + "dawn-weather/errors" + "encoding/json" + "fmt" + "os" + "strconv" + "time" + + "github.com/gofiber/fiber/v2" + "github.com/spf13/viper" + "github.com/valyala/fasthttp" +) + +type LogMessage struct { + Date string + PID string + RequestId string + Error *errors.DawnError + StatusCode string + Method string + Path string +} + +type Request struct { + Headers fasthttp.RequestHeader +} + +func cleanRequest(c *fiber.Ctx, r *fasthttp.Request) Request { + headers := fasthttp.AcquireRequest().Header + r.Header.CopyTo(&headers) + fmt.Println(headers.String()) + return Request{ + Headers: headers, + } +} + +func BuildMessage(c *fiber.Ctx) LogMessage { + const layout = "2006-01-02 03:04:05" + requestId := c.Locals("requestId") + + message := LogMessage{ + Date: time.Now().UTC().Format(layout), + RequestId: fmt.Sprintf("%s", requestId), + StatusCode: strconv.Itoa(c.Response().StatusCode()), + Method: c.Method(), + Path: c.Route().Path, + PID: strconv.Itoa(os.Getpid()), + } + return message +} + +func Log(message LogMessage) { + logString := "" + if viper.GetString("app.logType") == "json" { + tempLogString, _ := json.MarshalIndent(message, "", " ") + logString = string(tempLogString) + } else { + logString = fmt.Sprintf("%s %s %s %s - %s %s", message.Date, message.PID, message.RequestId, message.StatusCode, message.Method, message.Path) //strconv.Itoa(os.Getpid()) + " " + fmt.Sprintf("%s", requestId) + " " + strconv.Itoa(err.Code) + " - " + c.Method() + " " + c.Route().Path + " - " + err.Error() + if message.Error != nil { + logString += " - " + message.Error.Error() + } + } + + fmt.Println(logString) +} + +func New() fiber.Handler { + + return func(c *fiber.Ctx) error { + errHandler := c.App().Config().ErrorHandler + chainErr := c.Next() + + message := BuildMessage(c) + + if chainErr != nil { + dawnError := ErrorHandler(c, chainErr) + message.Error = dawnError + } + + Log(message) + + if chainErr != nil { + if err := errHandler(c, chainErr); err != nil { + _ = c.SendStatus(fiber.StatusInternalServerError) + } + } + + return nil + } +} + +func ErrorHandler(ctx *fiber.Ctx, err error) *errors.DawnError { + var returnError *errors.DawnError + if e, ok := err.(*errors.DawnError); ok { + returnError = e + } else { + returnError = errors.Build(err) + } + + return returnError +} diff --git a/main.go b/main.go index af3dade..8ae99a5 100644 --- a/main.go +++ b/main.go @@ -3,14 +3,14 @@ package main import ( "dawn-weather/config" "dawn-weather/errors" + "dawn-weather/logger" "dawn-weather/persistence" - "fmt" + "strconv" "github.com/ansrivas/fiberprometheus/v2" swagger "github.com/arsmn/fiber-swagger/v2" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/cors" - "github.com/gofiber/fiber/v2/middleware/logger" "github.com/gofiber/fiber/v2/middleware/recover" "github.com/gofiber/fiber/v2/middleware/requestid" "github.com/gofiber/fiber/v2/utils" @@ -46,9 +46,17 @@ func registerLogging(app *fiber.App) { ContextKey: "requestId", })) - app.Use(logger.New(logger.Config{ - Format: "${pid} ${locals:requestId} ${status} - ${method} ${path}\n", - })) + // app.Use(logger.New(logger.Config{ + // Format: "${pid} ${locals:requestId} ${status} - ${method} ${path}\n", + // })) + + // app.Use(func(c *fiber.Ctx) error { + // fmt.Println(c.Response().StatusCode()) + // fmt.Println("hey!") + // return c.Next() + // }) + + app.Use(logger.New()) } func registerPrometheus(app *fiber.App) { @@ -62,17 +70,25 @@ func createFiberConfig() fiber.Config { ErrorHandler: func(ctx *fiber.Ctx, err error) error { code := fiber.StatusInternalServerError - message := errors.StandardError{Source: viper.GetString("app.name"), ErrorCode: "UNKNOWN_ERROR", - Description: "Unknown error occurred", Details: errors.ErrorDetails{RequestId: ""}} + message := errors.StandardError{Source: viper.GetString("app.name"), ErrorCode: "INTERNAL_SERVER", + Description: "Internal Server Error Occurred", Details: errors.ErrorDetails{RequestId: ""}} if e, ok := err.(*errors.DawnError); ok { code = e.Code message = err.(*errors.DawnError).BuildStandardError(ctx) - err.(*errors.DawnError).LogString(ctx) } else { - fmt.Println(err) + err = errors.Build(err) + } + + logMessage := logger.BuildMessage(ctx) + logMessage.Error = err.(*errors.DawnError) + logMessage.StatusCode = strconv.Itoa(code) + + logger.Log(logMessage) + + if code == 500 { + message = errors.INTERNAL_SERVER_STANDARD_ERROR.BuildStandardError(ctx) } - // message.LogJson() err = ctx.Status(code).JSON(message) diff --git a/models/csv.go b/models/csv.go index a71ec0a..de0d5ba 100644 --- a/models/csv.go +++ b/models/csv.go @@ -107,11 +107,3 @@ func (r CSVRequest) Build(c *fiber.Ctx) CSVRequest { return newRequest } - -// func (r GddRequest) BuildLocation() entities.Location { -// l := entities.Location{ -// Type: "Point", -// Coordinates: []float64{r.Longitude, r.Latitude}, -// } -// return l -// } diff --git a/services/data_download_service.go b/services/data_download_service.go index c18dfd8..5ccf021 100644 --- a/services/data_download_service.go +++ b/services/data_download_service.go @@ -430,7 +430,7 @@ func GetDataDownload(request models.CSVRequest) string { f, err := os.Create(fileId.String() + ".csv") if err != nil { - panic(errors.BAD_REQUEST) + panic(errors.FILE_CREATION_ERROR.AddLogDetails("Could not create file")) } w := csv.NewWriter(f) -- GitLab