Skip to content

Commit

Permalink
Use StringFormat as default
Browse files Browse the repository at this point in the history
  • Loading branch information
minhduc140583 committed Aug 25, 2024
1 parent b08631f commit 159ec16
Show file tree
Hide file tree
Showing 13 changed files with 148 additions and 132 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
### Middleware Integration
#### Features
- <b>Middleware Function</b>: Designed to integrate seamlessly with existing Go libraries: [Echo](https://github.com/labstack/echo), [Gin](https://github.com/gin-gonic/gin), or net/http ([Gorilla mux](https://github.com/gorilla/mux), [Go-chi](https://github.com/go-chi/chi)).
- Sample for [Echo](https://github.com/labstack/echo) is at [go-sql-echo-sample](https://github.com/go-tutorials/go-sql-echo-sample)
- Sample for [Gin](https://github.com/gin-gonic/gin) is at [go-sql-gin-sample](https://github.com/go-tutorials/go-sql-gin-sample)
- Sample for [Echo](https://github.com/labstack/echo) is at [go-echo-sql-sample](https://github.com/go-tutorials/go-echo-sql-sample)
- Sample for [Gin](https://github.com/gin-gonic/gin) is at [go-gin-sql-sample](https://github.com/go-tutorials/go-gin-sql-sample)
- Sample for [Gorilla mux](https://github.com/gorilla/mux) is at [go-sql-sample](https://github.com/go-tutorials/go-sql-sample)
- <b>Context Handling</b>: Pass context to handle request-specific data throughout the middleware chain.
#### Benefits
Expand Down Expand Up @@ -80,8 +80,8 @@
### Sensitive Data Encryption
#### Features
- Mask/Encrypt sensitive data in the request and response bodies.
- Sample for [Echo](https://github.com/labstack/echo) is at [go-sql-echo-sample](https://github.com/go-tutorials/go-sql-echo-sample)
- Sample for [Gin](https://github.com/gin-gonic/gin) is at [go-sql-gin-sample](https://github.com/go-tutorials/go-sql-gin-sample)
- Sample for [Echo](https://github.com/labstack/echo) is at [go-echo-sql-sample](https://github.com/go-tutorials/go-echo-sql-sample)
- Sample for [Gin](https://github.com/gin-gonic/gin) is at [go-gin-sql-sample](https://github.com/go-tutorials/go-gin-sql-sample)
- Sample for [Gorilla mux](https://github.com/gorilla/mux) is at [go-sql-sample](https://github.com/go-tutorials/go-sql-sample)
- Sensitive Data Identification: identify and encrypt specific fields in JSON payloads.

Expand Down
2 changes: 1 addition & 1 deletion echo/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package echo
type LogConfig struct {
Separate bool `yaml:"separate" mapstructure:"separate" json:"separate,omitempty" gorm:"column:separate" bson:"separate,omitempty" dynamodbav:"separate,omitempty" firestore:"separate,omitempty"`
Build bool `yaml:"build" mapstructure:"build" json:"build,omitempty" gorm:"column:build" bson:"build,omitempty" dynamodbav:"build,omitempty" firestore:"build,omitempty"`
StringFormat bool `yaml:"string_format" mapstructure:"string_format" json:"stringFormat,omitempty" gorm:"column:string_format" bson:"stringFormat,omitempty" dynamodbav:"stringFormat,omitempty" firestore:"stringFormat,omitempty"`
Json bool `yaml:"json" mapstructure:"json" json:"json,omitempty" gorm:"column:json" bson:"json,omitempty" dynamodbav:"json,omitempty" firestore:"json,omitempty"`
Log bool `yaml:"log" mapstructure:"log" json:"log,omitempty" gorm:"column:log" bson:"log,omitempty" dynamodbav:"log,omitempty" firestore:"log,omitempty"`
Skips string `yaml:"skips" mapstructure:"skips" json:"skips,omitempty" gorm:"column:skips" bson:"skips,omitempty" dynamodbav:"skips,omitempty" firestore:"skips,omitempty"`
Ip string `yaml:"ip" mapstructure:"ip" json:"ip,omitempty" gorm:"column:ip" bson:"ip,omitempty" dynamodbav:"ip,omitempty" firestore:"ip,omitempty"`
Expand Down
36 changes: 20 additions & 16 deletions echo/mask_logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,57 +14,61 @@ type MaskLogger struct {
RequestKey string
MaskRequest func(map[string]interface{})
MaskResponse func(map[string]interface{})
StringFormat bool
JsonFormat bool
}

func NewMaskLogger(requestKey string, maskRequest func(map[string]interface{}), maskResponse func(map[string]interface{}), stringFormat bool) *MaskLogger {
return &MaskLogger{RequestKey: requestKey, MaskRequest: maskRequest, MaskResponse: maskResponse, StringFormat: stringFormat}
func NewMaskLogger(requestKey string, maskRequest func(map[string]interface{}), maskResponse func(map[string]interface{}), opts ...bool) *MaskLogger {
jsonFormat := false
if len(opts) > 0 {
jsonFormat = opts[0]
}
return &MaskLogger{RequestKey: requestKey, MaskRequest: maskRequest, MaskResponse: maskResponse, JsonFormat: jsonFormat}
}
func NewMaskLoggerWithSending(requestKey string, maskRequest func(map[string]interface{}), maskResponse func(map[string]interface{}), stringFormat bool, send func(context.Context, []byte, map[string]string) error, options ...map[string]string) *MaskLogger {
func NewMaskLoggerWithSending(requestKey string, maskRequest func(map[string]interface{}), maskResponse func(map[string]interface{}), jsonFormat bool, send func(context.Context, []byte, map[string]string) error, options ...map[string]string) *MaskLogger {
var keyMap map[string]string
if len(options) >= 1 {
keyMap = options[0]
}
return &MaskLogger{RequestKey: requestKey, MaskRequest: maskRequest, MaskResponse: maskResponse, StringFormat: stringFormat, send: send, KeyMap: keyMap}
return &MaskLogger{RequestKey: requestKey, MaskRequest: maskRequest, MaskResponse: maskResponse, JsonFormat: jsonFormat, send: send, KeyMap: keyMap}
}
func (l *MaskLogger) LogResponse(log func(context.Context, string, map[string]interface{}), r *http.Request, ww WrapResponseWriter,
c LogConfig, t1 time.Time, response string, fields map[string]interface{}, includeRequest bool) {
if includeRequest && len(c.Request) > 0 {
MaskRequest(c.Request, fields, l.MaskRequest, l.StringFormat)
MaskRequest(c.Request, fields, l.MaskRequest, l.JsonFormat)
}
MaskResponse(ww, c, t1, response, fields, l.MaskResponse, l.StringFormat)
MaskResponse(ww, c, t1, response, fields, l.MaskResponse, l.JsonFormat)
msg := r.Method + " " + r.RequestURI
log(r.Context(), msg, fields)
if l.send != nil {
go Send(r.Context(), l.send, msg, fields, l.KeyMap)
}
}
func (l *MaskLogger) LogRequest(log func(context.Context, string, map[string]interface{}), r *http.Request, fields map[string]interface{}) {
MaskRequest(l.RequestKey, fields, l.MaskRequest, l.StringFormat)
MaskRequest(l.RequestKey, fields, l.MaskRequest, l.JsonFormat)
msg := "Request " + r.Method + " " + r.RequestURI
log(r.Context(), msg, fields)
if l.send != nil {
go Send(r.Context(), l.send, msg, fields, l.KeyMap)
}
}

func MaskResponse(ww WrapResponseWriter, c LogConfig, t1 time.Time, response string, fields map[string]interface{}, mask func(map[string]interface{}), isStringFormat bool) {
func MaskResponse(ww WrapResponseWriter, c LogConfig, t1 time.Time, response string, fields map[string]interface{}, mask func(map[string]interface{}), isJsonFormat bool) {
if len(c.Response) > 0 {
fields[c.Response] = response
responseBody := response
responseMap := map[string]interface{}{}
json.Unmarshal([]byte(responseBody), &responseMap)
if len(responseMap) > 0 {
mask(responseMap)
if isStringFormat {
if isJsonFormat {
fields[c.Response] = responseMap
} else {
responseString, err := json.Marshal(responseMap)
if err != nil {
fmt.Printf("Error: %s", err.Error())
} else {
fields[c.Response] = string(responseString)
}
} else {
fields[c.Response] = responseMap
}
}
}
Expand All @@ -80,7 +84,7 @@ func MaskResponse(ww WrapResponseWriter, c LogConfig, t1 time.Time, response str
fields[c.Size] = ww.BytesWritten()
}
}
func MaskRequest(request string, fields map[string]interface{}, mask func(map[string]interface{}), isStringFormat bool) {
func MaskRequest(request string, fields map[string]interface{}, mask func(map[string]interface{}), isJsonFormat bool) {
if len(request) > 0 {
req, ok := fields[request]
if ok {
Expand All @@ -90,15 +94,15 @@ func MaskRequest(request string, fields map[string]interface{}, mask func(map[st
json.Unmarshal([]byte(requestBody), &requestMap)
if len(requestMap) > 0 {
mask(requestMap)
if isStringFormat {
if isJsonFormat {
fields[request] = requestMap
} else {
requestString, err := json.Marshal(requestMap)
if err != nil {
fmt.Printf("Error: %s", err.Error())
} else {
fields[request] = string(requestString)
}
} else {
fields[request] = requestMap
}
}
}
Expand Down
30 changes: 15 additions & 15 deletions echo/structured_logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,30 @@ type Formatter interface {
LogResponse(log func(context.Context, string, map[string]interface{}), r *http.Request, ww WrapResponseWriter, c LogConfig, startTime time.Time, response string, fields map[string]interface{}, includeRequest bool)
}
type StructuredLogger struct {
send func(context.Context, []byte, map[string]string) error
KeyMap map[string]string
RequestKey string
StringFormat bool
send func(context.Context, []byte, map[string]string) error
KeyMap map[string]string
RequestKey string
JsonFormat bool
}

var fieldConfig FieldConfig

func NewLogger() *StructuredLogger {
return &StructuredLogger{}
}
func NewLoggerWithStringFormat(requestKey string, stringFormat bool) *StructuredLogger {
return &StructuredLogger{RequestKey: requestKey, StringFormat: stringFormat}
func NewLoggerWithJsonFormat(requestKey string, jsonFormat bool) *StructuredLogger {
return &StructuredLogger{RequestKey: requestKey, JsonFormat: jsonFormat}
}
func NewLoggerWithSending(requestKey string, stringFormat bool, send func(context.Context, []byte, map[string]string) error, options ...map[string]string) *StructuredLogger {
func NewLoggerWithSending(requestKey string, jsonFormat bool, send func(context.Context, []byte, map[string]string) error, options ...map[string]string) *StructuredLogger {
var keyMap map[string]string
if len(options) >= 1 {
keyMap = options[0]
}
return &StructuredLogger{RequestKey: requestKey, StringFormat: stringFormat, send: send, KeyMap: keyMap}
return &StructuredLogger{RequestKey: requestKey, JsonFormat: jsonFormat, send: send, KeyMap: keyMap}
}
func (l *StructuredLogger) LogResponse(log func(context.Context, string, map[string]interface{}), r *http.Request, ww WrapResponseWriter,
c LogConfig, t1 time.Time, response string, fields map[string]interface{}, includeRequest bool) {
BuildResponse(ww, c, t1, response, fields, l.StringFormat)
BuildResponse(ww, c, t1, response, fields, l.JsonFormat)
msg := r.Method + " " + r.RequestURI
log(r.Context(), msg, fields)
if l.send != nil {
Expand All @@ -53,7 +53,7 @@ func Send(ctx context.Context, send func(context.Context, []byte, map[string]str
}
func (l *StructuredLogger) LogRequest(log func(context.Context, string, map[string]interface{}), r *http.Request, fields map[string]interface{}) {
msg := "Request " + r.Method + " " + r.RequestURI
if !l.StringFormat && len(l.RequestKey) > 0 {
if l.JsonFormat && len(l.RequestKey) > 0 {
req, ok := fields[l.RequestKey]
if ok {
requestBody, ok2 := req.(string)
Expand All @@ -72,11 +72,9 @@ func (l *StructuredLogger) LogRequest(log func(context.Context, string, map[stri
}
}

func BuildResponse(ww WrapResponseWriter, c LogConfig, t1 time.Time, response string, fields map[string]interface{}, isStringFormat bool) {
func BuildResponse(ww WrapResponseWriter, c LogConfig, t1 time.Time, response string, fields map[string]interface{}, jsonFormat bool) {
if len(c.Response) > 0 {
if isStringFormat {
fields[c.Response] = response
} else {
if jsonFormat {
responseBody := response
responseMap := map[string]interface{}{}
json.Unmarshal([]byte(responseBody), &responseMap)
Expand All @@ -85,9 +83,11 @@ func BuildResponse(ww WrapResponseWriter, c LogConfig, t1 time.Time, response st
} else {
fields[c.Response] = response
}
} else {
fields[c.Response] = response
}
}
if !isStringFormat && len(c.Request) > 0 {
if jsonFormat && len(c.Request) > 0 {
req, ok := fields[c.Request]
if ok {
requestBody, ok2 := req.(string)
Expand Down
2 changes: 1 addition & 1 deletion echo/v3/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package echo
type LogConfig struct {
Separate bool `yaml:"separate" mapstructure:"separate" json:"separate,omitempty" gorm:"column:separate" bson:"separate,omitempty" dynamodbav:"separate,omitempty" firestore:"separate,omitempty"`
Build bool `yaml:"build" mapstructure:"build" json:"build,omitempty" gorm:"column:build" bson:"build,omitempty" dynamodbav:"build,omitempty" firestore:"build,omitempty"`
StringFormat bool `yaml:"string_format" mapstructure:"string_format" json:"stringFormat,omitempty" gorm:"column:string_format" bson:"stringFormat,omitempty" dynamodbav:"stringFormat,omitempty" firestore:"stringFormat,omitempty"`
Json bool `yaml:"json" mapstructure:"json" json:"json,omitempty" gorm:"column:json" bson:"json,omitempty" dynamodbav:"json,omitempty" firestore:"json,omitempty"`
Log bool `yaml:"log" mapstructure:"log" json:"log,omitempty" gorm:"column:log" bson:"log,omitempty" dynamodbav:"log,omitempty" firestore:"log,omitempty"`
Skips string `yaml:"skips" mapstructure:"skips" json:"skips,omitempty" gorm:"column:skips" bson:"skips,omitempty" dynamodbav:"skips,omitempty" firestore:"skips,omitempty"`
Ip string `yaml:"ip" mapstructure:"ip" json:"ip,omitempty" gorm:"column:ip" bson:"ip,omitempty" dynamodbav:"ip,omitempty" firestore:"ip,omitempty"`
Expand Down
36 changes: 20 additions & 16 deletions echo/v3/mask_logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,57 +14,61 @@ type MaskLogger struct {
RequestKey string
MaskRequest func(map[string]interface{})
MaskResponse func(map[string]interface{})
StringFormat bool
JsonFormat bool
}

func NewMaskLogger(requestKey string, maskRequest func(map[string]interface{}), maskResponse func(map[string]interface{}), stringFormat bool) *MaskLogger {
return &MaskLogger{RequestKey: requestKey, MaskRequest: maskRequest, MaskResponse: maskResponse, StringFormat: stringFormat}
func NewMaskLogger(requestKey string, maskRequest func(map[string]interface{}), maskResponse func(map[string]interface{}), opts ...bool) *MaskLogger {
jsonFormat := false
if len(opts) > 0 {
jsonFormat = opts[0]
}
return &MaskLogger{RequestKey: requestKey, MaskRequest: maskRequest, MaskResponse: maskResponse, JsonFormat: jsonFormat}
}
func NewMaskLoggerWithSending(requestKey string, maskRequest func(map[string]interface{}), maskResponse func(map[string]interface{}), stringFormat bool, send func(context.Context, []byte, map[string]string) error, options ...map[string]string) *MaskLogger {
func NewMaskLoggerWithSending(requestKey string, maskRequest func(map[string]interface{}), maskResponse func(map[string]interface{}), jsonFormat bool, send func(context.Context, []byte, map[string]string) error, options ...map[string]string) *MaskLogger {
var keyMap map[string]string
if len(options) >= 1 {
keyMap = options[0]
}
return &MaskLogger{RequestKey: requestKey, MaskRequest: maskRequest, MaskResponse: maskResponse, StringFormat: stringFormat, send: send, KeyMap: keyMap}
return &MaskLogger{RequestKey: requestKey, MaskRequest: maskRequest, MaskResponse: maskResponse, JsonFormat: jsonFormat, send: send, KeyMap: keyMap}
}
func (l *MaskLogger) LogResponse(log func(context.Context, string, map[string]interface{}), r *http.Request, ww WrapResponseWriter,
c LogConfig, t1 time.Time, response string, fields map[string]interface{}, includeRequest bool) {
if includeRequest && len(c.Request) > 0 {
MaskRequest(c.Request, fields, l.MaskRequest, l.StringFormat)
MaskRequest(c.Request, fields, l.MaskRequest, l.JsonFormat)
}
MaskResponse(ww, c, t1, response, fields, l.MaskResponse, l.StringFormat)
MaskResponse(ww, c, t1, response, fields, l.MaskResponse, l.JsonFormat)
msg := r.Method + " " + r.RequestURI
log(r.Context(), msg, fields)
if l.send != nil {
go Send(r.Context(), l.send, msg, fields, l.KeyMap)
}
}
func (l *MaskLogger) LogRequest(log func(context.Context, string, map[string]interface{}), r *http.Request, fields map[string]interface{}) {
MaskRequest(l.RequestKey, fields, l.MaskRequest, l.StringFormat)
MaskRequest(l.RequestKey, fields, l.MaskRequest, l.JsonFormat)
msg := "Request " + r.Method + " " + r.RequestURI
log(r.Context(), msg, fields)
if l.send != nil {
go Send(r.Context(), l.send, msg, fields, l.KeyMap)
}
}

func MaskResponse(ww WrapResponseWriter, c LogConfig, t1 time.Time, response string, fields map[string]interface{}, mask func(map[string]interface{}), isStringFormat bool) {
func MaskResponse(ww WrapResponseWriter, c LogConfig, t1 time.Time, response string, fields map[string]interface{}, mask func(map[string]interface{}), isJsonFormat bool) {
if len(c.Response) > 0 {
fields[c.Response] = response
responseBody := response
responseMap := map[string]interface{}{}
json.Unmarshal([]byte(responseBody), &responseMap)
if len(responseMap) > 0 {
mask(responseMap)
if isStringFormat {
if isJsonFormat {
fields[c.Response] = responseMap
} else {
responseString, err := json.Marshal(responseMap)
if err != nil {
fmt.Printf("Error: %s", err.Error())
} else {
fields[c.Response] = string(responseString)
}
} else {
fields[c.Response] = responseMap
}
}
}
Expand All @@ -80,7 +84,7 @@ func MaskResponse(ww WrapResponseWriter, c LogConfig, t1 time.Time, response str
fields[c.Size] = ww.BytesWritten()
}
}
func MaskRequest(request string, fields map[string]interface{}, mask func(map[string]interface{}), isStringFormat bool) {
func MaskRequest(request string, fields map[string]interface{}, mask func(map[string]interface{}), isJsonFormat bool) {
if len(request) > 0 {
req, ok := fields[request]
if ok {
Expand All @@ -90,15 +94,15 @@ func MaskRequest(request string, fields map[string]interface{}, mask func(map[st
json.Unmarshal([]byte(requestBody), &requestMap)
if len(requestMap) > 0 {
mask(requestMap)
if isStringFormat {
if isJsonFormat {
fields[request] = requestMap
} else {
requestString, err := json.Marshal(requestMap)
if err != nil {
fmt.Printf("Error: %s", err.Error())
} else {
fields[request] = string(requestString)
}
} else {
fields[request] = requestMap
}
}
}
Expand Down
Loading

0 comments on commit 159ec16

Please sign in to comment.