logging

package
v0.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 7, 2025 License: MIT Imports: 7 Imported by: 0

README

Logging Package

Flexible HTTP request logging middleware with URL filtering and interface-based design.

Features

  • Interface-based design - Custom loggers and URL filters for testing and flexibility
  • Functional configuration - Clean configuration with functional option pattern
  • URL filtering - Filter out specific URLs from logging
  • Customizable - Custom loggers, formatters, and output writers
  • Mock support - Mock loggers and filters for unit testing

Quick Start

package main

import (
    "regexp"
    
    "github.com/go-chi/chi/v5"
    "github.com/Okja-Engineering/go-service-kit/pkg/logging"
)

func main() {
    router := chi.NewRouter()
    
    // Create logger with URL filtering
    logger := logging.NewRequestLogger(
        logging.WithRegexFilter(regexp.MustCompile(`/(health|metrics)`)),
        logging.WithNoColor(true),
    )
    
    // Use in your router
    router.Use(logger.Middleware())
    
    // Your routes
    router.Get("/api/users", handleGetUsers)
    router.Get("/health", handleHealth) // This won't be logged
}

Configuration

Functional Options
// Basic configuration
logger := logging.NewRequestLogger()

// Advanced configuration
logger := logging.NewRequestLogger(
    logging.WithLogger(customLogger),
    logging.WithFormatter(customFormatter),
    logging.WithRegexFilter(regexp.MustCompile(`/health`)),
    logging.WithNoColor(true),
    logging.WithOutput(os.Stderr),
)
Available Options
func WithLogger(logger Logger) LoggingOption
func WithFormatter(formatter middleware.LogFormatter) LoggingOption
func WithURLFilter(filter URLFilter) LoggingOption
func WithRegexFilter(pattern *regexp.Regexp) LoggingOption
func WithNoColor(noColor bool) LoggingOption
func WithOutput(output io.Writer) LoggingOption
Custom Loggers
// Implement the Logger interface
type CustomLogger struct {
    output *bytes.Buffer
}

func (l *CustomLogger) Printf(format string, v ...interface{}) {
    l.output.WriteString(fmt.Sprintf(format, v...))
}

func (l *CustomLogger) Println(v ...interface{}) {
    l.output.WriteString(fmt.Sprintln(v...))
}

// Use custom logger
customLogger := &CustomLogger{output: &bytes.Buffer{}}
logger := logging.NewRequestLogger(logging.WithLogger(customLogger))
Custom URL Filters
// Implement the URLFilter interface
type CustomURLFilter struct {
    excludedPaths []string
}

func (f *CustomURLFilter) ShouldFilter(url string) bool {
    for _, path := range f.excludedPaths {
        if strings.HasPrefix(url, path) {
            return true
        }
    }
    return false
}

// Use custom filter
filter := &CustomURLFilter{excludedPaths: []string{"/health", "/metrics"}}
logger := logging.NewRequestLogger(logging.WithURLFilter(filter))

API Reference

Core Interfaces
type Logger interface {
    Printf(format string, v ...interface{})
    Println(v ...interface{})
}

type URLFilter interface {
    ShouldFilter(url string) bool
}
Request Logger
type RequestLogger struct {
    config *LoggingConfig
}

func NewRequestLogger(options ...LoggingOption) *RequestLogger
func (rl *RequestLogger) Middleware() func(next http.Handler) http.Handler
Configuration
type LoggingConfig struct {
    Logger     Logger
    Formatter  middleware.LogFormatter
    URLFilter  URLFilter
    NoColor    bool
    Output     io.Writer
}

func DefaultLoggingConfig() *LoggingConfig
func NewLoggingConfig(options ...LoggingOption) *LoggingConfig
Built-in Implementations
// RegexURLFilter implements URLFilter using regex patterns
type RegexURLFilter struct {
    pattern *regexp.Regexp
}

func (f *RegexURLFilter) ShouldFilter(url string) bool

Examples

Basic Usage
// Simple usage with defaults
logger := logging.NewRequestLogger()
router.Use(logger.Middleware())
Advanced Configuration
// Custom configuration for production
logger := logging.NewRequestLogger(
    logging.WithRegexFilter(regexp.MustCompile(`/(health|metrics|ready)`)),
    logging.WithNoColor(true),
    logging.WithOutput(os.Stderr),
)

router.Use(logger.Middleware())
Custom Formatter
// Custom log formatter
formatter := &middleware.DefaultLogFormatter{
    Logger:  log.New(os.Stdout, "[API] ", log.LstdFlags),
    NoColor: true,
}

logger := logging.NewRequestLogger(
    logging.WithFormatter(formatter),
    logging.WithRegexFilter(regexp.MustCompile(`/health`)),
)

router.Use(logger.Middleware())
Complete Logging Setup
package main

import (
    "log"
    "os"
    "regexp"
    
    "github.com/go-chi/chi/v5"
    "github.com/Okja-Engineering/go-service-kit/pkg/logging"
)

func main() {
    router := chi.NewRouter()
    
    // Create custom formatter
    formatter := &middleware.DefaultLogFormatter{
        Logger:  log.New(os.Stdout, "[API] ", log.LstdFlags),
        NoColor: false,
    }
    
    // Create logger with filtering
    logger := logging.NewRequestLogger(
        logging.WithFormatter(formatter),
        logging.WithRegexFilter(regexp.MustCompile(`/(health|metrics|ready)`)),
        logging.WithNoColor(false),
    )
    
    // Use in router
    router.Use(logger.Middleware())
    
    // Routes
    router.Get("/health", handleHealth)     // Filtered out
    router.Get("/metrics", handleMetrics)   // Filtered out
    router.Get("/api/users", handleUsers)   // Logged
    router.Post("/api/users", handleCreate) // Logged
}

Testing

Using Mock Loggers
func TestMyFunction(t *testing.T) {
    // Create mock logger
    mockLogger := &MockLogger{output: &bytes.Buffer{}}
    
    // Create logger with mock
    logger := logging.NewRequestLogger(logging.WithLogger(mockLogger))
    
    // Test your function
    middleware := logger.Middleware()
    // ... test middleware
}
Using Mock URL Filters
func TestURLFiltering(t *testing.T) {
    // Create mock filter
    mockFilter := &MockURLFilter{shouldFilter: true}
    
    // Create logger with mock filter
    logger := logging.NewRequestLogger(logging.WithURLFilter(mockFilter))
    
    // Test filtering behavior
    middleware := logger.Middleware()
    // ... test middleware
}
Mock Implementations
type MockLogger struct {
    output *bytes.Buffer
}

func (m *MockLogger) Printf(format string, v ...interface{}) {
    m.output.WriteString(format)
}

func (m *MockLogger) Println(v ...interface{}) {
    m.output.WriteString("log")
}

type MockURLFilter struct {
    shouldFilter bool
}

func (m *MockURLFilter) ShouldFilter(url string) bool {
    return m.shouldFilter
}

Best Practices

  1. Filter noisy endpoints - Filter out health checks, metrics, and other noisy endpoints
  2. Use appropriate output - Use stderr for logs in production
  3. Create once, reuse - Create logger instance once and reuse throughout your application
  4. Use mock loggers for testing - Test your logging behavior with mock loggers
  5. Configure formatters appropriately - Use structured logging for production environments

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FilteredRequestLogger

func FilteredRequestLogger(f middleware.LogFormatter, urlRegEx *regexp.Regexp) func(next http.Handler) http.Handler

FilteredRequestLogger is a copy of the middleware.RequestLogger function - But with a reg-ex to filter & exclude URLs from logging

func NewFilteredRequestLogger

func NewFilteredRequestLogger(filterOut *regexp.Regexp) func(next http.Handler) http.Handler

Legacy functions for backward compatibility

Types

type Logger added in v0.0.3

type Logger interface {
	Printf(format string, v ...interface{})
	Println(v ...interface{})
}

Logger defines the interface for logging operations

type LoggingConfig added in v0.0.3

type LoggingConfig struct {
	Logger    Logger
	Formatter middleware.LogFormatter
	URLFilter URLFilter
	NoColor   bool
	Output    io.Writer
}

LoggingConfig holds configuration for request logging

func DefaultLoggingConfig added in v0.0.3

func DefaultLoggingConfig() *LoggingConfig

DefaultLoggingConfig provides sensible defaults

func NewLoggingConfig added in v0.0.3

func NewLoggingConfig(options ...LoggingOption) *LoggingConfig

NewLoggingConfig creates a new logging config with options

type LoggingOption added in v0.0.3

type LoggingOption func(*LoggingConfig)

LoggingOption is a functional option for logging configuration

func WithFormatter added in v0.0.3

func WithFormatter(formatter middleware.LogFormatter) LoggingOption

WithFormatter sets a custom log formatter

func WithLogger added in v0.0.3

func WithLogger(logger Logger) LoggingOption

WithLogger sets a custom logger

func WithNoColor added in v0.0.3

func WithNoColor(noColor bool) LoggingOption

WithNoColor disables color output

func WithOutput added in v0.0.3

func WithOutput(output io.Writer) LoggingOption

WithOutput sets the output writer

func WithRegexFilter added in v0.0.3

func WithRegexFilter(pattern *regexp.Regexp) LoggingOption

WithRegexFilter sets a regex-based URL filter

func WithURLFilter added in v0.0.3

func WithURLFilter(filter URLFilter) LoggingOption

WithURLFilter sets a custom URL filter

type RegexURLFilter added in v0.0.3

type RegexURLFilter struct {
	// contains filtered or unexported fields
}

RegexURLFilter implements URLFilter using regex patterns

func (*RegexURLFilter) ShouldFilter added in v0.0.3

func (f *RegexURLFilter) ShouldFilter(url string) bool

ShouldFilter checks if the URL should be filtered

type RequestLogger added in v0.0.3

type RequestLogger struct {
	// contains filtered or unexported fields
}

RequestLogger handles HTTP request logging with configuration

func NewRequestLogger added in v0.0.3

func NewRequestLogger(options ...LoggingOption) *RequestLogger

NewRequestLogger creates a new request logger with options

func (*RequestLogger) Middleware added in v0.0.3

func (rl *RequestLogger) Middleware() func(next http.Handler) http.Handler

Middleware returns the logging middleware function

type URLFilter added in v0.0.3

type URLFilter interface {
	ShouldFilter(url string) bool
}

URLFilter defines the interface for URL filtering

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL