diff --git a/pkg/config/config.go b/pkg/config/config.go index 1c6f9c2..9fcb11f 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -10,6 +10,7 @@ import ( "flag" "fmt" "os" + "regexp" "runtime/debug" "time" @@ -105,6 +106,12 @@ func prepareConfig(cfg *AppConfig) error { } } + // Prepare user-provided expressions, panic up-front if invalid + cfg.HTTP.excludeRegexps = make([]*regexp.Regexp, len(cfg.HTTP.LogExcludePathRegexps)) + for i, re := range cfg.HTTP.LogExcludePathRegexps { + cfg.HTTP.excludeRegexps[i] = regexp.MustCompile(re) + } + return errs } diff --git a/pkg/config/types_http.go b/pkg/config/types_http.go index 0190239..fefc17b 100644 --- a/pkg/config/types_http.go +++ b/pkg/config/types_http.go @@ -1,6 +1,10 @@ package config -import "time" +import ( + "regexp" + "sync" + "time" +) var defaultHTTPConfig = &HTTPConfig{ Enabled: true, @@ -14,13 +18,23 @@ var defaultHTTPConfig = &HTTPConfig{ // HTTPConfig provides HTTP server Configuration type HTTPConfig struct { - Enabled bool `yaml:"enabled" env:"APP_HTTP_ENABLED" json:"enabled,omitempty"` - Listen string `yaml:"listen,omitempty" env:"APP_HTTP_LISTEN" json:"listen,omitempty"` - LogRequests bool `yaml:"logRequests" env:"APP_HTTP_LOG_REQUESTS" json:"logRequests,omitempty"` - ReadTimeout string `yaml:"readTimeout" env:"APP_HTTP_READ_TIMEOUT" json:"readTimeout,omitempty"` // Go duration (e.g. 10s) - WriteTimeout string `yaml:"writeTimeout" env:"APP_HTTP_WRITE_TIMEOUT" json:"writeTimeout,omitempty"` // Go duration (e.g. 10s) - IdleTimeout string `yaml:"idleTimeout" env:"APP_HTTP_IDLE_TIMEOUT" json:"idleTimeout,omitempty"` // Go duration (e.g. 10s) - rT *time.Duration - wT *time.Duration - iT *time.Duration + Enabled bool `yaml:"enabled" env:"APP_HTTP_ENABLED" json:"enabled,omitempty"` + Listen string `yaml:"listen,omitempty" env:"APP_HTTP_LISTEN" json:"listen,omitempty"` + LogRequests bool `yaml:"logRequests" env:"APP_HTTP_LOG_REQUESTS" json:"logRequests,omitempty"` + LogExcludePathRegexps []string `yaml:"logExcludePathRegexps" env:"APP_HTTP_LOG_EXCLUDE_PATH_REGEXPS" json:"logExcludePathRegexps,omitempty"` + ReadTimeout string `yaml:"readTimeout" env:"APP_HTTP_READ_TIMEOUT" json:"readTimeout,omitempty"` // Go duration (e.g. 10s) + WriteTimeout string `yaml:"writeTimeout" env:"APP_HTTP_WRITE_TIMEOUT" json:"writeTimeout,omitempty"` // Go duration (e.g. 10s) + IdleTimeout string `yaml:"idleTimeout" env:"APP_HTTP_IDLE_TIMEOUT" json:"idleTimeout,omitempty"` // Go duration (e.g. 10s) + excludeRegexps []*regexp.Regexp + rT *time.Duration + wT *time.Duration + iT *time.Duration + lock sync.RWMutex +} + +func (h *HTTPConfig) GetExcludeRegexps() []*regexp.Regexp { + h.lock.RLock() + defer h.lock.RUnlock() + + return h.excludeRegexps } diff --git a/pkg/srv/http/http_log.go b/pkg/srv/http/http_log.go index cb05005..f15a6a2 100644 --- a/pkg/srv/http/http_log.go +++ b/pkg/srv/http/http_log.go @@ -10,6 +10,8 @@ import ( "time" "github.com/rs/zerolog" + + "gitea.libretechconsulting.com/rmcguire/go-app/pkg/config" ) var ExcludeFromLogging = regexp.MustCompile(`\/(ready|live|metrics)$`) @@ -21,12 +23,22 @@ type LoggingResponseWriter struct { } func loggingMiddleware(appCtx context.Context, next http.Handler) http.Handler { + appConfig := config.MustFromCtx(appCtx) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if ExcludeFromLogging.Match([]byte(r.URL.Path)) { next.ServeHTTP(w, r) return } + // User-configurable logging exclusions + for _, re := range appConfig.HTTP.GetExcludeRegexps() { + if re.MatchString(r.URL.Path) { + next.ServeHTTP(w, r) + return + } + } + log := zerolog.Ctx(appCtx) start := time.Now()