Browse code

golint fixes for daemon/logger/*

- downcase and privatize exported variables that were unused
- make accurate an error message
- added package comments
- remove unused var ReadLogsNotSupported
- enable linter
- some spelling corrections

Signed-off-by: Morgan Bauer <mbauer@us.ibm.com>

Morgan Bauer authored on 2015/07/22 07:26:52
Showing 8 changed files
... ...
@@ -8,13 +8,14 @@ import (
8 8
 	"time"
9 9
 )
10 10
 
11
-// Creator is a method that builds a logging driver instance with given context
11
+// Creator builds a logging driver instance with given context.
12 12
 type Creator func(Context) (Logger, error)
13 13
 
14
-//LogOptValidator is a method that validates the log opts provided
14
+// LogOptValidator checks the options specific to the underlying
15
+// logging implementation.
15 16
 type LogOptValidator func(cfg map[string]string) error
16 17
 
17
-// Context provides enough information for a logging driver to do its function
18
+// Context provides enough information for a logging driver to do its function.
18 19
 type Context struct {
19 20
 	Config              map[string]string
20 21
 	ContainerID         string
... ...
@@ -27,7 +28,7 @@ type Context struct {
27 27
 	LogPath             string
28 28
 }
29 29
 
30
-// Hostname returns the hostname from the underlying OS
30
+// Hostname returns the hostname from the underlying OS.
31 31
 func (ctx *Context) Hostname() (string, error) {
32 32
 	hostname, err := os.Hostname()
33 33
 	if err != nil {
... ...
@@ -36,7 +37,9 @@ func (ctx *Context) Hostname() (string, error) {
36 36
 	return hostname, nil
37 37
 }
38 38
 
39
-// Command returns the command that the container being logged was started with
39
+// Command returns the command that the container being logged was
40
+// started with. The Entrypoint is prepended to the container
41
+// arguments.
40 42
 func (ctx *Context) Command() string {
41 43
 	terms := []string{ctx.ContainerEntrypoint}
42 44
 	for _, arg := range ctx.ContainerArgs {
... ...
@@ -68,7 +71,7 @@ func (lf *logdriverFactory) registerLogOptValidator(name string, l LogOptValidat
68 68
 	defer lf.m.Unlock()
69 69
 
70 70
 	if _, ok := lf.optValidator[name]; ok {
71
-		return fmt.Errorf("logger: log driver named '%s' is already registered", name)
71
+		return fmt.Errorf("logger: log validator named '%s' is already registered", name)
72 72
 	}
73 73
 	lf.optValidator[name] = l
74 74
 	return nil
... ...
@@ -101,6 +104,8 @@ func RegisterLogDriver(name string, c Creator) error {
101 101
 	return factory.register(name, c)
102 102
 }
103 103
 
104
+// RegisterLogOptValidator registers the logging option validator with
105
+// the given logging driver name.
104 106
 func RegisterLogOptValidator(name string, l LogOptValidator) error {
105 107
 	return factory.registerLogOptValidator(name, l)
106 108
 }
... ...
@@ -110,6 +115,8 @@ func GetLogDriver(name string) (Creator, error) {
110 110
 	return factory.get(name)
111 111
 }
112 112
 
113
+// ValidateLogOpts checks the options for the given log driver. The
114
+// options supported are specific to the LogDriver implementation.
113 115
 func ValidateLogOpts(name string, cfg map[string]string) error {
114 116
 	l := factory.getLogOptValidator(name)
115 117
 	if l != nil {
... ...
@@ -1,3 +1,5 @@
1
+// Package fluentd provides the log driver for forwarding server logs
2
+// to fluentd endpoints.
1 3
 package fluentd
2 4
 
3 5
 import (
... ...
@@ -14,14 +16,14 @@ import (
14 14
 	"github.com/fluent/fluent-logger-golang/fluent"
15 15
 )
16 16
 
17
-type Fluentd struct {
17
+type fluentd struct {
18 18
 	tag           string
19 19
 	containerID   string
20 20
 	containerName string
21 21
 	writer        *fluent.Fluent
22 22
 }
23 23
 
24
-type Receiver struct {
24
+type receiver struct {
25 25
 	ID     string
26 26
 	FullID string
27 27
 	Name   string
... ...
@@ -67,7 +69,7 @@ func parseConfig(ctx logger.Context) (string, int, string, error) {
67 67
 	}
68 68
 
69 69
 	if config["fluentd-tag"] != "" {
70
-		receiver := &Receiver{
70
+		receiver := &receiver{
71 71
 			ID:     ctx.ContainerID[:12],
72 72
 			FullID: ctx.ContainerID,
73 73
 			Name:   ctx.ContainerName,
... ...
@@ -86,6 +88,9 @@ func parseConfig(ctx logger.Context) (string, int, string, error) {
86 86
 	return host, port, tag, nil
87 87
 }
88 88
 
89
+// New creates a fluentd logger using the configuration passed in on
90
+// the context. Supported context configuration variables are
91
+// fluentd-address & fluentd-tag.
89 92
 func New(ctx logger.Context) (logger.Logger, error) {
90 93
 	host, port, tag, err := parseConfig(ctx)
91 94
 	if err != nil {
... ...
@@ -99,7 +104,7 @@ func New(ctx logger.Context) (logger.Logger, error) {
99 99
 	if err != nil {
100 100
 		return nil, err
101 101
 	}
102
-	return &Fluentd{
102
+	return &fluentd{
103 103
 		tag:           tag,
104 104
 		containerID:   ctx.ContainerID,
105 105
 		containerName: ctx.ContainerName,
... ...
@@ -107,7 +112,7 @@ func New(ctx logger.Context) (logger.Logger, error) {
107 107
 	}, nil
108 108
 }
109 109
 
110
-func (f *Fluentd) Log(msg *logger.Message) error {
110
+func (f *fluentd) Log(msg *logger.Message) error {
111 111
 	data := map[string]string{
112 112
 		"container_id":   f.containerID,
113 113
 		"container_name": f.containerName,
... ...
@@ -119,6 +124,7 @@ func (f *Fluentd) Log(msg *logger.Message) error {
119 119
 	return f.writer.PostWithTime(f.tag, msg.Timestamp, data)
120 120
 }
121 121
 
122
+// ValidateLogOpt looks for fluentd specific log options fluentd-address & fluentd-tag.
122 123
 func ValidateLogOpt(cfg map[string]string) error {
123 124
 	for key := range cfg {
124 125
 		switch key {
... ...
@@ -131,10 +137,10 @@ func ValidateLogOpt(cfg map[string]string) error {
131 131
 	return nil
132 132
 }
133 133
 
134
-func (f *Fluentd) Close() error {
134
+func (f *fluentd) Close() error {
135 135
 	return f.writer.Close()
136 136
 }
137 137
 
138
-func (f *Fluentd) Name() string {
138
+func (f *fluentd) Name() string {
139 139
 	return name
140 140
 }
... ...
@@ -1,5 +1,7 @@
1 1
 // +build linux
2 2
 
3
+// Package gelf provides the log driver for forwarding server logs to
4
+// endpoints that support the Graylog Extended Log Format.
3 5
 package gelf
4 6
 
5 7
 import (
... ...
@@ -17,17 +19,17 @@ import (
17 17
 
18 18
 const name = "gelf"
19 19
 
20
-type GelfLogger struct {
20
+type gelfLogger struct {
21 21
 	writer *gelf.Writer
22 22
 	ctx    logger.Context
23
-	fields GelfFields
23
+	fields gelfFields
24 24
 }
25 25
 
26
-type GelfFields struct {
26
+type gelfFields struct {
27 27
 	hostname      string
28
-	containerId   string
28
+	containerID   string
29 29
 	containerName string
30
-	imageId       string
30
+	imageID       string
31 31
 	imageName     string
32 32
 	command       string
33 33
 	tag           string
... ...
@@ -43,6 +45,9 @@ func init() {
43 43
 	}
44 44
 }
45 45
 
46
+// New creates a gelf logger using the configuration passed in on the
47
+// context. Supported context configuration variables are
48
+// gelf-address, & gelf-tag.
46 49
 func New(ctx logger.Context) (logger.Logger, error) {
47 50
 	// parse gelf address
48 51
 	address, err := parseAddress(ctx.Config["gelf-address"])
... ...
@@ -59,11 +64,11 @@ func New(ctx logger.Context) (logger.Logger, error) {
59 59
 	// remove trailing slash from container name
60 60
 	containerName := bytes.TrimLeft([]byte(ctx.ContainerName), "/")
61 61
 
62
-	fields := GelfFields{
62
+	fields := gelfFields{
63 63
 		hostname:      hostname,
64
-		containerId:   ctx.ContainerID,
64
+		containerID:   ctx.ContainerID,
65 65
 		containerName: string(containerName),
66
-		imageId:       ctx.ContainerImageID,
66
+		imageID:       ctx.ContainerImageID,
67 67
 		imageName:     ctx.ContainerImageName,
68 68
 		command:       ctx.Command(),
69 69
 		tag:           ctx.Config["gelf-tag"],
... ...
@@ -76,14 +81,14 @@ func New(ctx logger.Context) (logger.Logger, error) {
76 76
 		return nil, fmt.Errorf("gelf: cannot connect to GELF endpoint: %s %v", address, err)
77 77
 	}
78 78
 
79
-	return &GelfLogger{
79
+	return &gelfLogger{
80 80
 		writer: gelfWriter,
81 81
 		ctx:    ctx,
82 82
 		fields: fields,
83 83
 	}, nil
84 84
 }
85 85
 
86
-func (s *GelfLogger) Log(msg *logger.Message) error {
86
+func (s *gelfLogger) Log(msg *logger.Message) error {
87 87
 	// remove trailing and leading whitespace
88 88
 	short := bytes.TrimSpace([]byte(msg.Line))
89 89
 
... ...
@@ -99,9 +104,9 @@ func (s *GelfLogger) Log(msg *logger.Message) error {
99 99
 		TimeUnix: float64(msg.Timestamp.UnixNano()/int64(time.Millisecond)) / 1000.0,
100 100
 		Level:    level,
101 101
 		Extra: map[string]interface{}{
102
-			"_container_id":   s.fields.containerId,
102
+			"_container_id":   s.fields.containerID,
103 103
 			"_container_name": s.fields.containerName,
104
-			"_image_id":       s.fields.imageId,
104
+			"_image_id":       s.fields.imageID,
105 105
 			"_image_name":     s.fields.imageName,
106 106
 			"_command":        s.fields.command,
107 107
 			"_tag":            s.fields.tag,
... ...
@@ -115,14 +120,16 @@ func (s *GelfLogger) Log(msg *logger.Message) error {
115 115
 	return nil
116 116
 }
117 117
 
118
-func (s *GelfLogger) Close() error {
118
+func (s *gelfLogger) Close() error {
119 119
 	return s.writer.Close()
120 120
 }
121 121
 
122
-func (s *GelfLogger) Name() string {
122
+func (s *gelfLogger) Name() string {
123 123
 	return name
124 124
 }
125 125
 
126
+// ValidateLogOpt looks for gelf specific log options gelf-address, &
127
+// gelf-tag.
126 128
 func ValidateLogOpt(cfg map[string]string) error {
127 129
 	for key := range cfg {
128 130
 		switch key {
... ...
@@ -1,5 +1,7 @@
1 1
 // +build linux
2 2
 
3
+// Package journald provides the log driver for forwarding server logs
4
+// to endpoints that receive the systemd format.
3 5
 package journald
4 6
 
5 7
 import (
... ...
@@ -12,7 +14,7 @@ import (
12 12
 
13 13
 const name = "journald"
14 14
 
15
-type Journald struct {
15
+type journald struct {
16 16
 	Jmap map[string]string
17 17
 }
18 18
 
... ...
@@ -22,6 +24,9 @@ func init() {
22 22
 	}
23 23
 }
24 24
 
25
+// New creates a journald logger using the configuration passed in on
26
+// the context. Supported context configuration variables are
27
+// syslog-address, syslog-facility, & syslog-tag.
25 28
 func New(ctx logger.Context) (logger.Logger, error) {
26 29
 	if !journal.Enabled() {
27 30
 		return nil, fmt.Errorf("journald is not enabled on this host")
... ...
@@ -36,20 +41,20 @@ func New(ctx logger.Context) (logger.Logger, error) {
36 36
 		"CONTAINER_ID":      ctx.ContainerID[:12],
37 37
 		"CONTAINER_ID_FULL": ctx.ContainerID,
38 38
 		"CONTAINER_NAME":    name}
39
-	return &Journald{Jmap: jmap}, nil
39
+	return &journald{Jmap: jmap}, nil
40 40
 }
41 41
 
42
-func (s *Journald) Log(msg *logger.Message) error {
42
+func (s *journald) Log(msg *logger.Message) error {
43 43
 	if msg.Source == "stderr" {
44 44
 		return journal.Send(string(msg.Line), journal.PriErr, s.Jmap)
45 45
 	}
46 46
 	return journal.Send(string(msg.Line), journal.PriInfo, s.Jmap)
47 47
 }
48 48
 
49
-func (s *Journald) Close() error {
49
+func (s *journald) Close() error {
50 50
 	return nil
51 51
 }
52 52
 
53
-func (s *Journald) Name() string {
53
+func (s *journald) Name() string {
54 54
 	return name
55 55
 }
... ...
@@ -1,3 +1,6 @@
1
+// Package jsonfilelog provides the default Logger implementation for
2
+// Docker logging. This logger logs to files on the host server in the
3
+// JSON format.
1 4
 package jsonfilelog
2 5
 
3 6
 import (
... ...
@@ -23,12 +26,12 @@ import (
23 23
 )
24 24
 
25 25
 const (
26
+	// Name is the name of the file that the jsonlogger logs to.
26 27
 	Name               = "json-file"
27 28
 	maxJSONDecodeRetry = 10
28 29
 )
29 30
 
30
-// JSONFileLogger is Logger implementation for default docker logging:
31
-// JSON objects to file
31
+// JSONFileLogger is Logger implementation for default Docker logging.
32 32
 type JSONFileLogger struct {
33 33
 	buf          *bytes.Buffer
34 34
 	f            *os.File   // store for closing
... ...
@@ -49,7 +52,8 @@ func init() {
49 49
 	}
50 50
 }
51 51
 
52
-// New creates new JSONFileLogger which writes to filename
52
+// New creates new JSONFileLogger which writes to filename passed in
53
+// on given context.
53 54
 func New(ctx logger.Context) (logger.Logger, error) {
54 55
 	log, err := os.OpenFile(ctx.LogPath, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0600)
55 56
 	if err != nil {
... ...
@@ -63,14 +67,14 @@ func New(ctx logger.Context) (logger.Logger, error) {
63 63
 			return nil, err
64 64
 		}
65 65
 	}
66
-	var maxFiles int = 1
66
+	var maxFiles = 1
67 67
 	if maxFileString, ok := ctx.Config["max-file"]; ok {
68 68
 		maxFiles, err = strconv.Atoi(maxFileString)
69 69
 		if err != nil {
70 70
 			return nil, err
71 71
 		}
72 72
 		if maxFiles < 1 {
73
-			return nil, fmt.Errorf("max-files cannot be less than 1.")
73
+			return nil, fmt.Errorf("max-files cannot be less than 1")
74 74
 		}
75 75
 	}
76 76
 	return &JSONFileLogger{
... ...
@@ -84,7 +88,7 @@ func New(ctx logger.Context) (logger.Logger, error) {
84 84
 	}, nil
85 85
 }
86 86
 
87
-// Log converts logger.Message to jsonlog.JSONLog and serializes it to file
87
+// Log converts logger.Message to jsonlog.JSONLog and serializes it to file.
88 88
 func (l *JSONFileLogger) Log(msg *logger.Message) error {
89 89
 	l.mu.Lock()
90 90
 	defer l.mu.Unlock()
... ...
@@ -153,6 +157,7 @@ func rotate(name string, n int) error {
153 153
 	return nil
154 154
 }
155 155
 
156
+// backup renames a file from curr to old, creating an empty file curr if it does not exist.
156 157
 func backup(old, curr string) error {
157 158
 	if _, err := os.Stat(old); !os.IsNotExist(err) {
158 159
 		err := os.Remove(old)
... ...
@@ -170,6 +175,7 @@ func backup(old, curr string) error {
170 170
 	return os.Rename(curr, old)
171 171
 }
172 172
 
173
+// ValidateLogOpt looks for json specific log options max-file & max-size.
173 174
 func ValidateLogOpt(cfg map[string]string) error {
174 175
 	for key := range cfg {
175 176
 		switch key {
... ...
@@ -182,11 +188,12 @@ func ValidateLogOpt(cfg map[string]string) error {
182 182
 	return nil
183 183
 }
184 184
 
185
+// LogPath returns the location the given json logger logs to.
185 186
 func (l *JSONFileLogger) LogPath() string {
186 187
 	return l.ctx.LogPath
187 188
 }
188 189
 
189
-// Close closes underlying file and signals all readers to stop
190
+// Close closes underlying file and signals all readers to stop.
190 191
 func (l *JSONFileLogger) Close() error {
191 192
 	l.mu.Lock()
192 193
 	err := l.f.Close()
... ...
@@ -198,7 +205,7 @@ func (l *JSONFileLogger) Close() error {
198 198
 	return err
199 199
 }
200 200
 
201
-// Name returns name of this logger
201
+// Name returns name of this logger.
202 202
 func (l *JSONFileLogger) Name() string {
203 203
 	return Name
204 204
 }
... ...
@@ -216,7 +223,8 @@ func decodeLogLine(dec *json.Decoder, l *jsonlog.JSONLog) (*logger.Message, erro
216 216
 	return msg, nil
217 217
 }
218 218
 
219
-// Reads from the log file
219
+// ReadLogs implements the logger's LogReader interface for the logs
220
+// created by this driver.
220 221
 func (l *JSONFileLogger) ReadLogs(config logger.ReadConfig) *logger.LogWatcher {
221 222
 	logWatcher := logger.NewLogWatcher()
222 223
 
... ...
@@ -326,7 +334,7 @@ func followLogs(f *os.File, logWatcher *logger.LogWatcher, notifyRotate chan int
326 326
 				// try again because this shouldn't happen
327 327
 				if _, ok := err.(*json.SyntaxError); ok && retries <= maxJSONDecodeRetry {
328 328
 					dec = json.NewDecoder(f)
329
-					retries += 1
329
+					retries++
330 330
 					continue
331 331
 				}
332 332
 				logWatcher.Err <- err
... ...
@@ -1,3 +1,10 @@
1
+// Package logger defines interfaces that logger drivers implement to
2
+// log messages.
3
+//
4
+// The other half of a logger driver is the implementation of the
5
+// factory, which holds the contextual instance information that
6
+// allows multiple loggers of the same type to perform different
7
+// actions, such as logging to different locations.
1 8
 package logger
2 9
 
3 10
 import (
... ...
@@ -7,16 +14,16 @@ import (
7 7
 	"github.com/docker/docker/pkg/timeutils"
8 8
 )
9 9
 
10
-// ErrReadLogsNotSupported is returned when the logger does not support reading logs
10
+// ErrReadLogsNotSupported is returned when the logger does not support reading logs.
11 11
 var ErrReadLogsNotSupported = errors.New("configured logging reader does not support reading")
12 12
 
13 13
 const (
14
-	// TimeFormat is the time format used for timestamps sent to log readers
14
+	// TimeFormat is the time format used for timestamps sent to log readers.
15 15
 	TimeFormat           = timeutils.RFC3339NanoFixed
16 16
 	logWatcherBufferSize = 4096
17 17
 )
18 18
 
19
-// Message is datastructure that represents record from some container
19
+// Message is datastructure that represents record from some container.
20 20
 type Message struct {
21 21
 	ContainerID string
22 22
 	Line        []byte
... ...
@@ -24,31 +31,31 @@ type Message struct {
24 24
 	Timestamp   time.Time
25 25
 }
26 26
 
27
-// Logger is the interface for docker logging drivers
27
+// Logger is the interface for docker logging drivers.
28 28
 type Logger interface {
29 29
 	Log(*Message) error
30 30
 	Name() string
31 31
 	Close() error
32 32
 }
33 33
 
34
-// ReadConfig is the configuration passed into ReadLogs
34
+// ReadConfig is the configuration passed into ReadLogs.
35 35
 type ReadConfig struct {
36 36
 	Since  time.Time
37 37
 	Tail   int
38 38
 	Follow bool
39 39
 }
40 40
 
41
-// LogReader is the interface for reading log messages for loggers that support reading
41
+// LogReader is the interface for reading log messages for loggers that support reading.
42 42
 type LogReader interface {
43 43
 	// Read logs from underlying logging backend
44 44
 	ReadLogs(ReadConfig) *LogWatcher
45 45
 }
46 46
 
47
-// LogWatcher is used when consuming logs read from the LogReader interface
47
+// LogWatcher is used when consuming logs read from the LogReader interface.
48 48
 type LogWatcher struct {
49
-	// For sending log messages to a reader
49
+	// For sending log messages to a reader.
50 50
 	Msg chan *Message
51
-	// For sending error messages that occur while while reading logs
51
+	// For sending error messages that occur while while reading logs.
52 52
 	Err           chan error
53 53
 	closeNotifier chan struct{}
54 54
 }
... ...
@@ -62,13 +69,14 @@ func NewLogWatcher() *LogWatcher {
62 62
 	}
63 63
 }
64 64
 
65
-// Close notifies the underlying log reader to stop
65
+// Close notifies the underlying log reader to stop.
66 66
 func (w *LogWatcher) Close() {
67 67
 	close(w.closeNotifier)
68 68
 }
69 69
 
70
-// WatchClose returns a channel receiver that receives notification when the watcher has been closed
71
-// This should only be called from one goroutine
70
+// WatchClose returns a channel receiver that receives notification
71
+// when the watcher has been closed. This should only be called from
72
+// one goroutine.
72 73
 func (w *LogWatcher) WatchClose() <-chan struct{} {
73 74
 	return w.closeNotifier
74 75
 }
... ...
@@ -1,5 +1,6 @@
1 1
 // +build linux
2 2
 
3
+// Package syslog provides the logdriver for forwarding server logs to syslog endpoints.
3 4
 package syslog
4 5
 
5 6
 import (
... ...
@@ -43,7 +44,7 @@ var facilities = map[string]syslog.Priority{
43 43
 	"local7":   syslog.LOG_LOCAL7,
44 44
 }
45 45
 
46
-type Syslog struct {
46
+type syslogger struct {
47 47
 	writer *syslog.Writer
48 48
 }
49 49
 
... ...
@@ -56,6 +57,9 @@ func init() {
56 56
 	}
57 57
 }
58 58
 
59
+// New creates a syslog logger using the configuration passed in on
60
+// the context. Supported context configuration variables are
61
+// syslog-address, syslog-facility, & syslog-tag.
59 62
 func New(ctx logger.Context) (logger.Logger, error) {
60 63
 	tag := ctx.Config["syslog-tag"]
61 64
 	if tag == "" {
... ...
@@ -82,23 +86,23 @@ func New(ctx logger.Context) (logger.Logger, error) {
82 82
 		return nil, err
83 83
 	}
84 84
 
85
-	return &Syslog{
85
+	return &syslogger{
86 86
 		writer: log,
87 87
 	}, nil
88 88
 }
89 89
 
90
-func (s *Syslog) Log(msg *logger.Message) error {
90
+func (s *syslogger) Log(msg *logger.Message) error {
91 91
 	if msg.Source == "stderr" {
92 92
 		return s.writer.Err(string(msg.Line))
93 93
 	}
94 94
 	return s.writer.Info(string(msg.Line))
95 95
 }
96 96
 
97
-func (s *Syslog) Close() error {
97
+func (s *syslogger) Close() error {
98 98
 	return s.writer.Close()
99 99
 }
100 100
 
101
-func (s *Syslog) Name() string {
101
+func (s *syslogger) Name() string {
102 102
 	return name
103 103
 }
104 104
 
... ...
@@ -132,12 +136,14 @@ func parseAddress(address string) (string, string, error) {
132 132
 	return "", "", nil
133 133
 }
134 134
 
135
+// ValidateLogOpt looks for syslog specific log options
136
+// syslog-address, syslog-facility, & syslog-tag.
135 137
 func ValidateLogOpt(cfg map[string]string) error {
136 138
 	for key := range cfg {
137 139
 		switch key {
138 140
 		case "syslog-address":
139
-		case "syslog-tag":
140 141
 		case "syslog-facility":
142
+		case "syslog-tag":
141 143
 		default:
142 144
 			return fmt.Errorf("unknown log opt '%s' for syslog log driver", key)
143 145
 		}
... ...
@@ -22,6 +22,12 @@ packages=(
22 22
 	daemon/execdriver/native/template
23 23
 	daemon/graphdriver/aufs
24 24
 	daemon/graphdriver/devmapper
25
+	daemon/logger
26
+	daemon/logger/fluentd
27
+	daemon/logger/gelf
28
+	daemon/logger/journald
29
+	daemon/logger/jsonfilelog
30
+	daemon/logger/syslog
25 31
 	daemon/network
26 32
 	docker
27 33
 	dockerinit