Преглед на файлове

add gelf option to customize compression type and level

this allows user to choose the compression type (i.e. gzip/zlib/none) using
--log-opt=gelf-compression-type=none or the compression level (-1..9) using
--log-opt=gelf-compression-level=0 for gelf driver.

Signed-off-by: Daniel Dao <dqminh@cloudflare.com>
Daniel Dao преди 9 години
родител
ревизия
bd94baa353
променени са 2 файла, в които са добавени 55 реда и са изтрити 5 реда
  1. 45 5
      daemon/logger/gelf/gelf.go
  2. 10 0
      docs/admin/logging/overview.md

+ 45 - 5
daemon/logger/gelf/gelf.go

@@ -6,9 +6,12 @@ package gelf
 
 
 import (
 import (
 	"bytes"
 	"bytes"
+	"compress/flate"
+	"encoding/json"
 	"fmt"
 	"fmt"
 	"net"
 	"net"
 	"net/url"
 	"net/url"
+	"strconv"
 	"time"
 	"time"
 
 
 	"github.com/Graylog2/go-gelf/gelf"
 	"github.com/Graylog2/go-gelf/gelf"
@@ -24,7 +27,7 @@ type gelfLogger struct {
 	writer   *gelf.Writer
 	writer   *gelf.Writer
 	ctx      logger.Context
 	ctx      logger.Context
 	hostname string
 	hostname string
-	extra    map[string]interface{}
+	rawExtra json.RawMessage
 }
 }
 
 
 func init() {
 func init() {
@@ -81,17 +84,43 @@ func New(ctx logger.Context) (logger.Logger, error) {
 		extra[k] = v
 		extra[k] = v
 	}
 	}
 
 
+	rawExtra, err := json.Marshal(extra)
+	if err != nil {
+		return nil, err
+	}
+
 	// create new gelfWriter
 	// create new gelfWriter
 	gelfWriter, err := gelf.NewWriter(address)
 	gelfWriter, err := gelf.NewWriter(address)
 	if err != nil {
 	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, err)
 	}
 	}
 
 
+	if v, ok := ctx.Config["gelf-compression-type"]; ok {
+		switch v {
+		case "gzip":
+			gelfWriter.CompressionType = gelf.CompressGzip
+		case "zlib":
+			gelfWriter.CompressionType = gelf.CompressZlib
+		case "none":
+			gelfWriter.CompressionType = gelf.CompressNone
+		default:
+			return nil, fmt.Errorf("gelf: invalid compression type %q", v)
+		}
+	}
+
+	if v, ok := ctx.Config["gelf-compression-level"]; ok {
+		val, err := strconv.Atoi(v)
+		if err != nil {
+			return nil, fmt.Errorf("gelf: invalid compression level %s, err %v", v, err)
+		}
+		gelfWriter.CompressionLevel = val
+	}
+
 	return &gelfLogger{
 	return &gelfLogger{
 		writer:   gelfWriter,
 		writer:   gelfWriter,
 		ctx:      ctx,
 		ctx:      ctx,
 		hostname: hostname,
 		hostname: hostname,
-		extra:    extra,
+		rawExtra: rawExtra,
 	}, nil
 	}, nil
 }
 }
 
 
@@ -107,7 +136,7 @@ func (s *gelfLogger) Log(msg *logger.Message) error {
 		Short:    string(msg.Line),
 		Short:    string(msg.Line),
 		TimeUnix: float64(msg.Timestamp.UnixNano()/int64(time.Millisecond)) / 1000.0,
 		TimeUnix: float64(msg.Timestamp.UnixNano()/int64(time.Millisecond)) / 1000.0,
 		Level:    level,
 		Level:    level,
-		Extra:    s.extra,
+		RawExtra: s.rawExtra,
 	}
 	}
 
 
 	if err := s.writer.WriteMessage(&m); err != nil {
 	if err := s.writer.WriteMessage(&m); err != nil {
@@ -127,15 +156,26 @@ func (s *gelfLogger) Name() string {
 // ValidateLogOpt looks for gelf specific log options gelf-address, &
 // ValidateLogOpt looks for gelf specific log options gelf-address, &
 // gelf-tag.
 // gelf-tag.
 func ValidateLogOpt(cfg map[string]string) error {
 func ValidateLogOpt(cfg map[string]string) error {
-	for key := range cfg {
+	for key, val := range cfg {
 		switch key {
 		switch key {
 		case "gelf-address":
 		case "gelf-address":
 		case "gelf-tag":
 		case "gelf-tag":
 		case "tag":
 		case "tag":
 		case "labels":
 		case "labels":
 		case "env":
 		case "env":
+		case "gelf-compression-level":
+			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":
+			switch val {
+			case "gzip", "zlib", "none":
+			default:
+				return fmt.Errorf("unknown value %q for log opt %q for gelf log driver", val, key)
+			}
 		default:
 		default:
-			return fmt.Errorf("unknown log opt '%s' for gelf log driver", key)
+			return fmt.Errorf("unknown log opt %q for gelf log driver", key)
 		}
 		}
 	}
 	}
 
 

+ 10 - 0
docs/admin/logging/overview.md

@@ -146,6 +146,8 @@ The GELF logging driver supports the following options:
     --log-opt tag="database"
     --log-opt tag="database"
     --log-opt labels=label1,label2
     --log-opt labels=label1,label2
     --log-opt env=env1,env2
     --log-opt env=env1,env2
+    --log-opt gelf-compression-type=gzip
+    --log-opt gelf-compression-level=1
 
 
 The `gelf-address` option specifies the remote GELF server address that the
 The `gelf-address` option specifies the remote GELF server address that the
 driver connects to. Currently, only `udp` is supported as the transport and you must
 driver connects to. Currently, only `udp` is supported as the transport and you must
@@ -167,6 +169,14 @@ underscore (`_`).
     "_fizz": "buzz",
     "_fizz": "buzz",
     // […]
     // […]
 
 
+The `gelf-compression-type` option can be used to change how the GELF driver
+compresses each log message. The accepted values are `gzip`, `zlib` and `none`.
+`gzip` is chosen by default.
+
+The `gelf-compression-level` option can be used to change the level of compresssion
+when `gzip` or `zlib` is selected as `gelf-compression-type`. Accepted value
+must be from from -1 to 9 (BestCompression). Higher levels typically
+run slower but compress more. Default value is 1 (BestSpeed).
 
 
 ## fluentd options
 ## fluentd options