Promtail: support unix timestamps with fractional seconds (#2301)

* support unix timestamps with fractional seconds

see #2193

* add test for parsing unix timestamp with fractions

* mention Unix timestamp with fractions in docs

* return error if timestamp is not split into two parts

* don't capitalize error

Co-authored-by: Cyril Tovena <cyril.tovena@gmail.com>

Co-authored-by: Cyril Tovena <cyril.tovena@gmail.com>
pull/2305/head
Felix Ruess 5 years ago committed by GitHub
parent 3defe3a5bd
commit 616771aeff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      docs/clients/promtail/stages/timestamp.md
  2. 22
      pkg/logentry/stages/timestamp_test.go
  3. 17
      pkg/logentry/stages/util.go

@ -44,7 +44,7 @@ of pre-defined formats to represent common forms:
Additionally, support for common Unix timestamps is supported with the following
`format` values:
- `Unix`: `1562708916`
- `Unix`: `1562708916` or with fractions `1562708916.000000123`
- `UnixMs`: `1562708916414`
- `UnixUs`: `1562708916414123`
- `UnixNs`: `1562708916000000123`

@ -223,6 +223,28 @@ func TestTimestampStage_Process(t *testing.T) {
},
time.Date(2019, 7, 9, 21, 48, 36, 0, time.UTC),
},
"unix fractions ms success": {
TimestampConfig{
Source: "ts",
Format: "Unix",
},
map[string]interface{}{
"somethigelse": "notimportant",
"ts": "1562708916.414123",
},
time.Date(2019, 7, 9, 21, 48, 36, 414123*1000, time.UTC),
},
"unix fractions ns success": {
TimestampConfig{
Source: "ts",
Format: "Unix",
},
map[string]interface{}{
"somethigelse": "notimportant",
"ts": "1562708916.000000123",
},
time.Date(2019, 7, 9, 21, 48, 36, 123, time.UTC),
},
"unix millisecond success": {
TimestampConfig{
Source: "ts",

@ -2,6 +2,7 @@ package stages
import (
"fmt"
"math"
"strconv"
"strings"
"time"
@ -64,6 +65,22 @@ func convertDateLayout(predef string, location *time.Location) parser {
}
case "Unix":
return func(t string) (time.Time, error) {
if strings.Count(t, ".") == 1 {
split := strings.Split(t, ".")
if len(split) != 2 {
return time.Time{}, fmt.Errorf("can't split %v into two parts", t)
}
sec, err := strconv.ParseInt(split[0], 10, 64)
if err != nil {
return time.Time{}, err
}
frac, err := strconv.ParseInt(split[1], 10, 64)
if err != nil {
return time.Time{}, err
}
nsec := int64(float64(frac) * math.Pow(10, float64(9-len(split[1]))))
return time.Unix(sec, nsec), nil
}
i, err := strconv.ParseInt(t, 10, 64)
if err != nil {
return time.Time{}, err

Loading…
Cancel
Save