Browse code

log driver - add ability to interpolate container context into the log tag field

Signed-off-by: Philip Monroe <phil@philmonroe.com>

Philip Monroe authored on 2015/08/07 07:50:44
Showing 13 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,72 @@
0
+package logger
1
+
2
+import (
3
+	"fmt"
4
+	"os"
5
+	"strings"
6
+	"time"
7
+)
8
+
9
+// Context provides enough information for a logging driver to do its function.
10
+type Context struct {
11
+	Config              map[string]string
12
+	ContainerID         string
13
+	ContainerName       string
14
+	ContainerEntrypoint string
15
+	ContainerArgs       []string
16
+	ContainerImageID    string
17
+	ContainerImageName  string
18
+	ContainerCreated    time.Time
19
+	LogPath             string
20
+}
21
+
22
+// Hostname returns the hostname from the underlying OS.
23
+func (ctx *Context) Hostname() (string, error) {
24
+	hostname, err := os.Hostname()
25
+	if err != nil {
26
+		return "", fmt.Errorf("logger: can not resolve hostname: %v", err)
27
+	}
28
+	return hostname, nil
29
+}
30
+
31
+// Command returns the command that the container being logged was
32
+// started with. The Entrypoint is prepended to the container
33
+// arguments.
34
+func (ctx *Context) Command() string {
35
+	terms := []string{ctx.ContainerEntrypoint}
36
+	for _, arg := range ctx.ContainerArgs {
37
+		terms = append(terms, arg)
38
+	}
39
+	command := strings.Join(terms, " ")
40
+	return command
41
+}
42
+
43
+// ID Returns the Container ID shortened to 12 characters.
44
+func (ctx *Context) ID() string {
45
+	return ctx.ContainerID[:12]
46
+}
47
+
48
+// FullID is an alias of ContainerID.
49
+func (ctx *Context) FullID() string {
50
+	return ctx.ContainerID
51
+}
52
+
53
+// Name returns the ContainerName without a preceding '/'.
54
+func (ctx *Context) Name() string {
55
+	return ctx.ContainerName[1:]
56
+}
57
+
58
+// ImageID returns the ContainerImageID shortened to 12 characters.
59
+func (ctx *Context) ImageID() string {
60
+	return ctx.ContainerImageID[:12]
61
+}
62
+
63
+// ImageFullID is an alias of ContainerID.
64
+func (ctx *Context) ImageFullID() string {
65
+	return ctx.ContainerImageID
66
+}
67
+
68
+// ImageName is an alias of ContainerImageName
69
+func (ctx *Context) ImageName() string {
70
+	return ctx.ContainerImageName
71
+}
... ...
@@ -2,10 +2,7 @@ package logger
2 2
 
3 3
 import (
4 4
 	"fmt"
5
-	"os"
6
-	"strings"
7 5
 	"sync"
8
-	"time"
9 6
 )
10 7
 
11 8
 // Creator builds a logging driver instance with given context.
... ...
@@ -15,40 +12,6 @@ type Creator func(Context) (Logger, error)
15 15
 // logging implementation.
16 16
 type LogOptValidator func(cfg map[string]string) error
17 17
 
18
-// Context provides enough information for a logging driver to do its function.
19
-type Context struct {
20
-	Config              map[string]string
21
-	ContainerID         string
22
-	ContainerName       string
23
-	ContainerEntrypoint string
24
-	ContainerArgs       []string
25
-	ContainerImageID    string
26
-	ContainerImageName  string
27
-	ContainerCreated    time.Time
28
-	LogPath             string
29
-}
30
-
31
-// Hostname returns the hostname from the underlying OS.
32
-func (ctx *Context) Hostname() (string, error) {
33
-	hostname, err := os.Hostname()
34
-	if err != nil {
35
-		return "", fmt.Errorf("logger: can not resolve hostname: %v", err)
36
-	}
37
-	return hostname, nil
38
-}
39
-
40
-// Command returns the command that the container being logged was
41
-// started with. The Entrypoint is prepended to the container
42
-// arguments.
43
-func (ctx *Context) Command() string {
44
-	terms := []string{ctx.ContainerEntrypoint}
45
-	for _, arg := range ctx.ContainerArgs {
46
-		terms = append(terms, arg)
47
-	}
48
-	command := strings.Join(terms, " ")
49
-	return command
50
-}
51
-
52 18
 type logdriverFactory struct {
53 19
 	registry     map[string]Creator
54 20
 	optValidator map[string]LogOptValidator
... ...
@@ -3,16 +3,15 @@
3 3
 package fluentd
4 4
 
5 5
 import (
6
-	"bytes"
7 6
 	"fmt"
8 7
 	"math"
9 8
 	"net"
10 9
 	"strconv"
11 10
 	"strings"
12
-	"text/template"
13 11
 
14 12
 	"github.com/Sirupsen/logrus"
15 13
 	"github.com/docker/docker/daemon/logger"
14
+	"github.com/docker/docker/daemon/logger/loggerutils"
16 15
 	"github.com/fluent/fluent-logger-golang/fluent"
17 16
 )
18 17
 
... ...
@@ -23,12 +22,6 @@ type fluentd struct {
23 23
 	writer        *fluent.Fluent
24 24
 }
25 25
 
26
-type receiver struct {
27
-	ID     string
28
-	FullID string
29
-	Name   string
30
-}
31
-
32 26
 const (
33 27
 	name             = "fluentd"
34 28
 	defaultHostName  = "localhost"
... ...
@@ -48,10 +41,14 @@ func init() {
48 48
 func parseConfig(ctx logger.Context) (string, int, string, error) {
49 49
 	host := defaultHostName
50 50
 	port := defaultPort
51
-	tag := "docker." + ctx.ContainerID[:12]
52 51
 
53 52
 	config := ctx.Config
54 53
 
54
+	tag, err := loggerutils.ParseLogTag(ctx, "docker.{{.ID}}")
55
+	if err != nil {
56
+		return "", 0, "", err
57
+	}
58
+
55 59
 	if address := config["fluentd-address"]; address != "" {
56 60
 		if h, p, err := net.SplitHostPort(address); err != nil {
57 61
 			if !strings.Contains(err.Error(), "missing port in address") {
... ...
@@ -68,23 +65,6 @@ func parseConfig(ctx logger.Context) (string, int, string, error) {
68 68
 		}
69 69
 	}
70 70
 
71
-	if config["fluentd-tag"] != "" {
72
-		receiver := &receiver{
73
-			ID:     ctx.ContainerID[:12],
74
-			FullID: ctx.ContainerID,
75
-			Name:   ctx.ContainerName,
76
-		}
77
-		tmpl, err := template.New("tag").Parse(config["fluentd-tag"])
78
-		if err != nil {
79
-			return "", 0, "", err
80
-		}
81
-		buf := new(bytes.Buffer)
82
-		if err := tmpl.Execute(buf, receiver); err != nil {
83
-			return "", 0, "", err
84
-		}
85
-		tag = buf.String()
86
-	}
87
-
88 71
 	return host, port, tag, nil
89 72
 }
90 73
 
... ...
@@ -130,6 +110,7 @@ func ValidateLogOpt(cfg map[string]string) error {
130 130
 		switch key {
131 131
 		case "fluentd-address":
132 132
 		case "fluentd-tag":
133
+		case "tag":
133 134
 		default:
134 135
 			return fmt.Errorf("unknown log opt '%s' for fluentd log driver", key)
135 136
 		}
... ...
@@ -14,6 +14,7 @@ import (
14 14
 	"github.com/Graylog2/go-gelf/gelf"
15 15
 	"github.com/Sirupsen/logrus"
16 16
 	"github.com/docker/docker/daemon/logger"
17
+	"github.com/docker/docker/daemon/logger/loggerutils"
17 18
 	"github.com/docker/docker/pkg/urlutil"
18 19
 )
19 20
 
... ...
@@ -64,6 +65,12 @@ func New(ctx logger.Context) (logger.Logger, error) {
64 64
 	// remove trailing slash from container name
65 65
 	containerName := bytes.TrimLeft([]byte(ctx.ContainerName), "/")
66 66
 
67
+	// parse log tag
68
+	tag, err := loggerutils.ParseLogTag(ctx, "")
69
+	if err != nil {
70
+		return nil, err
71
+	}
72
+
67 73
 	fields := gelfFields{
68 74
 		hostname:      hostname,
69 75
 		containerID:   ctx.ContainerID,
... ...
@@ -71,7 +78,7 @@ func New(ctx logger.Context) (logger.Logger, error) {
71 71
 		imageID:       ctx.ContainerImageID,
72 72
 		imageName:     ctx.ContainerImageName,
73 73
 		command:       ctx.Command(),
74
-		tag:           ctx.Config["gelf-tag"],
74
+		tag:           tag,
75 75
 		created:       ctx.ContainerCreated,
76 76
 	}
77 77
 
... ...
@@ -135,6 +142,7 @@ func ValidateLogOpt(cfg map[string]string) error {
135 135
 		switch key {
136 136
 		case "gelf-address":
137 137
 		case "gelf-tag":
138
+		case "tag":
138 139
 		default:
139 140
 			return fmt.Errorf("unknown log opt '%s' for gelf log driver", key)
140 141
 		}
141 142
new file mode 100644
... ...
@@ -0,0 +1,46 @@
0
+package loggerutils
1
+
2
+import (
3
+	"bytes"
4
+	"fmt"
5
+	"text/template"
6
+
7
+	"github.com/Sirupsen/logrus"
8
+	"github.com/docker/docker/daemon/logger"
9
+)
10
+
11
+// ParseLogTag generates a context aware tag for consistency across different
12
+// log drivers based on the context of the running container.
13
+func ParseLogTag(ctx logger.Context, defaultTemplate string) (string, error) {
14
+	tagTemplate := lookupTagTemplate(ctx, defaultTemplate)
15
+
16
+	tmpl, err := template.New("log-tag").Parse(tagTemplate)
17
+	if err != nil {
18
+		return "", err
19
+	}
20
+	buf := new(bytes.Buffer)
21
+	if err := tmpl.Execute(buf, &ctx); err != nil {
22
+		return "", err
23
+	}
24
+
25
+	return buf.String(), nil
26
+}
27
+
28
+func lookupTagTemplate(ctx logger.Context, defaultTemplate string) string {
29
+	tagTemplate := ctx.Config["tag"]
30
+
31
+	deprecatedConfigs := []string{"syslog-tag", "gelf-tag", "fluentd-tag"}
32
+	for i := 0; tagTemplate == "" && i < len(deprecatedConfigs); i++ {
33
+		cfg := deprecatedConfigs[i]
34
+		if ctx.Config[cfg] != "" {
35
+			tagTemplate = ctx.Config[cfg]
36
+			logrus.Warn(fmt.Sprintf("Using log tag from deprecated log-opt '%s'. Please use: --log-opt tag=\"%s\"", cfg, tagTemplate))
37
+		}
38
+	}
39
+
40
+	if tagTemplate == "" {
41
+		tagTemplate = defaultTemplate
42
+	}
43
+
44
+	return tagTemplate
45
+}
0 46
new file mode 100644
... ...
@@ -0,0 +1,58 @@
0
+package loggerutils
1
+
2
+import (
3
+	"testing"
4
+
5
+	"github.com/docker/docker/daemon/logger"
6
+)
7
+
8
+func TestParseLogTagDefaultTag(t *testing.T) {
9
+	ctx := buildContext(map[string]string{})
10
+	tag, e := ParseLogTag(ctx, "{{.ID}}")
11
+	assertTag(t, e, tag, ctx.ID())
12
+}
13
+
14
+func TestParseLogTag(t *testing.T) {
15
+	ctx := buildContext(map[string]string{"tag": "{{.ImageName}}/{{.Name}}/{{.ID}}"})
16
+	tag, e := ParseLogTag(ctx, "{{.ID}}")
17
+	assertTag(t, e, tag, "test-image/test-container/container-ab")
18
+}
19
+
20
+func TestParseLogTagSyslogTag(t *testing.T) {
21
+	ctx := buildContext(map[string]string{"syslog-tag": "{{.ImageName}}/{{.Name}}/{{.ID}}"})
22
+	tag, e := ParseLogTag(ctx, "{{.ID}}")
23
+	assertTag(t, e, tag, "test-image/test-container/container-ab")
24
+}
25
+
26
+func TestParseLogTagGelfTag(t *testing.T) {
27
+	ctx := buildContext(map[string]string{"gelf-tag": "{{.ImageName}}/{{.Name}}/{{.ID}}"})
28
+	tag, e := ParseLogTag(ctx, "{{.ID}}")
29
+	assertTag(t, e, tag, "test-image/test-container/container-ab")
30
+}
31
+
32
+func TestParseLogTagFluentdTag(t *testing.T) {
33
+	ctx := buildContext(map[string]string{"fluentd-tag": "{{.ImageName}}/{{.Name}}/{{.ID}}"})
34
+	tag, e := ParseLogTag(ctx, "{{.ID}}")
35
+	assertTag(t, e, tag, "test-image/test-container/container-ab")
36
+}
37
+
38
+// Helpers
39
+
40
+func buildContext(cfg map[string]string) logger.Context {
41
+	return logger.Context{
42
+		ContainerID:        "container-abcdefghijklmnopqrstuvwxyz01234567890",
43
+		ContainerName:      "/test-container",
44
+		ContainerImageID:   "image-abcdefghijklmnopqrstuvwxyz01234567890",
45
+		ContainerImageName: "test-image",
46
+		Config:             cfg,
47
+	}
48
+}
49
+
50
+func assertTag(t *testing.T, e error, tag string, expected string) {
51
+	if e != nil {
52
+		t.Fatalf("Error generating tag: %q", e)
53
+	}
54
+	if tag != expected {
55
+		t.Fatalf("Wrong tag: %q, should be %q", tag, expected)
56
+	}
57
+}
... ...
@@ -16,6 +16,7 @@ import (
16 16
 
17 17
 	"github.com/Sirupsen/logrus"
18 18
 	"github.com/docker/docker/daemon/logger"
19
+	"github.com/docker/docker/daemon/logger/loggerutils"
19 20
 	"github.com/docker/docker/pkg/urlutil"
20 21
 )
21 22
 
... ...
@@ -61,9 +62,9 @@ func init() {
61 61
 // the context. Supported context configuration variables are
62 62
 // syslog-address, syslog-facility, & syslog-tag.
63 63
 func New(ctx logger.Context) (logger.Logger, error) {
64
-	tag := ctx.Config["syslog-tag"]
65
-	if tag == "" {
66
-		tag = ctx.ContainerID[:12]
64
+	tag, err := loggerutils.ParseLogTag(ctx, "{{.ID}}")
65
+	if err != nil {
66
+		return nil, err
67 67
 	}
68 68
 
69 69
 	proto, address, err := parseAddress(ctx.Config["syslog-address"])
... ...
@@ -146,6 +147,7 @@ func ValidateLogOpt(cfg map[string]string) error {
146 146
 		case "syslog-address":
147 147
 		case "syslog-facility":
148 148
 		case "syslog-tag":
149
+		case "tag":
149 150
 		default:
150 151
 			return fmt.Errorf("unknown log opt '%s' for syslog log driver", key)
151 152
 		}
... ...
@@ -12,13 +12,26 @@ parent = "mn_use_docker"
12 12
 
13 13
 The following list of features are deprecated.
14 14
 
15
+### Driver Specific Log Tags
16
+**Deprecated In Release: v1.9**
17
+
18
+**Target For Removal In Release: v1.11**
19
+
20
+Log tags are now generated in a standard way across different logging drivers.
21
+Because of which, the driver specific log tag options `syslog-tag`, `gelf-tag` and
22
+`fluentd-tag` have been deprecated in favor of the generic `tag` option.
23
+
24
+    docker --log-driver=syslog --log-opt tag="{{.ImageName}}/{{.Name}}/{{.ID}}"
25
+
26
+
27
+
15 28
 ### LXC built-in exec driver
16 29
 **Deprecated In Release: v1.8**
17 30
 
18 31
 **Target For Removal In Release: v1.10**
19 32
 
20 33
 The built-in LXC execution driver is deprecated for an external implementation.
21
-The lxc-conf flag and API fields will also be removed. 
34
+The lxc-conf flag and API fields will also be removed.
22 35
 
23 36
 ### Old Command Line Options
24 37
 **Deprecated In Release: [v1.8.0](/release-notes/#docker-engine-1-8-0)**
... ...
@@ -29,7 +42,7 @@ The flags `-d` and `--daemon` are deprecated in favor of the `daemon` subcommand
29 29
 
30 30
     docker daemon -H ...
31 31
 
32
-The following single-dash (`-opt`) variant of certain command line options 
32
+The following single-dash (`-opt`) variant of certain command line options
33 33
 are deprecated and replaced with double-dash options (`--opt`):
34 34
 
35 35
     docker attach -nostdin
... ...
@@ -5,6 +5,7 @@ description = "Describes how to use the fluentd logging driver."
5 5
 keywords = ["Fluentd, docker, logging, driver"]
6 6
 [menu.main]
7 7
 parent = "smn_logging"
8
+weight=2
8 9
 +++
9 10
 <![end-metadata]-->
10 11
 
... ...
@@ -32,7 +33,7 @@ The `docker logs` command is not available for this logging driver.
32 32
 Some options are supported by specifying `--log-opt` as many times as needed:
33 33
 
34 34
  - `fluentd-address`: specify `host:port` to connect `localhost:24224`
35
- - `fluentd-tag`: specify tag for fluentd message, which interpret some markup, ex `{{.ID}}`, `{{.FullID}}` or `{{.Name}}` `docker.{{.ID}}`
35
+ - `tag`: specify tag for fluentd message, which interpret some markup, ex `{{.ID}}`, `{{.FullID}}` or `{{.Name}}` `docker.{{.ID}}`
36 36
 
37 37
 
38 38
 Configure the default logging driver by passing the
... ...
@@ -65,24 +66,12 @@ By default, the logging driver connects to `localhost:24224`. Supply the
65 65
 
66 66
     docker run --log-driver=fluentd --log-opt fluentd-address=myhost.local:24224
67 67
 
68
-### fluentd-tag
68
+### tag
69 69
 
70
-Every Fluentd's event has a tag that indicates where the log comes from. By
71
-default, the driver uses the `docker.{{.ID}}` tag.  Use the `fluentd-tag` option
72
-to change this behavior.
70
+By default, Docker uses the first 12 characters of the container ID to tag log messages.
71
+Refer to the [log tag option documentation](/reference/logging/log_tags/) for customizing
72
+the log tag format.
73 73
 
74
-When specifying a `fluentd-tag` value, you can use the following markup tags:
75
-
76
- - `{{.ID}}`: short container id (12 characters)
77
- - `{{.FullID}}`: full container id
78
- - `{{.Name}}`: container name
79
-
80
-## Note regarding container names
81
-
82
-At startup time, the system sets the `container_name` field and `{{.Name}}`
83
-in the tags to their values at startup. If you use `docker rename` to rename a
84
-container, the new name is not be reflected in  `fluentd` messages. Instead,
85
-these messages continue to use the original container name.
86 74
 
87 75
 ## Fluentd daemon management with Docker
88 76
 
... ...
@@ -1,7 +1,7 @@
1 1
 <!--[metadata]>
2 2
 +++
3
-title = "Logging Drivers"
4
-description = "Logging Drivers"
3
+title = "Logging"
4
+description = "Logging and Logging Drivers"
5 5
 keywords = [" docker, logging, driver"]
6 6
 [menu.main]
7 7
 parent = "smn_administrate"
... ...
@@ -14,6 +14,7 @@ weight=8
14 14
 # Logging Drivers
15 15
 
16 16
 * [Configuring logging drivers](overview)
17
+* [Configuring log tags](log_tags)
17 18
 * [Fluentd logging driver](fluentd)
18 19
 * [Journald logging driver](journald)
19 20
 * [Amazon CloudWatch Logs logging driver](awslogs)
... ...
@@ -5,6 +5,7 @@ description = "Describes how to use the fluentd logging driver."
5 5
 keywords = ["Fluentd, docker, logging, driver"]
6 6
 [menu.main]
7 7
 parent = "smn_logging"
8
+weight = 2
8 9
 +++
9 10
 <![end-metadata]-->
10 11
 
11 12
new file mode 100644
... ...
@@ -0,0 +1,50 @@
0
+<!--[metadata]>
1
+title = "Log tags for logging driver"
2
+description = "Describes how to format tags for."
3
+keywords = ["docker, logging, driver, syslog, Fluentd, gelf"]
4
+[menu.main]
5
+parent = "smn_logging"
6
+weight = 1
7
+<![end-metadata]-->
8
+
9
+# Log Tags
10
+
11
+The `tag` log option specifies how to format a tag that identifies the
12
+container's log messages. By default, the system uses the first 12 characters of
13
+the container id. To override this behavior, specify a `tag` option:
14
+
15
+```
16
+docker run --log-driver=fluentd --log-opt fluentd-address=myhost.local:24224 --log-opt tag="mailer"
17
+```
18
+
19
+Docker supports some special template markup you can use when specifying a tag's value:
20
+
21
+| Markup             | Description                                          |
22
+|--------------------|------------------------------------------------------|
23
+| `{{.ID}}`          | The first 12 characters of the container id.         |
24
+| `{{.FullID}}`      | The full container id.                               |
25
+| `{{.Name}}`        | The container name.                                  |
26
+| `{{.ImageID}}`     | The first 12 characters of the container's image id. |
27
+| `{{.ImageFullID}}` | The container's full image identifier.               |
28
+| `{{.ImageName}}`   | The name of the image used by the container.         |
29
+
30
+For example, specifying a `--log-opt tag="{{.ImageName}}/{{.Name}}/{{.ID}}"` value yields `syslog` log lines like:
31
+
32
+```
33
+Aug  7 18:33:19 HOSTNAME docker/hello-world/foobar/5790672ab6a0[9103]: Hello from Docker.
34
+```
35
+
36
+At startup time, the system sets the `container_name` field and `{{.Name}}` in
37
+the tags. If you use `docker rename` to rename a container, the new name is not
38
+reflected in the log messages. Instead, these messages continue to use the
39
+original container name.
40
+
41
+For advanced usage, the generated tag's use [go
42
+templates](http://golang.org/pkg/text/template/) and the container's [logging
43
+context](https://github.com/docker/docker/blob/master/daemon/logger/context.go).
44
+
45
+>**Note**:The driver specific log options `syslog-tag`, `fluentd-tag` and
46
+>`gelf-tag` still work for backwards compatibility. However, going forward you
47
+>should standardize on using the generic `tag` log option instead.
... ...
@@ -2,7 +2,7 @@
2 2
 +++
3 3
 title = "Configuring Logging Drivers"
4 4
 description = "Configure logging driver."
5
-keywords = ["Fluentd, docker, logging, driver"]
5
+keywords = ["docker, logging, driver, Fluentd"]
6 6
 [menu.main]
7 7
 parent = "smn_logging"
8 8
 weight=-1
... ...
@@ -25,9 +25,9 @@ container's logging driver. The following options are supported:
25 25
 | `fluentd`   | Fluentd logging driver for Docker. Writes log messages to `fluentd` (forward input).                                          |
26 26
 | `awslogs`   | Amazon CloudWatch Logs logging driver for Docker. Writes log messages to Amazon CloudWatch Logs.                              |
27 27
 
28
-The `docker logs`command is available only for the `json-file` logging driver.  
28
+The `docker logs`command is available only for the `json-file` logging driver.
29 29
 
30
-### The json-file options
30
+## json-file options
31 31
 
32 32
 The following logging options are supported for the `json-file` logging driver:
33 33
 
... ...
@@ -39,16 +39,16 @@ Logs that reach `max-size` are rolled over. You can set the size in kilobytes(k)
39 39
 
40 40
 `max-file` specifies the maximum number of files that a log is rolled over before being discarded. eg `--log-opt max-file=100`. If `max-size` is not set, then `max-file` is not honored.
41 41
 
42
-If `max-size` and `max-file` are set, `docker logs` only returns the log lines from the newest log file. 
42
+If `max-size` and `max-file` are set, `docker logs` only returns the log lines from the newest log file.
43 43
 
44
-### The syslog options
44
+## syslog options
45 45
 
46 46
 The following logging options are supported for the `syslog` logging driver:
47 47
 
48 48
     --log-opt syslog-address=[tcp|udp]://host:port
49 49
     --log-opt syslog-address=unix://path
50 50
     --log-opt syslog-facility=daemon
51
-    --log-opt syslog-tag="mailer"
51
+    --log-opt tag="mailer"
52 52
 
53 53
 `syslog-address` specifies the remote syslog server address where the driver connects to.
54 54
 If not specified it defaults to the local unix socket of the running system.
... ...
@@ -83,22 +83,23 @@ the following named facilities:
83 83
 * `local6`
84 84
 * `local7`
85 85
 
86
-The `syslog-tag` specifies a tag that identifies the container's syslog messages. By default,
87
-the system uses the first 12 characters of the container id. To override this behavior, specify
88
-a `syslog-tag` option
86
+By default, Docker uses the first 12 characters of the container ID to tag log messages.
87
+Refer to the [log tag option documentation](/reference/logging/log_tags/) for customizing
88
+the log tag format.
89 89
 
90
-## Specify journald options
90
+
91
+## journald options
91 92
 
92 93
 The `journald` logging driver stores the container id in the journal's `CONTAINER_ID` field. For detailed information on
93 94
 working with this logging driver, see [the journald logging driver](/reference/logging/journald/)
94 95
 reference documentation.
95 96
 
96
-## Specify gelf options
97
+## gelf options
97 98
 
98 99
 The GELF logging driver supports the following options:
99 100
 
100 101
     --log-opt gelf-address=udp://host:port
101
-    --log-opt gelf-tag="database"
102
+    --log-opt tag="database"
102 103
 
103 104
 The `gelf-address` option specifies the remote GELF server address that the
104 105
 driver connects to. Currently, only `udp` is supported as the transport and you must
... ...
@@ -107,24 +108,21 @@ driver to a GELF remote server at `192.168.0.42` on port `12201`
107 107
 
108 108
     $ docker run --log-driver=gelf --log-opt gelf-address=udp://192.168.0.42:12201
109 109
 
110
-The `gelf-tag` option specifies a tag for easy container identification.
110
+By default, Docker uses the first 12 characters of the container ID to tag log messages.
111
+Refer to the [log tag option documentation](/reference/logging/log_tags/) for customizing
112
+the log tag format.
113
+
111 114
 
112
-## Specify fluentd options
115
+## fluentd options
113 116
 
114 117
 You can use the `--log-opt NAME=VALUE` flag to specify these additional Fluentd logging driver options.
115 118
 
116 119
  - `fluentd-address`: specify `host:port` to connect [localhost:24224]
117
- - `fluentd-tag`: specify tag for `fluentd` message, 
118
-
119
-When specifying a `fluentd-tag` value, you can use the following markup tags:
120
-
121
- - `{{.ID}}`: short container id (12 characters)
122
- - `{{.FullID}}`: full container id
123
- - `{{.Name}}`: container name
120
+ - `tag`: specify tag for `fluentd` message,
124 121
 
125 122
 For example, to specify both additional options:
126 123
 
127
-`docker run --log-driver=fluentd --log-opt fluentd-address=localhost:24224 --log-opt fluentd-tag=docker.{{.Name}}`
124
+`docker run --log-driver=fluentd --log-opt fluentd-address=localhost:24224 --log-opt tag=docker.{{.Name}}`
128 125
 
129 126
 If container cannot connect to the Fluentd daemon on the specified address,
130 127
 the container stops immediately. For detailed information on working with this