diff --git a/daemon/logger/jsonfilelog/jsonfilelog.go b/daemon/logger/jsonfilelog/jsonfilelog.go index 7aa92f3d37..720a7c3b61 100644 --- a/daemon/logger/jsonfilelog/jsonfilelog.go +++ b/daemon/logger/jsonfilelog/jsonfilelog.go @@ -27,6 +27,7 @@ type JSONFileLogger struct { closed bool writer *loggerutils.LogFile readers map[*logger.LogWatcher]struct{} // stores the active log followers + tag string // tag values requested by the user to log } func init() { @@ -61,11 +62,21 @@ func New(info logger.Info) (logger.Logger, error) { } } - var extra []byte attrs, err := info.ExtraAttributes(nil) if err != nil { return nil, err } + + // no default template. only use a tag if the user asked for it + tag, err := loggerutils.ParseLogTag(info, "") + if err != nil { + return nil, err + } + if tag != "" { + attrs["tag"] = tag + } + + var extra []byte if len(attrs) > 0 { var err error extra, err = json.Marshal(attrs) @@ -92,6 +103,7 @@ func New(info logger.Info) (logger.Logger, error) { return &JSONFileLogger{ writer: writer, readers: make(map[*logger.LogWatcher]struct{}), + tag: tag, }, nil } @@ -130,6 +142,7 @@ func ValidateLogOpt(cfg map[string]string) error { case "labels": case "env": case "env-regex": + case "tag": default: return fmt.Errorf("unknown log opt '%s' for json-file log driver", key) } diff --git a/daemon/logger/jsonfilelog/jsonfilelog_test.go b/daemon/logger/jsonfilelog/jsonfilelog_test.go index 893c054669..e988e862fd 100644 --- a/daemon/logger/jsonfilelog/jsonfilelog_test.go +++ b/daemon/logger/jsonfilelog/jsonfilelog_test.go @@ -14,6 +14,7 @@ import ( "github.com/docker/docker/daemon/logger" "github.com/docker/docker/daemon/logger/jsonfilelog/jsonlog" "github.com/gotestyourself/gotestyourself/fs" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -57,6 +58,46 @@ func TestJSONFileLogger(t *testing.T) { } } +func TestJSONFileLoggerWithTags(t *testing.T) { + cid := "a7317399f3f857173c6179d44823594f8294678dea9999662e5c625b5a1c7657" + cname := "test-container" + tmp, err := ioutil.TempDir("", "docker-logger-") + + require.NoError(t, err) + + defer os.RemoveAll(tmp) + filename := filepath.Join(tmp, "container.log") + l, err := New(logger.Info{ + Config: map[string]string{ + "tag": "{{.ID}}/{{.Name}}", // first 12 characters of ContainerID and full ContainerName + }, + ContainerID: cid, + ContainerName: cname, + LogPath: filename, + }) + + require.NoError(t, err) + defer l.Close() + + err = l.Log(&logger.Message{Line: []byte("line1"), Source: "src1"}) + require.NoError(t, err) + + err = l.Log(&logger.Message{Line: []byte("line2"), Source: "src2"}) + require.NoError(t, err) + + err = l.Log(&logger.Message{Line: []byte("line3"), Source: "src3"}) + require.NoError(t, err) + + res, err := ioutil.ReadFile(filename) + require.NoError(t, err) + + expected := `{"log":"line1\n","stream":"src1","attrs":{"tag":"a7317399f3f8/test-container"},"time":"0001-01-01T00:00:00Z"} +{"log":"line2\n","stream":"src2","attrs":{"tag":"a7317399f3f8/test-container"},"time":"0001-01-01T00:00:00Z"} +{"log":"line3\n","stream":"src3","attrs":{"tag":"a7317399f3f8/test-container"},"time":"0001-01-01T00:00:00Z"} +` + assert.Equal(t, expected, string(res)) +} + func BenchmarkJSONFileLoggerLog(b *testing.B) { tmp := fs.NewDir(b, "bench-jsonfilelog") defer tmp.Remove() diff --git a/daemon/logger/jsonfilelog/jsonlog/jsonlogbytes_test.go b/daemon/logger/jsonfilelog/jsonlog/jsonlogbytes_test.go index 4645cd4faa..e52d32c037 100644 --- a/daemon/logger/jsonfilelog/jsonlog/jsonlogbytes_test.go +++ b/daemon/logger/jsonfilelog/jsonlog/jsonlogbytes_test.go @@ -29,6 +29,8 @@ func TestJSONLogsMarshalJSONBuf(t *testing.T) { {Log: []byte{0x7F}}: `^{\"log\":\"\x7f\",\"time\":`, // with raw attributes {Log: []byte("A log line"), RawAttrs: []byte(`{"hello":"world","value":1234}`)}: `^{\"log\":\"A log line\",\"attrs\":{\"hello\":\"world\",\"value\":1234},\"time\":`, + // with Tag set + {Log: []byte("A log line with tag"), RawAttrs: []byte(`{"hello":"world","value":1234}`)}: `^{\"log\":\"A log line with tag\",\"attrs\":{\"hello\":\"world\",\"value\":1234},\"time\":`, } for jsonLog, expression := range logs { var buf bytes.Buffer