Skip to content

Commit

Permalink
feat: support to parse UNIX timestamp in log records
Browse files Browse the repository at this point in the history
  • Loading branch information
macrat committed Dec 20, 2022
1 parent fe1b083 commit cc02e93
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 9 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,7 @@ The log file of Ayd is stored in [JSON Lines](https://jsonlines.org/) format, en
Each record has at least 4 fields.

- `time` when status check started, in [RFC3339 format](https://tools.ietf.org/html/rfc3339) like `2001-02-30T16:05:06+00:00`.
Ayd can parse some variant formats like `2001-02-03 16:05:06+0000` or `20010203_160506Z`, and the UNIX time seconds.

- `status` of the record that `HEALTHY`, `DEGRADE`, `FAILURE`, `UNKNOWN`, or `ABORTED`.

Expand Down
13 changes: 9 additions & 4 deletions lib-ayd/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,15 @@ func (r *Record) UnmarshalJSON(data []byte) error {
if value, ok := raw["time"]; !ok {
return ayderr.New(ErrInvalidRecord, nil, "invalid record: time: missing required field")
} else {
if s, ok := value.(string); !ok {
return ayderr.New(ErrInvalidRecord, nil, "invalid record: time: should be a string")
} else if r.Time, err = ParseTime(s); err != nil {
return ayderr.New(ErrInvalidRecord, err, "invalid record: time")
switch v := value.(type) {
case float64:
r.Time = time.UnixMilli(int64(v * 1000))
case string:
if r.Time, err = ParseTime(v); err != nil {
return ayderr.New(ErrInvalidRecord, err, "invalid record: time")
}
default:
return ayderr.New(ErrInvalidRecord, nil, "invalid record: time: should be a string or a number")
}
delete(raw, "time")
}
Expand Down
27 changes: 22 additions & 5 deletions lib-ayd/record_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ func TestRecord(t *testing.T) {

tests := []struct {
String string
Encode string
Record ayd.Record
Error string
}{
Expand Down Expand Up @@ -88,7 +89,8 @@ func TestRecord(t *testing.T) {
},
},
{
String: `{"time":"2021-01-02T15:04:05+09:00", "status":"DEGRADE", "latency":1027.890, "target":"dummy:"}`,
String: `{"time":"2021-01-02 15:04:05+09:00", "status":"DEGRADE", "latency":1027.890, "target":"dummy:"}`,
Encode: `{"time":"2021-01-02T15:04:05+09:00", "status":"DEGRADE", "latency":1027.890, "target":"dummy:"}`,
Record: ayd.Record{
Time: time.Date(2021, 1, 2, 15, 4, 5, 0, tokyo),
Target: &ayd.URL{Scheme: "dummy"},
Expand All @@ -97,6 +99,17 @@ func TestRecord(t *testing.T) {
Latency: 1027890 * time.Microsecond,
},
},
{
String: `{"time":1641135845, "status":"HEALTHY", "latency":12.345, "target":"dummy:"}`,
Encode: `{"time":"2022-01-02T15:04:05Z", "status":"HEALTHY", "latency":12.345, "target":"dummy:"}`,
Record: ayd.Record{
Time: time.Date(2022, 1, 2, 15, 4, 5, 0, time.UTC),
Target: &ayd.URL{Scheme: "dummy"},
Status: ayd.StatusHealthy,
Message: "",
Latency: 12345 * time.Microsecond,
},
},
{
String: `{"time":"2021-01-02T15:04:05+09:00", "status":"HEALTHY", "latency":123abc, "target":"ping:example.com", "message":"hello world"}`,
Error: "invalid record: invalid character 'a' after object key:value pair",
Expand All @@ -122,8 +135,8 @@ func TestRecord(t *testing.T) {
Error: `invalid record: time: missing required field`,
},
{
String: `{"time":123, "status":"HEALTHY", "latency":123.456, "target":"ping:example.com", "message":"hello world"}`,
Error: `invalid record: time: should be a string`,
String: `{"time":{}, "status":"HEALTHY", "latency":123.456, "target":"ping:example.com", "message":"hello world"}`,
Error: `invalid record: time: should be a string or a number`,
},
{
String: `{"time":"2021-01-02T15:04:05+09:00", "status":null, "latency":123.456, "target":"ping:example.com", "message":"hello world"}`,
Expand Down Expand Up @@ -209,8 +222,12 @@ func TestRecord(t *testing.T) {
t.Errorf("unexpected extra\n%s", diff)
}

if tt.Record.String() != tt.String {
t.Errorf("expected: %#v\n but got: %#v", tt.String, tt.Record.String())
expect := tt.Encode
if expect == "" {
expect = tt.String
}
if tt.Record.String() != expect {
t.Errorf("expected: %#v\n but got: %#v", expect, tt.Record.String())
}
}
}
Expand Down

0 comments on commit cc02e93

Please sign in to comment.