Pārlūkot izejas kodu

Add support for TCP parameters

Signed-off-by: Ghislain Bourgeois <ghislain.bourgeois@gmail.com>
Ghislain Bourgeois 7 gadi atpakaļ
vecāks
revīzija
e21f7b6e76
2 mainītis faili ar 106 papildinājumiem un 17 dzēšanām
  1. 34 12
      daemon/logger/gelf/gelf.go
  2. 72 5
      daemon/logger/gelf/gelf_test.go

+ 34 - 12
daemon/logger/gelf/gelf.go

@@ -47,6 +47,10 @@ func New(info logger.Info) (logger.Logger, error) {
 		return nil, err
 	}
 
+	if address.Scheme == "tcp" {
+		return nil, fmt.Errorf("gelf: TCP not yet implemented")
+	}
+
 	// collect extra data for GELF message
 	hostname, err := info.Hostname()
 	if err != nil {
@@ -90,9 +94,9 @@ func New(info logger.Info) (logger.Logger, error) {
 	}
 
 	// create new gelfWriter
-	gelfWriter, err := gelf.NewUDPWriter(address)
+	gelfWriter, err := gelf.NewUDPWriter(address.String())
 	if err != nil {
-		return nil, fmt.Errorf("gelf: cannot connect to GELF endpoint: %s %v", address, err)
+		return nil, fmt.Errorf("gelf: cannot connect to GELF endpoint: %s %v", address.String(), err)
 	}
 
 	if v, ok := info.Config["gelf-compression-type"]; ok {
@@ -156,6 +160,11 @@ func (s *gelfLogger) Name() string {
 
 // ValidateLogOpt looks for gelf specific log option gelf-address.
 func ValidateLogOpt(cfg map[string]string) error {
+	address, err := parseAddress(cfg["gelf-address"])
+	if err != nil {
+		return err
+	}
+
 	for key, val := range cfg {
 		switch key {
 		case "gelf-address":
@@ -164,46 +173,59 @@ func ValidateLogOpt(cfg map[string]string) error {
 		case "env":
 		case "env-regex":
 		case "gelf-compression-level":
+			if address.Scheme != "udp" {
+				return fmt.Errorf("compression is only supported on UDP")
+			}
 			i, err := strconv.Atoi(val)
 			if err != nil || i < flate.DefaultCompression || i > flate.BestCompression {
 				return fmt.Errorf("unknown value %q for log opt %q for gelf log driver", val, key)
 			}
 		case "gelf-compression-type":
+			if address.Scheme != "udp" {
+				return fmt.Errorf("compression is only supported on UDP")
+			}
 			switch val {
 			case "gzip", "zlib", "none":
 			default:
 				return fmt.Errorf("unknown value %q for log opt %q for gelf log driver", val, key)
 			}
+		case "gelf-tcp-max-reconnect", "gelf-tcp-reconnect-delay":
+			if address.Scheme != "tcp" {
+				return fmt.Errorf("%q is only valid for TCP", key)
+			}
+			i, err := strconv.Atoi(val)
+			if err != nil || i < 0 {
+				return fmt.Errorf("%q must be a positive integer", key)
+			}
 		default:
 			return fmt.Errorf("unknown log opt %q for gelf log driver", key)
 		}
 	}
 
-	_, err := parseAddress(cfg["gelf-address"])
-	return err
+	return nil
 }
 
-func parseAddress(address string) (string, error) {
+func parseAddress(address string) (*url.URL, error) {
 	if address == "" {
-		return "", nil
+		return nil, fmt.Errorf("gelf-address is a required parameter")
 	}
 	if !urlutil.IsTransportURL(address) {
-		return "", fmt.Errorf("gelf-address should be in form proto://address, got %v", address)
+		return nil, fmt.Errorf("gelf-address should be in form proto://address, got %v", address)
 	}
 	url, err := url.Parse(address)
 	if err != nil {
-		return "", err
+		return nil, err
 	}
 
 	// we support only udp
-	if url.Scheme != "udp" {
-		return "", fmt.Errorf("gelf: endpoint needs to be UDP")
+	if url.Scheme != "udp" && url.Scheme != "tcp" {
+		return nil, fmt.Errorf("gelf: endpoint needs to be TCP or UDP")
 	}
 
 	// get host and port
 	if _, _, err = net.SplitHostPort(url.Host); err != nil {
-		return "", fmt.Errorf("gelf: please provide gelf-address as udp://host:port")
+		return nil, fmt.Errorf("gelf: please provide gelf-address as proto://host:port")
 	}
 
-	return url.Host, nil
+	return url, nil
 }

+ 72 - 5
daemon/logger/gelf/gelf_test.go

@@ -8,12 +8,12 @@ import (
 
 //Validate parseAddress
 func TestParseAddress(t *testing.T) {
-	host, err := parseAddress("udp://127.0.0.1:12201")
+	url, err := parseAddress("udp://127.0.0.1:12201")
 	if err != nil {
 		t.Fatal(err)
 	}
-	if host != "127.0.0.1:12201" {
-		t.Fatalf("Expected host 127.0.0.1, got %s", host)
+	if url.String() != "udp://127.0.0.1:12201" {
+		t.Fatalf("Expected address udp://127.0.0.1:12201, got %s", url.String())
 	}
 
 	_, err = parseAddress("127.0.0.1:12201")
@@ -27,8 +27,8 @@ func TestParseAddress(t *testing.T) {
 	}
 }
 
-//Validate options
-func TestValidateLogOpt(t *testing.T) {
+//Validate UDP options
+func TestUDPValidateLogOpt(t *testing.T) {
 	err := ValidateLogOpt(map[string]string{
 		"gelf-address":           "udp://127.0.0.1:12201",
 		"tag":                    "testtag",
@@ -65,4 +65,71 @@ func TestValidateLogOpt(t *testing.T) {
 	if err == nil {
 		t.Fatal("Expected unknown option error")
 	}
+
+	err = ValidateLogOpt(map[string]string{})
+	if err == nil {
+		t.Fatal("Expected required parameter error")
+	}
+}
+
+//Validate TCP options
+func TestTCPValidateLogOpt(t *testing.T) {
+	err := ValidateLogOpt(map[string]string{
+		"gelf-address": "tcp://127.0.0.1:12201",
+	})
+	if err != nil {
+		t.Fatal("Expected TCP to be supported")
+	}
+
+	err = ValidateLogOpt(map[string]string{
+		"gelf-address":           "tcp://127.0.0.1:12201",
+		"gelf-compression-level": "9",
+	})
+	if err == nil {
+		t.Fatal("Expected TCP to reject compression level")
+	}
+
+	err = ValidateLogOpt(map[string]string{
+		"gelf-address":          "tcp://127.0.0.1:12201",
+		"gelf-compression-type": "gzip",
+	})
+	if err == nil {
+		t.Fatal("Expected TCP to reject compression type")
+	}
+
+	err = ValidateLogOpt(map[string]string{
+		"gelf-address":             "tcp://127.0.0.1:12201",
+		"gelf-tcp-max-reconnect":   "5",
+		"gelf-tcp-reconnect-delay": "10",
+	})
+	if err != nil {
+		t.Fatal("Expected TCP reconnect to be a valid parameters")
+	}
+
+	err = ValidateLogOpt(map[string]string{
+		"gelf-address":             "tcp://127.0.0.1:12201",
+		"gelf-tcp-max-reconnect":   "-1",
+		"gelf-tcp-reconnect-delay": "-3",
+	})
+	if err == nil {
+		t.Fatal("Expected negative TCP reconnect to be rejected")
+	}
+
+	err = ValidateLogOpt(map[string]string{
+		"gelf-address":             "tcp://127.0.0.1:12201",
+		"gelf-tcp-max-reconnect":   "invalid",
+		"gelf-tcp-reconnect-delay": "invalid",
+	})
+	if err == nil {
+		t.Fatal("Expected TCP reconnect to be required to be an int")
+	}
+
+	err = ValidateLogOpt(map[string]string{
+		"gelf-address":             "udp://127.0.0.1:12201",
+		"gelf-tcp-max-reconnect":   "1",
+		"gelf-tcp-reconnect-delay": "3",
+	})
+	if err == nil {
+		t.Fatal("Expected TCP reconnect to be invalid for UDP")
+	}
 }