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>
Upstream-commit: 7581cf96fbe0cddacf246f2982634190ebe455c9
Component: engine
This commit is contained in:
Yong Tang
2016-04-08 05:00:11 +00:00
parent f61a32826f
commit 6e179f4b7d
3 changed files with 23 additions and 3 deletions
@@ -76,9 +76,20 @@ func rfc5424formatterWithAppNameAsTag(p syslog.Priority, hostname, tag, content
return msg
}
// The timestamp field in rfc5424 is derived from rfc3339. Whereas rfc3339 makes allowances
// for multiple syntaxes, there are further restrictions in rfc5424, i.e., the maximium
// resolution is limited to "TIME-SECFRAC" which is 6 (microsecond resolution)
func rfc5424microformatterWithAppNameAsTag(p syslog.Priority, hostname, tag, content string) string {
timestamp := time.Now().Format("2006-01-02T15:04:05.999999Z07:00")
pid := os.Getpid()
msg := fmt.Sprintf("<%d>%d %s %s %s %d %s %s",
p, 1, timestamp, hostname, tag, pid, tag, content)
return msg
}
// New creates a syslog logger using the configuration passed in on
// the context. Supported context configuration variables are
// syslog-address, syslog-facility, & syslog-tag.
// syslog-address, syslog-facility, syslog-format, syslog-tag.
func New(ctx logger.Context) (logger.Logger, error) {
tag, err := loggerutils.ParseLogTag(ctx, "{{.ID}}")
if err != nil {
@@ -240,6 +251,8 @@ func parseLogFormat(logFormat string) (syslog.Formatter, syslog.Framer, error) {
return syslog.RFC3164Formatter, syslog.DefaultFramer, nil
case "rfc5424":
return rfc5424formatterWithAppNameAsTag, syslog.RFC5425MessageLengthFramer, nil
case "rfc5424micro":
return rfc5424microformatterWithAppNameAsTag, syslog.RFC5425MessageLengthFramer, nil
default:
return nil, nil, errors.New("Invalid syslog format")
}
@@ -19,6 +19,12 @@ func TestParseLogFormat(t *testing.T) {
t.Fatal("Failed to parse rfc5424 format", err, formatter, framer)
}
formatter, framer, err = parseLogFormat("rfc5424micro")
if err != nil || !functionMatches(rfc5424microformatterWithAppNameAsTag, formatter) ||
!functionMatches(syslog.RFC5425MessageLengthFramer, framer) {
t.Fatal("Failed to parse rfc5424 (microsecond) format", err, formatter, framer)
}
formatter, framer, err = parseLogFormat("rfc3164")
if err != nil || !functionMatches(syslog.RFC3164Formatter, formatter) ||
!functionMatches(syslog.DefaultFramer, framer) {