Skip to content

Commit

Permalink
Add fallback_formats for timestamp stage
Browse files Browse the repository at this point in the history
  • Loading branch information
winkingturtle-vmw committed Sep 25, 2020
1 parent ee67b9c commit d05a4ab
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 4 deletions.
6 changes: 6 additions & 0 deletions docs/sources/clients/promtail/stages/timestamp.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ timestamp:
# UnixMs UnixUs UnixNs].
format: <string>

# Fallback formats to try if the format fails to parse the value
# Can use pre-defined formats by name: [ANSIC UnixDate RubyDate RFC822
# RFC822Z RFC850 RFC1123 RFC1123Z RFC3339 RFC3339Nano Unix
# UnixMs UnixUs UnixNs].
[fallback_formats: []<string>]

# IANA Timezone Database string.
[location: <string>]

Expand Down
25 changes: 21 additions & 4 deletions pkg/logentry/stages/timestamp.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ var (

// TimestampConfig configures timestamp extraction
type TimestampConfig struct {
Source string `mapstructure:"source"`
Format string `mapstructure:"format"`
Location *string `mapstructure:"location"`
ActionOnFailure *string `mapstructure:"action_on_failure"`
Source string `mapstructure:"source"`
Format string `mapstructure:"format"`
FallbackFormats []string `mapstructure:"fallback_formats"`
Location *string `mapstructure:"location"`
ActionOnFailure *string `mapstructure:"action_on_failure"`
}

// parser can convert the time string into a time.Time value
Expand Down Expand Up @@ -82,6 +83,22 @@ func validateTimestampConfig(cfg *TimestampConfig) (parser, error) {
}
}

if len(cfg.FallbackFormats) > 0 {
multiConvertDateLayout := func(input string) (time.Time, error) {
orignalTime, originalErr := convertDateLayout(cfg.Format, loc)(input)
if originalErr == nil {
return orignalTime, originalErr
}
for i := 0; i < len(cfg.FallbackFormats); i++ {
if t, err := convertDateLayout(cfg.FallbackFormats[i], loc)(input); err == nil {
return t, err
}
}
return orignalTime, originalErr
}
return multiConvertDateLayout, nil
}

return convertDateLayout(cfg.Format, loc), nil
}

Expand Down
10 changes: 10 additions & 0 deletions pkg/logentry/stages/timestamp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,16 @@ func TestTimestampValidation(t *testing.T) {
},
err: fmt.Errorf(ErrInvalidActionOnFailure, TimestampActionOnFailureOptions),
},
"fallback formats contains the format": {
config: &TimestampConfig{
Source: "source1",
Format: "UnixMs",
FallbackFormats: []string{"2006-01-02 03:04:05.000000000 +0000 UTC", time.RFC3339},
},
err: nil,
testString: "2012-11-01T22:08:41-04:00",
expectedTime: time.Date(2012, 11, 01, 22, 8, 41, 0, time.FixedZone("", -4*60*60)),
},
}
for name, test := range tests {
test := test
Expand Down

0 comments on commit d05a4ab

Please sign in to comment.