Browse code

Additional syslog-format option to allow microsecond resolution in syslog timestamp.

This fix tries to add an additional syslog-format of `rfc5424micro` which follows
the same as rfc5424 except that it use microsecond resolution for timestamp. The
purpose is to solve the issue raised in #21793 where log events might lose its
ordering if happens on the same second.

The timestamp field in rfc5424 is derived from rfc3339, though the maximium
resolution is limited to "TIME-SECFRAC" which is 6 (microsecond resolution).

The appropriate documentation (`docs/admin/logging/overview.md`) has been updated
to reflect the change in this fix.

This fix adds a unit test to cover the newly introduced format.

This fix fixes #21793.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>

Yong Tang authored on 2016/04/07 15:03:28
Showing 3 changed files
... ...
@@ -76,9 +76,20 @@ func rfc5424formatterWithAppNameAsTag(p syslog.Priority, hostname, tag, content
76 76
 	return msg
77 77
 }
78 78
 
79
+// The timestamp field in rfc5424 is derived from rfc3339. Whereas rfc3339 makes allowances
80
+// for multiple syntaxes, there are further restrictions in rfc5424, i.e., the maximium
81
+// resolution is limited to "TIME-SECFRAC" which is 6 (microsecond resolution)
82
+func rfc5424microformatterWithAppNameAsTag(p syslog.Priority, hostname, tag, content string) string {
83
+	timestamp := time.Now().Format("2006-01-02T15:04:05.999999Z07:00")
84
+	pid := os.Getpid()
85
+	msg := fmt.Sprintf("<%d>%d %s %s %s %d %s %s",
86
+		p, 1, timestamp, hostname, tag, pid, tag, content)
87
+	return msg
88
+}
89
+
79 90
 // New creates a syslog logger using the configuration passed in on
80 91
 // the context. Supported context configuration variables are
81
-// syslog-address, syslog-facility, & syslog-tag.
92
+// syslog-address, syslog-facility, syslog-format,  syslog-tag.
82 93
 func New(ctx logger.Context) (logger.Logger, error) {
83 94
 	tag, err := loggerutils.ParseLogTag(ctx, "{{.ID}}")
84 95
 	if err != nil {
... ...
@@ -240,6 +251,8 @@ func parseLogFormat(logFormat string) (syslog.Formatter, syslog.Framer, error) {
240 240
 		return syslog.RFC3164Formatter, syslog.DefaultFramer, nil
241 241
 	case "rfc5424":
242 242
 		return rfc5424formatterWithAppNameAsTag, syslog.RFC5425MessageLengthFramer, nil
243
+	case "rfc5424micro":
244
+		return rfc5424microformatterWithAppNameAsTag, syslog.RFC5425MessageLengthFramer, nil
243 245
 	default:
244 246
 		return nil, nil, errors.New("Invalid syslog format")
245 247
 	}
... ...
@@ -19,6 +19,12 @@ func TestParseLogFormat(t *testing.T) {
19 19
 		t.Fatal("Failed to parse rfc5424 format", err, formatter, framer)
20 20
 	}
21 21
 
22
+	formatter, framer, err = parseLogFormat("rfc5424micro")
23
+	if err != nil || !functionMatches(rfc5424microformatterWithAppNameAsTag, formatter) ||
24
+		!functionMatches(syslog.RFC5425MessageLengthFramer, framer) {
25
+		t.Fatal("Failed to parse rfc5424 (microsecond) format", err, formatter, framer)
26
+	}
27
+
22 28
 	formatter, framer, err = parseLogFormat("rfc3164")
23 29
 	if err != nil || !functionMatches(syslog.RFC3164Formatter, formatter) ||
24 30
 		!functionMatches(syslog.DefaultFramer, framer) {
... ...
@@ -80,7 +80,7 @@ The following logging options are supported for the `syslog` logging driver:
80 80
     --log-opt syslog-tls-key=/etc/ca-certificates/custom/key.pem
81 81
     --log-opt syslog-tls-skip-verify=true
82 82
     --log-opt tag="mailer"
83
-    --log-opt syslog-format=[rfc5424|rfc3164] 
83
+    --log-opt syslog-format=[rfc5424|rfc5424micro|rfc3164]
84 84
 
85 85
 `syslog-address` specifies the remote syslog server address where the driver connects to.
86 86
 If not specified it defaults to the local unix socket of the running system.
... ...
@@ -135,7 +135,8 @@ the log tag format.
135 135
 `syslog-format` specifies syslog message format to use when logging.
136 136
 If not specified it defaults to the local unix syslog format without hostname specification.
137 137
 Specify rfc3164 to perform logging in RFC-3164 compatible format. Specify rfc5424 to perform 
138
-logging in RFC-5424 compatible format
138
+logging in RFC-5424 compatible format. Specify rfc5424micro to perform logging in RFC-5424
139
+compatible format with microsecond timestamp resolution.
139 140
 
140 141
 
141 142
 ## journald options