caddyhttp: General improvements to access logging (#3301)

* httpcaddyfile: Exclude access logs written to files from default log

Even though any logs can just be ignored, most users don't seem to like
configuring an access log to go to a file only to have it doubly appear
in the default log.

Related to:
- #3294
- https://caddy.community/t/v2-logging-format/7642/4?u=matt
- https://caddy.community/t/caddyfile-questions/7651/3?u=matt

* caddyhttp: General improvements to access log controls (fixes #3310)

* caddyhttp: Move log config nil check higher

* Rename LoggerName -> DefaultLoggerName
This commit is contained in:
Matt Holt
2020-04-28 08:32:04 -06:00
committed by GitHub
parent c11d0e47a3
commit 10db57027d
2 changed files with 106 additions and 34 deletions

View File

@ -101,9 +101,9 @@ type Server struct {
// client authentication.
StrictSNIHost *bool `json:"strict_sni_host,omitempty"`
// Customizes how access logs are handled in this server. To
// minimally enable access logs, simply set this to a non-null,
// empty struct.
// Enables access logging and configures how access logs are handled
// in this server. To minimally enable access logs, simply set this
// to a non-null, empty struct.
Logs *ServerLogConfig `json:"logs,omitempty"`
// Enable experimental HTTP/3 support. Note that HTTP/3 is not a
@ -157,7 +157,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
loggableReq,
)
if s.accessLogger != nil {
if s.shouldLogRequest(r) {
wrec := NewResponseRecorder(w, nil, nil)
w = wrec
@ -390,17 +390,52 @@ func (*HTTPErrorConfig) WithError(r *http.Request, err error) *http.Request {
return r
}
// ServerLogConfig describes a server's logging configuration.
// shouldLogRequest returns true if this request should be logged.
func (s *Server) shouldLogRequest(r *http.Request) bool {
if s.accessLogger == nil || s.Logs == nil {
// logging is disabled
return false
}
for _, dh := range s.Logs.SkipHosts {
// logging for this particular host is disabled
if r.Host == dh {
return false
}
}
if _, ok := s.Logs.LoggerNames[r.Host]; ok {
// this host is mapped to a particular logger name
return true
}
if s.Logs.SkipUnmappedHosts {
// this host is not mapped and thus must not be logged
return false
}
return true
}
// ServerLogConfig describes a server's logging configuration. If
// enabled without customization, all requests to this server are
// logged to the default logger; logger destinations may be
// customized per-request-host.
type ServerLogConfig struct {
// The logger name for all logs emitted by this server unless
// the hostname is found in the LoggerNames (logger_names) map.
LoggerName string `json:"log_name,omitempty"`
// The default logger name for all logs emitted by this server for
// hostnames that are not in the LoggerNames (logger_names) map.
DefaultLoggerName string `json:"default_logger_name,omitempty"`
// LoggerNames maps request hostnames to a custom logger name.
// For example, a mapping of "example.com" to "example" would
// cause access logs from requests with a Host of example.com
// to be emitted by a logger named "http.log.access.example".
LoggerNames map[string]string `json:"logger_names,omitempty"`
// By default, all requests to this server will be logged if
// access logging is enabled. This field lists the request
// hosts for which access logging should be disabled.
SkipHosts []string `json:"skip_hosts,omitempty"`
// If true, requests to any host not appearing in the
// LoggerNames (logger_names) map will not be logged.
SkipUnmappedHosts bool `json:"skip_unmapped_hosts,omitempty"`
}
// wrapLogger wraps logger in a logger named according to user preferences for the given host.
@ -415,7 +450,7 @@ func (slc ServerLogConfig) getLoggerName(host string) string {
if loggerName, ok := slc.LoggerNames[host]; ok {
return loggerName
}
return slc.LoggerName
return slc.DefaultLoggerName
}
// errLogValues inspects err and returns the status code