mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-30 17:53:21 -04:00 
			
		
		
		
	plugin/log: support multi nameScope (#2420)
This commit is contained in:
		| @@ -23,10 +23,10 @@ log | ||||
| Or if you want/need slightly more control: | ||||
|  | ||||
| ~~~ txt | ||||
| log [NAME] [FORMAT] | ||||
| log [NAMES...] [FORMAT] | ||||
| ~~~ | ||||
|  | ||||
| * `NAME` is the name to match in order to be logged | ||||
| * `NAMES` is the name list to match in order to be logged | ||||
| * `FORMAT` is the log format to use (default is Common Log Format), `{common}` is used as a shortcut | ||||
|   for the Common Log Format. You can also use `{combined}` for a format that adds the query opcode | ||||
|   `{>opcode}` to the Common Log Format. | ||||
| @@ -34,7 +34,7 @@ log [NAME] [FORMAT] | ||||
| You can further specify the classes of responses that get logged: | ||||
|  | ||||
| ~~~ txt | ||||
| log [NAME] [FORMAT] { | ||||
| log [NAMES...] [FORMAT] { | ||||
|     class CLASSES... | ||||
| } | ||||
| ~~~ | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| package log | ||||
|  | ||||
| import ( | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/coredns/coredns/core/dnsserver" | ||||
| 	"github.com/coredns/coredns/plugin" | ||||
| 	"github.com/coredns/coredns/plugin/pkg/response" | ||||
| @@ -34,62 +36,75 @@ func logParse(c *caddy.Controller) ([]Rule, error) { | ||||
|  | ||||
| 	for c.Next() { | ||||
| 		args := c.RemainingArgs() | ||||
| 		length := len(rules) | ||||
|  | ||||
| 		if len(args) == 0 { | ||||
| 		switch len(args) { | ||||
| 		case 0: | ||||
| 			// Nothing specified; use defaults | ||||
| 			rules = append(rules, Rule{ | ||||
| 				NameScope: ".", | ||||
| 				Format:    DefaultLogFormat, | ||||
| 				Class:     make(map[response.Class]struct{}), | ||||
| 			}) | ||||
| 		} else if len(args) == 1 { | ||||
| 		case 1: | ||||
| 			rules = append(rules, Rule{ | ||||
| 				NameScope: dns.Fqdn(args[0]), | ||||
| 				Format:    DefaultLogFormat, | ||||
| 				Class:     make(map[response.Class]struct{}), | ||||
| 			}) | ||||
| 		} else { | ||||
| 			// Name scope, and maybe a format specified | ||||
| 		default: | ||||
| 			// Name scopes, and maybe a format specified | ||||
| 			format := DefaultLogFormat | ||||
|  | ||||
| 			switch args[1] { | ||||
| 			case "{common}": | ||||
| 				format = CommonLogFormat | ||||
| 			case "{combined}": | ||||
| 				format = CombinedLogFormat | ||||
| 			default: | ||||
| 				format = args[1] | ||||
| 			if strings.Contains(args[len(args)-1], "{") { | ||||
| 				switch args[len(args)-1] { | ||||
| 				case "{common}": | ||||
| 					format = CommonLogFormat | ||||
| 				case "{combined}": | ||||
| 					format = CombinedLogFormat | ||||
| 				default: | ||||
| 					format = args[len(args)-1] | ||||
| 				} | ||||
|  | ||||
| 				args = args[:len(args)-1] | ||||
| 			} | ||||
|  | ||||
| 			rules = append(rules, Rule{ | ||||
| 				NameScope: dns.Fqdn(args[0]), | ||||
| 				Format:    format, | ||||
| 				Class:     make(map[response.Class]struct{}), | ||||
| 			}) | ||||
| 			for _, str := range args { | ||||
| 				rules = append(rules, Rule{ | ||||
| 					NameScope: dns.Fqdn(str), | ||||
| 					Format:    format, | ||||
| 					Class:     make(map[response.Class]struct{}), | ||||
| 				}) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		// Class refinements in an extra block. | ||||
| 		classes := make(map[response.Class]struct{}) | ||||
| 		for c.NextBlock() { | ||||
| 			switch c.Val() { | ||||
| 			// class followed by combinations of all, denial, error and success. | ||||
| 			case "class": | ||||
| 				classes := c.RemainingArgs() | ||||
| 				if len(classes) == 0 { | ||||
| 				classesArgs := c.RemainingArgs() | ||||
| 				if len(classesArgs) == 0 { | ||||
| 					return nil, c.ArgErr() | ||||
| 				} | ||||
| 				for _, c := range classes { | ||||
| 				for _, c := range classesArgs { | ||||
| 					cls, err := response.ClassFromString(c) | ||||
| 					if err != nil { | ||||
| 						return nil, err | ||||
| 					} | ||||
| 					rules[len(rules)-1].Class[cls] = struct{}{} | ||||
| 					classes[cls] = struct{}{} | ||||
| 				} | ||||
| 			default: | ||||
| 				return nil, c.ArgErr() | ||||
| 			} | ||||
| 		} | ||||
| 		if len(rules[len(rules)-1].Class) == 0 { | ||||
| 			rules[len(rules)-1].Class[response.All] = struct{}{} | ||||
| 		if len(classes) == 0 { | ||||
| 			classes[response.All] = struct{}{} | ||||
| 		} | ||||
|  | ||||
| 		for i := len(rules) - 1; i >= length; i -= 1 { | ||||
| 			rules[i].Class = classes | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -55,6 +55,35 @@ func TestLogParse(t *testing.T) { | ||||
| 			Format:    "{when}", | ||||
| 			Class:     map[response.Class]struct{}{response.All: struct{}{}}, | ||||
| 		}}}, | ||||
| 		{`log example.org example.net`, false, []Rule{{ | ||||
| 			NameScope: "example.org.", | ||||
| 			Format:    DefaultLogFormat, | ||||
| 			Class:     map[response.Class]struct{}{response.All: struct{}{}}, | ||||
| 		}, { | ||||
| 			NameScope: "example.net.", | ||||
| 			Format:    DefaultLogFormat, | ||||
| 			Class:     map[response.Class]struct{}{response.All: struct{}{}}, | ||||
| 		}}}, | ||||
| 		{`log example.org example.net {host}`, false, []Rule{{ | ||||
| 			NameScope: "example.org.", | ||||
| 			Format:    "{host}", | ||||
| 			Class:     map[response.Class]struct{}{response.All: struct{}{}}, | ||||
| 		}, { | ||||
| 			NameScope: "example.net.", | ||||
| 			Format:    "{host}", | ||||
| 			Class:     map[response.Class]struct{}{response.All: struct{}{}}, | ||||
| 		}}}, | ||||
| 		{`log example.org example.net {when} { | ||||
| 			class denial | ||||
| 		}`, false, []Rule{{ | ||||
| 			NameScope: "example.org.", | ||||
| 			Format:    "{when}", | ||||
| 			Class:     map[response.Class]struct{}{response.Denial: struct{}{}}, | ||||
| 		}, { | ||||
| 			NameScope: "example.net.", | ||||
| 			Format:    "{when}", | ||||
| 			Class:     map[response.Class]struct{}{response.Denial: struct{}{}}, | ||||
| 		}}}, | ||||
|  | ||||
| 		{`log example.org { | ||||
| 				class all | ||||
|   | ||||
		Reference in New Issue
	
	Block a user