mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	add labels/env log option for jsonfile
this allows jsonfile logger to collect extra metadata from containers with `--log-opt labels=label1,label2 --log-opt env=env1,env2`. Extra attributes are saved into `attrs` attributes for each log data. Signed-off-by: Daniel Dao <dqminh@cloudflare.com>
This commit is contained in:
		
							parent
							
								
									11a24f19c2
								
							
						
					
					
						commit
						0083f6e984
					
				
					 4 changed files with 85 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -41,6 +41,7 @@ type JSONFileLogger struct {
 | 
			
		|||
	ctx          logger.Context
 | 
			
		||||
	readers      map[*logger.LogWatcher]struct{} // stores the active log followers
 | 
			
		||||
	notifyRotate *pubsub.Publisher
 | 
			
		||||
	extra        []byte // json-encoded extra attributes
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
| 
						 | 
				
			
			@ -77,6 +78,16 @@ func New(ctx logger.Context) (logger.Logger, error) {
 | 
			
		|||
			return nil, fmt.Errorf("max-file cannot be less than 1")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var extra []byte
 | 
			
		||||
	if attrs := ctx.ExtraAttributes(nil); len(attrs) > 0 {
 | 
			
		||||
		var err error
 | 
			
		||||
		extra, err = json.Marshal(attrs)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &JSONFileLogger{
 | 
			
		||||
		f:            log,
 | 
			
		||||
		buf:          bytes.NewBuffer(nil),
 | 
			
		||||
| 
						 | 
				
			
			@ -85,6 +96,7 @@ func New(ctx logger.Context) (logger.Logger, error) {
 | 
			
		|||
		n:            maxFiles,
 | 
			
		||||
		readers:      make(map[*logger.LogWatcher]struct{}),
 | 
			
		||||
		notifyRotate: pubsub.NewPublisher(0, 1),
 | 
			
		||||
		extra:        extra,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -97,7 +109,12 @@ func (l *JSONFileLogger) Log(msg *logger.Message) error {
 | 
			
		|||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	err = (&jsonlog.JSONLogs{Log: append(msg.Line, '\n'), Stream: msg.Source, Created: timestamp}).MarshalJSONBuf(l.buf)
 | 
			
		||||
	err = (&jsonlog.JSONLogs{
 | 
			
		||||
		Log:      append(msg.Line, '\n'),
 | 
			
		||||
		Stream:   msg.Source,
 | 
			
		||||
		Created:  timestamp,
 | 
			
		||||
		RawAttrs: l.extra,
 | 
			
		||||
	}).MarshalJSONBuf(l.buf)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -181,6 +198,8 @@ func ValidateLogOpt(cfg map[string]string) error {
 | 
			
		|||
		switch key {
 | 
			
		||||
		case "max-file":
 | 
			
		||||
		case "max-size":
 | 
			
		||||
		case "labels":
 | 
			
		||||
		case "env":
 | 
			
		||||
		default:
 | 
			
		||||
			return fmt.Errorf("unknown log opt '%s' for json-file log driver", key)
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +1,11 @@
 | 
			
		|||
package jsonfilelog
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
| 
						 | 
				
			
			@ -149,3 +151,51 @@ func TestJSONFileLoggerWithOpts(t *testing.T) {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestJSONFileLoggerWithLabelsEnv(t *testing.T) {
 | 
			
		||||
	cid := "a7317399f3f857173c6179d44823594f8294678dea9999662e5c625b5a1c7657"
 | 
			
		||||
	tmp, err := ioutil.TempDir("", "docker-logger-")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	defer os.RemoveAll(tmp)
 | 
			
		||||
	filename := filepath.Join(tmp, "container.log")
 | 
			
		||||
	config := map[string]string{"labels": "rack,dc", "env": "environ,debug,ssl"}
 | 
			
		||||
	l, err := New(logger.Context{
 | 
			
		||||
		ContainerID:     cid,
 | 
			
		||||
		LogPath:         filename,
 | 
			
		||||
		Config:          config,
 | 
			
		||||
		ContainerLabels: map[string]string{"rack": "101", "dc": "lhr"},
 | 
			
		||||
		ContainerEnv:    []string{"environ=production", "debug=false", "port=10001", "ssl=true"},
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	defer l.Close()
 | 
			
		||||
	if err := l.Log(&logger.Message{ContainerID: cid, Line: []byte("line"), Source: "src1"}); err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	res, err := ioutil.ReadFile(filename)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var jsonLog jsonlog.JSONLogs
 | 
			
		||||
	if err := json.Unmarshal(res, &jsonLog); err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	extra := make(map[string]string)
 | 
			
		||||
	if err := json.Unmarshal(jsonLog.RawAttrs, &extra); err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	expected := map[string]string{
 | 
			
		||||
		"rack":    "101",
 | 
			
		||||
		"dc":      "lhr",
 | 
			
		||||
		"environ": "production",
 | 
			
		||||
		"debug":   "false",
 | 
			
		||||
		"ssl":     "true",
 | 
			
		||||
	}
 | 
			
		||||
	if !reflect.DeepEqual(extra, expected) {
 | 
			
		||||
		t.Fatalf("Wrong log attrs: %q, expected %q", extra, expected)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue