Carry #34248 Added tag log option to json-logger and use RawAttrs
Vincent Demeester authored on 2018/01/23 08:02:54... | ... |
@@ -27,6 +27,7 @@ type JSONFileLogger struct { |
27 | 27 |
closed bool |
28 | 28 |
writer *loggerutils.LogFile |
29 | 29 |
readers map[*logger.LogWatcher]struct{} // stores the active log followers |
30 |
+ tag string // tag values requested by the user to log |
|
30 | 31 |
} |
31 | 32 |
|
32 | 33 |
func init() { |
... | ... |
@@ -61,11 +62,21 @@ func New(info logger.Info) (logger.Logger, error) { |
61 | 61 |
} |
62 | 62 |
} |
63 | 63 |
|
64 |
- var extra []byte |
|
65 | 64 |
attrs, err := info.ExtraAttributes(nil) |
66 | 65 |
if err != nil { |
67 | 66 |
return nil, err |
68 | 67 |
} |
68 |
+ |
|
69 |
+ // no default template. only use a tag if the user asked for it |
|
70 |
+ tag, err := loggerutils.ParseLogTag(info, "") |
|
71 |
+ if err != nil { |
|
72 |
+ return nil, err |
|
73 |
+ } |
|
74 |
+ if tag != "" { |
|
75 |
+ attrs["tag"] = tag |
|
76 |
+ } |
|
77 |
+ |
|
78 |
+ var extra []byte |
|
69 | 79 |
if len(attrs) > 0 { |
70 | 80 |
var err error |
71 | 81 |
extra, err = json.Marshal(attrs) |
... | ... |
@@ -92,6 +103,7 @@ func New(info logger.Info) (logger.Logger, error) { |
92 | 92 |
return &JSONFileLogger{ |
93 | 93 |
writer: writer, |
94 | 94 |
readers: make(map[*logger.LogWatcher]struct{}), |
95 |
+ tag: tag, |
|
95 | 96 |
}, nil |
96 | 97 |
} |
97 | 98 |
|
... | ... |
@@ -130,6 +142,7 @@ func ValidateLogOpt(cfg map[string]string) error { |
130 | 130 |
case "labels": |
131 | 131 |
case "env": |
132 | 132 |
case "env-regex": |
133 |
+ case "tag": |
|
133 | 134 |
default: |
134 | 135 |
return fmt.Errorf("unknown log opt '%s' for json-file log driver", key) |
135 | 136 |
} |
... | ... |
@@ -14,6 +14,7 @@ import ( |
14 | 14 |
"github.com/docker/docker/daemon/logger" |
15 | 15 |
"github.com/docker/docker/daemon/logger/jsonfilelog/jsonlog" |
16 | 16 |
"github.com/gotestyourself/gotestyourself/fs" |
17 |
+ "github.com/stretchr/testify/assert" |
|
17 | 18 |
"github.com/stretchr/testify/require" |
18 | 19 |
) |
19 | 20 |
|
... | ... |
@@ -57,6 +58,46 @@ func TestJSONFileLogger(t *testing.T) { |
57 | 57 |
} |
58 | 58 |
} |
59 | 59 |
|
60 |
+func TestJSONFileLoggerWithTags(t *testing.T) { |
|
61 |
+ cid := "a7317399f3f857173c6179d44823594f8294678dea9999662e5c625b5a1c7657" |
|
62 |
+ cname := "test-container" |
|
63 |
+ tmp, err := ioutil.TempDir("", "docker-logger-") |
|
64 |
+ |
|
65 |
+ require.NoError(t, err) |
|
66 |
+ |
|
67 |
+ defer os.RemoveAll(tmp) |
|
68 |
+ filename := filepath.Join(tmp, "container.log") |
|
69 |
+ l, err := New(logger.Info{ |
|
70 |
+ Config: map[string]string{ |
|
71 |
+ "tag": "{{.ID}}/{{.Name}}", // first 12 characters of ContainerID and full ContainerName |
|
72 |
+ }, |
|
73 |
+ ContainerID: cid, |
|
74 |
+ ContainerName: cname, |
|
75 |
+ LogPath: filename, |
|
76 |
+ }) |
|
77 |
+ |
|
78 |
+ require.NoError(t, err) |
|
79 |
+ defer l.Close() |
|
80 |
+ |
|
81 |
+ err = l.Log(&logger.Message{Line: []byte("line1"), Source: "src1"}) |
|
82 |
+ require.NoError(t, err) |
|
83 |
+ |
|
84 |
+ err = l.Log(&logger.Message{Line: []byte("line2"), Source: "src2"}) |
|
85 |
+ require.NoError(t, err) |
|
86 |
+ |
|
87 |
+ err = l.Log(&logger.Message{Line: []byte("line3"), Source: "src3"}) |
|
88 |
+ require.NoError(t, err) |
|
89 |
+ |
|
90 |
+ res, err := ioutil.ReadFile(filename) |
|
91 |
+ require.NoError(t, err) |
|
92 |
+ |
|
93 |
+ expected := `{"log":"line1\n","stream":"src1","attrs":{"tag":"a7317399f3f8/test-container"},"time":"0001-01-01T00:00:00Z"} |
|
94 |
+{"log":"line2\n","stream":"src2","attrs":{"tag":"a7317399f3f8/test-container"},"time":"0001-01-01T00:00:00Z"} |
|
95 |
+{"log":"line3\n","stream":"src3","attrs":{"tag":"a7317399f3f8/test-container"},"time":"0001-01-01T00:00:00Z"} |
|
96 |
+` |
|
97 |
+ assert.Equal(t, expected, string(res)) |
|
98 |
+} |
|
99 |
+ |
|
60 | 100 |
func BenchmarkJSONFileLoggerLog(b *testing.B) { |
61 | 101 |
tmp := fs.NewDir(b, "bench-jsonfilelog") |
62 | 102 |
defer tmp.Remove() |
... | ... |
@@ -29,6 +29,8 @@ func TestJSONLogsMarshalJSONBuf(t *testing.T) { |
29 | 29 |
{Log: []byte{0x7F}}: `^{\"log\":\"\x7f\",\"time\":`, |
30 | 30 |
// with raw attributes |
31 | 31 |
{Log: []byte("A log line"), RawAttrs: []byte(`{"hello":"world","value":1234}`)}: `^{\"log\":\"A log line\",\"attrs\":{\"hello\":\"world\",\"value\":1234},\"time\":`, |
32 |
+ // with Tag set |
|
33 |
+ {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\":`, |
|
32 | 34 |
} |
33 | 35 |
for jsonLog, expression := range logs { |
34 | 36 |
var buf bytes.Buffer |