Last active
June 1, 2024 11:56
-
-
Save buYoung/817e90a27cd6a55052e9dc1e4154abfd to your computer and use it in GitHub Desktop.
Advanced Logging in Go with Zerolog and Lumberjack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package logger | |
type LogRequestBodyType string | |
const ( | |
LogRequestBodyTypeFormData = "multipart/form-data" | |
LogRequestBodyTypeJSON = "application/json" | |
LogRequestBodyTypeTEXT = "text/plain" | |
LogRequestBodyTypeURLEncoded = "application/x-www-form-urlencoded" | |
) | |
type LogLevel int | |
const ( | |
LogLevelDebug = -1 | |
LogLevelInfo = 0 | |
LogLevelWarn = 1 | |
LogLevelError = 2 | |
LogLevelDPanic = 3 | |
LogLevelPanic = 4 | |
LogLevelFatal = 5 | |
) | |
type LogHTTPMethod string | |
const ( | |
LogHTTPMethodGET = "GET" | |
LogHTTPMethodPOST = "POST" | |
LogHTTPMethodPUT = "PUT" | |
LogHTTPMethodDELETE = "DELETE" | |
LogHTTPMethodPATCH = "PATCH" | |
LogHTTPMethodHEAD = "HEAD" | |
LogHTTPMethodOPTIONS = "OPTIONS" | |
LogHTTPMethodCONNECT = "CONNECT" | |
LogHTTPMethodTRACE = "TRACE" | |
LogHTTPMethodUNKNOWN = "UNKNOWN" | |
) | |
type RequestLog[RequestBody any, ResponseBody any] struct { | |
RequestID string `json:"request_id"` | |
HTTPMethod LogHTTPMethod `json:"http_method"` | |
URL string `json:"url"` | |
ClientIP string `json:"client_ip"` | |
QueryParameters map[string]string `json:"query_parameters"` | |
RequestHeaders map[string]string `json:"request_headers"` | |
RequestBody RequestBody `json:"request_body"` | |
RequestBodyType LogRequestBodyType `json:"request_body_type"` | |
ResponseStatusCode int `json:"response_status_code"` | |
ResponseHeaders map[string]string `json:"response_headers"` | |
ResponseBody ResponseBody `json:"response_body"` | |
ProcessingTimes map[string]int `json:"processing_time_ms"` | |
} | |
type RequestErrorLog[RequestBody any] struct { | |
RequestID string `json:"request_id"` | |
HTTPMethod LogHTTPMethod `json:"http_method"` | |
URL string `json:"url"` | |
ClientIP string `json:"client_ip"` | |
QueryParameters map[string]string `json:"query_parameters"` | |
RequestHeaders map[string]string `json:"request_headers"` | |
RequestBody RequestBody `json:"request_body"` | |
RequestBodyType LogRequestBodyType `json:"request_body_type"` | |
ProcessingTimes map[string]int `json:"processing_time_ms"` | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package logger | |
import ( | |
"fmt" | |
"io" | |
"os" | |
"path" | |
"github.com/rs/zerolog" | |
"gopkg.in/natefinch/lumberjack.v2" | |
) | |
type Config struct { | |
IsDevAndShowConsole bool | |
Directory string | |
Filename string | |
MaxSize int | |
MaxBackups int | |
MaxAge int | |
} | |
type SpecificLevelWriter struct { | |
io.Writer | |
Levels []zerolog.Level | |
isDevAndShowConsole bool | |
} | |
func (w SpecificLevelWriter) WriteLevel(level zerolog.Level, p []byte) (int, error) { | |
for _, l := range w.Levels { | |
if w.isDevAndShowConsole && l == zerolog.NoLevel { | |
return w.Write(p) //nolint:wrapcheck | |
} | |
if l == level { | |
return w.Write(p) //nolint:wrapcheck | |
} | |
} | |
return len(p), nil | |
} | |
func CreateNewLogger(config Config) (*zerolog.Logger, error) { | |
writers := zerolog.MultiLevelWriter( | |
SpecificLevelWriter{ | |
Writer: &lumberjack.Logger{ | |
Filename: path.Join(config.Directory, fmt.Sprintf("%s_%s.%s", config.Filename, "verbose", "log")), | |
MaxSize: config.MaxSize, | |
MaxBackups: config.MaxBackups, | |
MaxAge: config.MaxAge, | |
Compress: true, | |
}, | |
Levels: []zerolog.Level{zerolog.TraceLevel}, | |
isDevAndShowConsole: false, | |
}, | |
SpecificLevelWriter{ | |
Writer: &lumberjack.Logger{ | |
Filename: path.Join(config.Directory, fmt.Sprintf("%s_%s.%s", config.Filename, "info", "log")), | |
MaxSize: config.MaxSize, | |
MaxBackups: config.MaxBackups, | |
MaxAge: config.MaxAge, | |
Compress: true, | |
}, | |
Levels: []zerolog.Level{zerolog.InfoLevel, zerolog.DebugLevel, zerolog.WarnLevel}, | |
isDevAndShowConsole: false, | |
}, | |
SpecificLevelWriter{ | |
Writer: &lumberjack.Logger{ | |
Filename: path.Join(config.Directory, fmt.Sprintf("%s_%s.%s", config.Filename, "error", "log")), | |
MaxSize: config.MaxSize, | |
MaxBackups: config.MaxBackups, | |
MaxAge: config.MaxAge, | |
Compress: true, | |
}, | |
Levels: []zerolog.Level{zerolog.ErrorLevel, zerolog.PanicLevel, zerolog.FatalLevel}, | |
isDevAndShowConsole: false, | |
}, | |
SpecificLevelWriter{ | |
Writer: zerolog.ConsoleWriter{Out: os.Stderr}, | |
Levels: []zerolog.Level{zerolog.NoLevel}, | |
isDevAndShowConsole: config.IsDevAndShowConsole, | |
}, | |
) | |
zerolog.TimestampFieldName = "timestamp" | |
zerolog.TimeFieldFormat = "2006-01-02T15:04:05.000Z" | |
logger := zerolog.New(writers).With().Timestamp().Logger() | |
return &logger, nil | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
_logger, err := logger.CreateNewLogger(logger.Config{ | |
IsDevAndShowConsole: true, | |
Directory: "log", | |
Filename: "app", | |
MaxSize: 1, | |
MaxBackups: 5, | |
MaxAge: 5, | |
}) | |
if err != nil { | |
panic(err) | |
} | |
_logger.Info().Interface("http", logger.RequestLog[string, string]{ | |
RequestID: "1234", | |
ClientIP: "", | |
HTTPMethod: logger.LogHTTPMethodGET, | |
URL: "http://localhost:8080", | |
QueryParameters: map[string]string{ | |
"key": "value", | |
}, | |
RequestHeaders: map[string]string{ | |
"key": "value", | |
}, | |
RequestBody: "Hello, World!", | |
RequestBodyType: logger.LogRequestBodyTypeJSON, | |
ResponseStatusCode: 200, | |
ResponseHeaders: map[string]string{ | |
"key": "value", | |
}, | |
ResponseBody: "Hello, World!", | |
ProcessingTimes: map[string]int{ | |
"key": 100, | |
}, | |
}).Msg("Hello, World!") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment