Browse code

Fluentd: extract parsing config, and validate early

This extracts parsing the driver's configuration to a
function, and uses the same function both when initializing
the driver, and when validating logging options.

Doing so allows validating if the provided options are in
the correct format when calling `ValidateOpts`, instead
of resulting in an error when initializing the logging driver.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2019/04/16 18:56:20
Showing 1 changed files
... ...
@@ -3,7 +3,6 @@
3 3
 package fluentd // import "github.com/docker/docker/daemon/logger/fluentd"
4 4
 
5 5
 import (
6
-	"fmt"
7 6
 	"math"
8 7
 	"net"
9 8
 	"net/url"
... ...
@@ -70,7 +69,7 @@ func init() {
70 70
 // the context. The supported context configuration variable is
71 71
 // fluentd-address.
72 72
 func New(info logger.Info) (logger.Logger, error) {
73
-	loc, err := parseAddress(info.Config[addressKey])
73
+	fluentConfig, err := parseConfig(info.Config)
74 74
 	if err != nil {
75 75
 		return nil, errdefs.InvalidParameter(err)
76 76
 	}
... ...
@@ -85,59 +84,6 @@ func New(info logger.Info) (logger.Logger, error) {
85 85
 		return nil, errdefs.InvalidParameter(err)
86 86
 	}
87 87
 
88
-	bufferLimit := defaultBufferLimit
89
-	if info.Config[bufferLimitKey] != "" {
90
-		bl64, err := units.RAMInBytes(info.Config[bufferLimitKey])
91
-		if err != nil {
92
-			return nil, err
93
-		}
94
-		bufferLimit = int(bl64)
95
-	}
96
-
97
-	retryWait := defaultRetryWait
98
-	if info.Config[retryWaitKey] != "" {
99
-		rwd, err := time.ParseDuration(info.Config[retryWaitKey])
100
-		if err != nil {
101
-			return nil, err
102
-		}
103
-		retryWait = int(rwd.Seconds() * 1000)
104
-	}
105
-
106
-	maxRetries := defaultMaxRetries
107
-	if info.Config[maxRetriesKey] != "" {
108
-		mr64, err := strconv.ParseUint(info.Config[maxRetriesKey], 10, strconv.IntSize)
109
-		if err != nil {
110
-			return nil, err
111
-		}
112
-		maxRetries = int(mr64)
113
-	}
114
-
115
-	asyncConnect := false
116
-	if info.Config[asyncConnectKey] != "" {
117
-		if asyncConnect, err = strconv.ParseBool(info.Config[asyncConnectKey]); err != nil {
118
-			return nil, err
119
-		}
120
-	}
121
-
122
-	subSecondPrecision := false
123
-	if info.Config[subSecondPrecisionKey] != "" {
124
-		if subSecondPrecision, err = strconv.ParseBool(info.Config[subSecondPrecisionKey]); err != nil {
125
-			return nil, err
126
-		}
127
-	}
128
-
129
-	fluentConfig := fluent.Config{
130
-		FluentPort:         loc.port,
131
-		FluentHost:         loc.host,
132
-		FluentNetwork:      loc.protocol,
133
-		FluentSocketPath:   loc.path,
134
-		BufferLimit:        bufferLimit,
135
-		RetryWait:          retryWait,
136
-		MaxRetry:           maxRetries,
137
-		Async:              asyncConnect,
138
-		SubSecondPrecision: subSecondPrecision,
139
-	}
140
-
141 88
 	logrus.WithField("container", info.ContainerID).WithField("config", fluentConfig).
142 89
 		Debug("logging driver fluentd configured")
143 90
 
... ...
@@ -204,14 +150,78 @@ func ValidateLogOpt(cfg map[string]string) error {
204 204
 		case subSecondPrecisionKey:
205 205
 			// Accepted
206 206
 		default:
207
-			return fmt.Errorf("unknown log opt '%s' for fluentd log driver", key)
207
+			return errors.Errorf("unknown log opt '%s' for fluentd log driver", key)
208 208
 		}
209 209
 	}
210 210
 
211
-	_, err := parseAddress(cfg[addressKey])
211
+	_, err := parseConfig(cfg)
212 212
 	return err
213 213
 }
214 214
 
215
+func parseConfig(cfg map[string]string) (fluent.Config, error) {
216
+	var config fluent.Config
217
+
218
+	loc, err := parseAddress(cfg[addressKey])
219
+	if err != nil {
220
+		return config, err
221
+	}
222
+
223
+	bufferLimit := defaultBufferLimit
224
+	if cfg[bufferLimitKey] != "" {
225
+		bl64, err := units.RAMInBytes(cfg[bufferLimitKey])
226
+		if err != nil {
227
+			return config, err
228
+		}
229
+		bufferLimit = int(bl64)
230
+	}
231
+
232
+	retryWait := defaultRetryWait
233
+	if cfg[retryWaitKey] != "" {
234
+		rwd, err := time.ParseDuration(cfg[retryWaitKey])
235
+		if err != nil {
236
+			return config, err
237
+		}
238
+		retryWait = int(rwd.Seconds() * 1000)
239
+	}
240
+
241
+	maxRetries := defaultMaxRetries
242
+	if cfg[maxRetriesKey] != "" {
243
+		mr64, err := strconv.ParseUint(cfg[maxRetriesKey], 10, strconv.IntSize)
244
+		if err != nil {
245
+			return config, err
246
+		}
247
+		maxRetries = int(mr64)
248
+	}
249
+
250
+	asyncConnect := false
251
+	if cfg[asyncConnectKey] != "" {
252
+		if asyncConnect, err = strconv.ParseBool(cfg[asyncConnectKey]); err != nil {
253
+			return config, err
254
+		}
255
+	}
256
+
257
+	subSecondPrecision := false
258
+	if cfg[subSecondPrecisionKey] != "" {
259
+		if subSecondPrecision, err = strconv.ParseBool(cfg[subSecondPrecisionKey]); err != nil {
260
+			return config, err
261
+		}
262
+	}
263
+
264
+	config = fluent.Config{
265
+		FluentPort:         loc.port,
266
+		FluentHost:         loc.host,
267
+		FluentNetwork:      loc.protocol,
268
+		FluentSocketPath:   loc.path,
269
+		BufferLimit:        bufferLimit,
270
+		RetryWait:          retryWait,
271
+		MaxRetry:           maxRetries,
272
+		Async:              asyncConnect,
273
+		SubSecondPrecision: subSecondPrecision,
274
+	}
275
+
276
+	return config, nil
277
+}
278
+
215 279
 func parseAddress(address string) (*location, error) {
216 280
 	if address == "" {
217 281
 		return &location{