diff options
author | Francis Lavoie <[email protected]> | 2024-02-10 02:31:11 -0500 |
---|---|---|
committer | Francis Lavoie <[email protected]> | 2024-04-15 15:10:05 -0400 |
commit | 24c180a6729ef6b812c9b311fff82421517b53c7 (patch) | |
tree | ef0db9e6e1faf1483bcfe12f28f62f6647eda64c | |
parent | b21921d090358ac7ce096c78736cf21b4c576751 (diff) | |
download | caddy-24c180a6729ef6b812c9b311fff82421517b53c7.tar.gz caddy-24c180a6729ef6b812c9b311fff82421517b53c7.zip |
Implement "string or array" parsing, keep original `logger_names`
10 files changed, 62 insertions, 60 deletions
diff --git a/caddyconfig/httpcaddyfile/httptype.go b/caddyconfig/httpcaddyfile/httptype.go index 0d961b2de..ab1012939 100644 --- a/caddyconfig/httpcaddyfile/httptype.go +++ b/caddyconfig/httpcaddyfile/httptype.go @@ -804,10 +804,10 @@ func (st *ServerType) serversFromPairings( } else if len(ncl.hostnames) > 0 { // if the logger overrides the hostnames, map that to the logger name for _, h := range ncl.hostnames { - if srv.Logs.LoggerMapping == nil { - srv.Logs.LoggerMapping = make(map[string][]string) + if srv.Logs.LoggerNames == nil { + srv.Logs.LoggerNames = make(map[string]caddyhttp.StringArray) } - srv.Logs.LoggerMapping[h] = append(srv.Logs.LoggerMapping[h], ncl.name) + srv.Logs.LoggerNames[h] = append(srv.Logs.LoggerNames[h], ncl.name) } } else { // otherwise, map each host to the logger name @@ -817,10 +817,10 @@ func (st *ServerType) serversFromPairings( if err != nil { host = h } - if srv.Logs.LoggerMapping == nil { - srv.Logs.LoggerMapping = make(map[string][]string) + if srv.Logs.LoggerNames == nil { + srv.Logs.LoggerNames = make(map[string]caddyhttp.StringArray) } - srv.Logs.LoggerMapping[host] = append(srv.Logs.LoggerMapping[host], ncl.name) + srv.Logs.LoggerNames[host] = append(srv.Logs.LoggerNames[host], ncl.name) } } } diff --git a/caddytest/integration/caddyfile_adapt/import_args_snippet.caddyfiletest b/caddytest/integration/caddyfile_adapt/import_args_snippet.caddyfiletest index 109fb4cff..9d5c25352 100644 --- a/caddytest/integration/caddyfile_adapt/import_args_snippet.caddyfiletest +++ b/caddytest/integration/caddyfile_adapt/import_args_snippet.caddyfiletest @@ -71,7 +71,7 @@ b.example.com { } ], "logs": { - "logger_mapping": { + "logger_names": { "a.example.com": [ "log0" ], diff --git a/caddytest/integration/caddyfile_adapt/log_except_catchall_blocks.caddyfiletest b/caddytest/integration/caddyfile_adapt/log_except_catchall_blocks.caddyfiletest index 332fa3d11..b2a7f2afc 100644 --- a/caddytest/integration/caddyfile_adapt/log_except_catchall_blocks.caddyfiletest +++ b/caddytest/integration/caddyfile_adapt/log_except_catchall_blocks.caddyfiletest @@ -98,7 +98,7 @@ http://localhost:2020 { ] }, "logs": { - "logger_mapping": { + "logger_names": { "localhost": [ "" ] diff --git a/caddytest/integration/caddyfile_adapt/log_multi_logger_name.caddyfiletest b/caddytest/integration/caddyfile_adapt/log_multi_logger_name.caddyfiletest index 153d46b41..3127d4b2b 100644 --- a/caddytest/integration/caddyfile_adapt/log_multi_logger_name.caddyfiletest +++ b/caddytest/integration/caddyfile_adapt/log_multi_logger_name.caddyfiletest @@ -60,7 +60,7 @@ } ], "logs": { - "logger_mapping": { + "logger_names": { "bar.example.com": [ "json" ], diff --git a/caddytest/integration/caddyfile_adapt/log_override_hostname.caddyfiletest b/caddytest/integration/caddyfile_adapt/log_override_hostname.caddyfiletest index 76162d522..b9213e65a 100644 --- a/caddytest/integration/caddyfile_adapt/log_override_hostname.caddyfiletest +++ b/caddytest/integration/caddyfile_adapt/log_override_hostname.caddyfiletest @@ -74,7 +74,7 @@ example.com:8443 { } ], "logs": { - "logger_mapping": { + "logger_names": { "bar.example.com": [ "log0" ], @@ -104,7 +104,7 @@ example.com:8443 { } ], "logs": { - "logger_mapping": { + "logger_names": { "example.com": [ "log2" ] diff --git a/caddytest/integration/caddyfile_adapt/log_override_name_multiaccess.caddyfiletest b/caddytest/integration/caddyfile_adapt/log_override_name_multiaccess.caddyfiletest index ddb742676..2708503e5 100644 --- a/caddytest/integration/caddyfile_adapt/log_override_name_multiaccess.caddyfiletest +++ b/caddytest/integration/caddyfile_adapt/log_override_name_multiaccess.caddyfiletest @@ -75,7 +75,7 @@ http://localhost:8881 { ] }, "logs": { - "logger_mapping": { + "logger_names": { "localhost": [ "foo" ] diff --git a/caddytest/integration/caddyfile_adapt/log_override_name_multiaccess_debug.caddyfiletest b/caddytest/integration/caddyfile_adapt/log_override_name_multiaccess_debug.caddyfiletest index 5a1002e23..7ea659789 100644 --- a/caddytest/integration/caddyfile_adapt/log_override_name_multiaccess_debug.caddyfiletest +++ b/caddytest/integration/caddyfile_adapt/log_override_name_multiaccess_debug.caddyfiletest @@ -80,7 +80,7 @@ http://localhost:8881 { ] }, "logs": { - "logger_mapping": { + "logger_names": { "localhost": [ "foo" ] diff --git a/caddytest/integration/caddyfile_adapt/log_skip_hosts.caddyfiletest b/caddytest/integration/caddyfile_adapt/log_skip_hosts.caddyfiletest index b21af2b0a..c10610c2e 100644 --- a/caddytest/integration/caddyfile_adapt/log_skip_hosts.caddyfiletest +++ b/caddytest/integration/caddyfile_adapt/log_skip_hosts.caddyfiletest @@ -62,7 +62,7 @@ example.com { } ], "logs": { - "logger_mapping": { + "logger_names": { "one.example.com": [ "" ] diff --git a/modules/caddyhttp/logging.go b/modules/caddyhttp/logging.go index 9930be6bc..313f12e12 100644 --- a/modules/caddyhttp/logging.go +++ b/modules/caddyhttp/logging.go @@ -15,6 +15,7 @@ package caddyhttp import ( + "encoding/json" "errors" "net" "net/http" @@ -32,31 +33,25 @@ import ( // customized per-request-host. type ServerLogConfig struct { // The default logger name for all logs emitted by this server for - // hostnames that are not in logger_names or logger_mapping. + // hostnames that are not in the 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". - // DEPRECATED: Use LoggerMapping instead. - LoggerNames map[string]string `json:"logger_names,omitempty"` - - // LoggerMapping maps request hostnames to one or more 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". If - // there are multiple logger names, then the log will be emitted - // to all of them. - LoggerMapping map[string][]string `json:"logger_mapping,omitempty"` + // LoggerNames maps request hostnames to one or more custom logger + // names. 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". If there are + // multiple logger names, then the log will be emitted to all of them. + // For backwards compatibility, if the value is a string, it is treated + // as a single-element array. + LoggerNames map[string]StringArray `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 - // logger_names or logger_mapping will not be logged. + // If true, requests to any host not appearing in the + // logger_names map will not be logged. SkipUnmappedHosts bool `json:"skip_unmapped_hosts,omitempty"` // If true, credentials that are otherwise omitted, will be logged. @@ -83,7 +78,7 @@ func (slc ServerLogConfig) wrapLogger(logger *zap.Logger, host string) []*zap.Lo func (slc ServerLogConfig) getLoggerHosts(host string) []string { tryHost := func(key string) ([]string, bool) { // first try exact match - if hosts, ok := slc.LoggerMapping[key]; ok { + if hosts, ok := slc.LoggerNames[key]; ok { return hosts, ok } // strip port and try again (i.e. Host header of "example.com:1234" should @@ -92,24 +87,8 @@ func (slc ServerLogConfig) getLoggerHosts(host string) []string { if err != nil { return []string{}, false } - if hosts, ok := slc.LoggerMapping[hostOnly]; ok { - return hosts, ok - } - - // Now try the deprecated LoggerNames - - // first try exact match - if host, ok := slc.LoggerNames[key]; ok { - return []string{host}, ok - } - // strip port and try again (i.e. Host header of "example.com:1234" should - // match "example.com" if there is no "example.com:1234" in the map) - hostOnly, _, err = net.SplitHostPort(key) - if err != nil { - return []string{}, false - } - host, ok := slc.LoggerNames[hostOnly] - return []string{host}, ok + hosts, ok := slc.LoggerNames[hostOnly] + return hosts, ok } // try the exact hostname first @@ -136,21 +115,48 @@ func (slc ServerLogConfig) getLoggerHosts(host string) []string { func (slc *ServerLogConfig) clone() *ServerLogConfig { clone := &ServerLogConfig{ DefaultLoggerName: slc.DefaultLoggerName, - LoggerNames: make(map[string]string), - LoggerMapping: make(map[string][]string), + LoggerNames: make(map[string]StringArray), SkipHosts: append([]string{}, slc.SkipHosts...), SkipUnmappedHosts: slc.SkipUnmappedHosts, ShouldLogCredentials: slc.ShouldLogCredentials, } for k, v := range slc.LoggerNames { - clone.LoggerNames[k] = v - } - for k, v := range slc.LoggerMapping { - clone.LoggerMapping[k] = append([]string{}, v...) + clone.LoggerNames[k] = append([]string{}, v...) } return clone } +// StringArray is a slices of strings, but also accepts +// a single string as a value when JSON unmarshaling, +// converting it to a slice of one string. +type StringArray []string + +// UnmarshalJSON satisfies json.Unmarshaler. +func (sa *StringArray) UnmarshalJSON(b []byte) error { + var jsonObj any + err := json.Unmarshal(b, &jsonObj) + if err != nil { + return err + } + switch obj := jsonObj.(type) { + case string: + *sa = StringArray([]string{obj}) + return nil + case []any: + s := make([]string, 0, len(obj)) + for _, v := range obj { + value, ok := v.(string) + if !ok { + return errors.New("unsupported type") + } + s = append(s, value) + } + *sa = StringArray(s) + return nil + } + return errors.New("unsupported type") +} + // errLogValues inspects err and returns the status code // to use, the error log message, and any extra fields. // If err is a HandlerError, the returned values will diff --git a/modules/caddyhttp/server.go b/modules/caddyhttp/server.go index 7c68a1740..0e88ef26d 100644 --- a/modules/caddyhttp/server.go +++ b/modules/caddyhttp/server.go @@ -712,10 +712,6 @@ func (s *Server) shouldLogRequest(r *http.Request) bool { // logging is disabled return false } - if _, ok := s.Logs.LoggerMapping[r.Host]; ok { - // this host is mapped to a particular logger name - return true - } if _, ok := s.Logs.LoggerNames[r.Host]; ok { // this host is mapped to a particular logger name return true |