Documentation
¶
Overview ¶
Package logging provides utilities for configuring structured logging in web applications.
The package simplifies logger setup by automatically configuring the default slog logger based on the application's environment. It selects appropriate log handlers (Text for local development, JSON for test/production) and log levels (DEBUG in verbose mode, INFO otherwise).
Basic usage:
cfg := config.ServerConfig{
Environment: config.Production,
VerboseMode: false,
}
logging.SetDefaultLogger(cfg)
// Now use slog throughout your application
slog.Info("application started", "port", 8080)
Environment-specific behavior:
- Local: Text handler for human-readable logs during development
- Test/Production: JSON handler for structured log aggregation
Verbose mode:
- false: INFO level and above
- true: DEBUG level and above (includes all debug messages)
Concurrency:
SetDefaultLogger is NOT safe for concurrent use. It should be called once during application initialization before spawning goroutines that use slog. After initialization, the configured logger is safe for concurrent use across goroutines.
Integration with log/slog:
This package configures the default logger used by slog.Info, slog.Debug, and other top-level slog functions via slog.SetDefault(). All standard slog functionality is available after configuration.
Example ¶
Example demonstrates basic logging configuration for a web application.
package main
import (
"fmt"
"github.com/harrydayexe/GoWebUtilities/config"
"github.com/harrydayexe/GoWebUtilities/logging"
)
func main() {
// Configure logging based on environment
cfg := config.ServerConfig{
Environment: config.Local,
VerboseMode: false,
}
logging.SetDefaultLogger(cfg)
// Now use slog throughout your application
// Note: Actual log output is suppressed for test output
fmt.Println("Logging configured for local development")
fmt.Println("Handler: Text format")
fmt.Println("Level: INFO")
}
Output: Logging configured for local development Handler: Text format Level: INFO
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func SetDefaultLogger ¶
func SetDefaultLogger(cfg config.ServerConfig)
SetDefaultLogger configures the default slog logger based on the provided ServerConfig. It sets the global default logger used by slog.Info, slog.Debug, and other top-level slog functions.
The function configures two aspects:
- Log level: DEBUG if cfg.VerboseMode is true, otherwise INFO
- Handler type: Text for Local environment, JSON for Test/Production
Log handlers write to os.Stdout. All log output includes timestamps and context fields.
This function is NOT safe for concurrent use and modifies global state via slog.SetDefault. Call it once during application initialization (e.g., in main(), before starting the server) before any goroutines that use logging are spawned.
Example:
cfg, _ := config.ParseConfig[config.ServerConfig]()
logging.SetDefaultLogger(cfg)
slog.Info("server starting", "environment", cfg.Environment)
Example ¶
ExampleSetDefaultLogger demonstrates typical usage of SetDefaultLogger.
package main
import (
"fmt"
"github.com/harrydayexe/GoWebUtilities/config"
"github.com/harrydayexe/GoWebUtilities/logging"
)
func main() {
// Create configuration
cfg := config.ServerConfig{
Environment: config.Production,
VerboseMode: false,
Port: 8080,
}
// Configure the default logger
logging.SetDefaultLogger(cfg)
// The default logger is now configured and ready to use
// All slog.* calls will use this configuration
fmt.Println("Production logging configured")
fmt.Println("Ready to use slog.Info(), slog.Debug(), etc.")
}
Output: Production logging configured Ready to use slog.Info(), slog.Debug(), etc.
Example (ContextualLogging) ¶
ExampleSetDefaultLogger_contextualLogging demonstrates using context with logging.
package main
import (
"context"
"fmt"
"io"
"log/slog"
"github.com/harrydayexe/GoWebUtilities/config"
"github.com/harrydayexe/GoWebUtilities/logging"
)
func main() {
cfg := config.ServerConfig{
Environment: config.Production,
VerboseMode: false,
}
logging.SetDefaultLogger(cfg)
// Suppress actual log output for example (do this after SetDefaultLogger)
slog.SetDefault(slog.New(slog.NewJSONHandler(io.Discard, nil)))
// Use context for request tracking
ctx := context.Background()
// Log with context information (suppressed)
logger := slog.Default().With(
"request_id", "req-123",
"user_id", "user-456",
)
logger.InfoContext(ctx, "processing request")
fmt.Println("Contextual logging enabled")
fmt.Println("Each log includes:")
fmt.Println("- Request ID")
fmt.Println("- User ID")
fmt.Println("- Timestamp")
fmt.Println("- Log level")
}
Output: Contextual logging enabled Each log includes: - Request ID - User ID - Timestamp - Log level
Example (ErrorHandling) ¶
ExampleSetDefaultLogger_errorHandling demonstrates logging configuration with error handling.
package main
import (
"fmt"
"io"
"log/slog"
"github.com/harrydayexe/GoWebUtilities/config"
"github.com/harrydayexe/GoWebUtilities/logging"
)
func main() {
// Suppress actual log output for example
slog.SetDefault(slog.New(slog.NewJSONHandler(io.Discard, nil)))
// Parse config with error handling
cfg := config.ServerConfig{
Environment: config.Production,
VerboseMode: false,
}
// Configure logger
logging.SetDefaultLogger(cfg)
// Use structured logging for errors
if err := someOperation(); err != nil {
slog.Error("operation failed",
"error", err,
"operation", "someOperation",
)
}
fmt.Println("Structured error logging configured")
fmt.Println("Errors include context and details")
}
// someOperation is a helper function for the example
func someOperation() error {
return nil
}
Output: Structured error logging configured Errors include context and details
Example (FullApplication) ¶
ExampleSetDefaultLogger_fullApplication demonstrates a complete application setup.
package main
import (
"fmt"
"io"
"log/slog"
"net/http"
"github.com/harrydayexe/GoWebUtilities/config"
"github.com/harrydayexe/GoWebUtilities/logging"
)
func main() {
// Step 1: Parse configuration
cfg := config.ServerConfig{
Environment: config.Production,
VerboseMode: false,
Port: 8080,
}
// Step 2: Configure logging early in application startup
logging.SetDefaultLogger(cfg)
// Suppress actual log output for example (do this after SetDefaultLogger)
slog.SetDefault(slog.New(slog.NewJSONHandler(io.Discard, nil)))
// Step 3: Log application startup (suppressed)
slog.Info("application starting",
"environment", cfg.Environment,
"port", cfg.Port,
"verbose", cfg.VerboseMode,
)
// Step 4: Create HTTP handlers
mux := http.NewServeMux()
mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("OK"))
})
// Step 5: Create server (note: this parses config from env, may log)
// In production, you would call server.Run() here
fmt.Println("Application configured with server and logging")
fmt.Println("Logging ready for:")
fmt.Println("- Application events")
fmt.Println("- Request processing")
fmt.Println("- Error tracking")
}
Output: Application configured with server and logging Logging ready for: - Application events - Request processing - Error tracking
Example (Local) ¶
ExampleSetDefaultLogger_local demonstrates local development logging configuration.
package main
import (
"fmt"
"github.com/harrydayexe/GoWebUtilities/config"
"github.com/harrydayexe/GoWebUtilities/logging"
)
func main() {
cfg := config.ServerConfig{
Environment: config.Local,
VerboseMode: false,
}
logging.SetDefaultLogger(cfg)
// Local environment uses text handler for human-readable logs
// Perfect for development and debugging
fmt.Println("Local development logging:")
fmt.Println("- Text format (human-readable)")
fmt.Println("- INFO level and above")
fmt.Println("- Output to stdout")
}
Output: Local development logging: - Text format (human-readable) - INFO level and above - Output to stdout
Example (Production) ¶
ExampleSetDefaultLogger_production demonstrates production logging configuration.
package main
import (
"fmt"
"github.com/harrydayexe/GoWebUtilities/config"
"github.com/harrydayexe/GoWebUtilities/logging"
)
func main() {
cfg := config.ServerConfig{
Environment: config.Production,
VerboseMode: false,
}
logging.SetDefaultLogger(cfg)
// Production environment uses JSON handler for structured logging
// Ideal for log aggregation and analysis
fmt.Println("Production logging:")
fmt.Println("- JSON format (structured)")
fmt.Println("- INFO level and above")
fmt.Println("- Ready for log aggregation systems")
}
Output: Production logging: - JSON format (structured) - INFO level and above - Ready for log aggregation systems
Example (Verbose) ¶
ExampleSetDefaultLogger_verbose demonstrates verbose debug logging.
package main
import (
"fmt"
"github.com/harrydayexe/GoWebUtilities/config"
"github.com/harrydayexe/GoWebUtilities/logging"
)
func main() {
cfg := config.ServerConfig{
Environment: config.Production,
VerboseMode: true,
}
logging.SetDefaultLogger(cfg)
// Verbose mode enables DEBUG level logging
// Useful for troubleshooting and detailed diagnostics
fmt.Println("Verbose logging enabled:")
fmt.Println("- DEBUG level and above")
fmt.Println("- Includes detailed diagnostic information")
fmt.Println("- Use for troubleshooting")
}
Output: Verbose logging enabled: - DEBUG level and above - Includes detailed diagnostic information - Use for troubleshooting
Example (WithMiddleware) ¶
ExampleSetDefaultLogger_withMiddleware demonstrates logging with middleware stack.
package main
import (
"fmt"
"io"
"log/slog"
"net/http"
"os"
"github.com/harrydayexe/GoWebUtilities/config"
"github.com/harrydayexe/GoWebUtilities/logging"
"github.com/harrydayexe/GoWebUtilities/middleware"
)
func main() {
// Configure application-level logging
cfg := config.ServerConfig{
Environment: config.Production,
VerboseMode: false,
}
logging.SetDefaultLogger(cfg)
// Suppress actual log output for example
slog.SetDefault(slog.New(slog.NewJSONHandler(io.Discard, nil)))
// Create request-specific logger for middleware
requestLogger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
Level: slog.LevelInfo,
}))
// Create middleware stack with logging
stack := middleware.CreateStack(
middleware.NewLoggingMiddleware(requestLogger),
middleware.NewSetContentTypeJSON(),
)
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Use default logger in handlers
slog.Info("processing request", "endpoint", r.URL.Path)
w.Write([]byte(`{"status":"ok"}`))
})
_ = stack(handler)
fmt.Println("Application configured with:")
fmt.Println("- Default logger for application events")
fmt.Println("- Request logger for HTTP middleware")
fmt.Println("- Structured JSON logging throughout")
}
Output: Application configured with: - Default logger for application events - Request logger for HTTP middleware - Structured JSON logging throughout
Example (WithServer) ¶
ExampleSetDefaultLogger_withServer demonstrates logging configuration with server startup.
package main
import (
"fmt"
"io"
"log/slog"
"net/http"
"github.com/harrydayexe/GoWebUtilities/config"
"github.com/harrydayexe/GoWebUtilities/logging"
)
func main() {
// Parse configuration from environment
cfg := config.ServerConfig{
Environment: config.Production,
VerboseMode: false,
Port: 8080,
}
// Configure logging before starting server
logging.SetDefaultLogger(cfg)
// Suppress actual log output for example
slog.SetDefault(slog.New(slog.NewJSONHandler(io.Discard, nil)))
// Create HTTP handler
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// Use structured logging in handlers
slog.Info("handling request", "path", r.URL.Path, "method", r.Method)
w.Write([]byte("OK"))
})
// Server will use the configured logger
fmt.Println("Application startup sequence:")
fmt.Println("1. Parse configuration")
fmt.Println("2. Configure logging")
fmt.Println("3. Set up HTTP handlers")
fmt.Println("4. Start server")
}
Output: Application startup sequence: 1. Parse configuration 2. Configure logging 3. Set up HTTP handlers 4. Start server
Types ¶
This section is empty.