A Go library for structured logging and consistent JSON HTTP responses.
go get github.com/MonkyMars/gechoGecho provides two main features:
- Structured Logger - A thread-safe logger with multiple output formats and log levels
- HTTP Response Builder - Consistent JSON responses for HTTP handlers
import "github.com/MonkyMars/gecho"
func handler(w http.ResponseWriter, r *http.Request) {
// Success response
gecho.Success(w, gecho.Send())
// Success with data
gecho.Success(w,
gecho.WithData(map[string]any{"id": 1, "name": "Alice"}),
gecho.Send(),
)
// Error response
gecho.NotFound(w,
gecho.WithMessage("User not found"),
gecho.Send(),
)
}Success Responses:
Success(w, opts...)- 200 OKCreated(w, opts...)- 201 CreatedAccepted(w, opts...)- 202 AcceptedNoContent(w, opts...)- 204 No Content
Error Responses:
BadRequest(w, opts...)- 400 Bad RequestUnauthorized(w, opts...)- 401 UnauthorizedForbidden(w, opts...)- 403 ForbiddenNotFound(w, opts...)- 404 Not FoundMethodNotAllowed(w, opts...)- 405 Method Not AllowedConflict(w, opts...)- 409 ConflictInternalServerError(w, opts...)- 500 Internal Server ErrorServiceUnavailable(w, opts...)- 503 Service Unavailable
WithData(data any)- Add data to responseWithMessage(msg string)- Override default messageWithStatus(code int)- Override default status codeSend()- Send the response immediately
Responses can be modified after creation and sent later:
func handler(w http.ResponseWriter, r *http.Request) {
// Create response without sending
resp := gecho.Success(w, gecho.WithData(userData))
// Modify conditionally
if user.IsAdmin {
resp.SetMessage("Admin user found")
resp.AddData("role", "admin")
}
// Send when ready
resp.Send()
}Response Methods:
SetMessage(msg string)- Change the messageSetStatus(code int)- Change the status codeSetData(data any)- Replace all dataAddData(key, value)- Add a single field to dataSend()- Send the response
Chaining:
gecho.Created(w, gecho.WithData(user)).
SetMessage("User created and email sent").
AddData("email_sent", true).
Send()All responses return this JSON structure:
{
"status": 200,
"success": true,
"message": "Success",
"data": {"id": 1, "name": "Alice"},
"timestamp": "2024-01-15T10:30:45.123Z"
}import "github.com/MonkyMars/gecho"
func main() {
// Create logger with defaults
logger := gecho.NewDefaultLogger()
// Log messages
logger.Info("Server starting")
logger.Error("Failed to connect")
// Log with fields
logger.Info("User logged in",
gecho.Field("user_id", 123),
gecho.Field("ip", "192.168.1.1"),
)
}// Custom configuration
config := gecho.NewConfig(
gecho.WithLogLevel(gecho.LevelDebug),
gecho.WithLogFormat(gecho.FormatJSON),
gecho.WithShowCaller(true),
)
logger := gecho.NewLogger(config)
// Change level at runtime
logger.SetLevel(gecho.ParseLogLevel("debug"))WithLogLevel(level Level)- Set minimum log level (default:LevelInfo)WithLogFormat(format Format)- Set output format (default:FormatPretty)WithColorize(bool)- Enable/disable colored output (default: auto-detected)WithShowCaller(bool)- Show/hide file and line number (default:true)WithTimeFormat(string)- Custom time format (default:"2006-01-02 15:04:05.000")WithOutput(io.Writer)- Set output destination (default:os.Stdout)WithErrorOutput(io.Writer)- Set error output destination (default:os.Stderr)WithDefaultCallerSkip(int)- Adjust call stack depth for caller info (default:2)
LevelDebug- Debug messagesLevelInfo- Informational messagesLevelWarn- Warning messagesLevelError- Error messagesLevelFatal- Fatal errors (exits program)
FormatText- Plain text with fieldsFormatJSON- JSON outputFormatPretty- Colored output with parentheses format (default)
// Create logger with persistent fields
requestLogger := logger.WithFields(map[string]any{
"request_id": "abc123",
"user_id": 456,
})
requestLogger.Info("Processing request") // All logs include request_id and user_idfunc main() {
mux := http.NewServeMux()
mux.HandleFunc("/", handler)
logger := gecho.NewDefaultLogger()
loggedHandler := gecho.Handlers.HandleLogging(mux, logger)
http.ListenAndServe(":8080", loggedHandler)
}Logs include method, path, status, duration, and remote address.
func handler(w http.ResponseWriter, r *http.Request) {
// Only allow POST requests
if err := gecho.Handlers.HandleMethod(w, r, http.MethodPost); err != nil {
return // Error response already sent
}
// Handle POST request
}package main
import (
"net/http"
"github.com/MonkyMars/gecho"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/users", getUsers)
logger := gecho.NewDefaultLogger()
loggedHandler := gecho.Handlers.HandleLogging(mux, logger)
http.ListenAndServe(":8080", loggedHandler)
}
func getUsers(w http.ResponseWriter, r *http.Request) {
if err := gecho.Handlers.HandleMethod(w, r, http.MethodGet); err != nil {
return
}
users := []map[string]any{
{"id": 1, "name": "Alice"},
{"id": 2, "name": "Bob"},
}
// Create response and modify before sending
resp := gecho.Success(w, gecho.WithData(map[string]any{"users": users}))
resp.AddData("count", len(users))
resp.Send()
}gecho.go- Main package exportserrors/- Error response functionssuccess/- Success response functionshandlers/- HTTP middleware and utilitiesutils/- Core response builder and logger
Contributions are welcome. Open an issue or pull request with a description and tests for changes.
This library is provided as-is. Breaking changes may occur between versions.