Skip to content

Commit bafe9dc

Browse files
fix(exporter): Ensure that timestamp are in second and not milliseconds (#2751)
* fix(exporter): Ensure that timestamp are in second and not milliseconds Signed-off-by: Thomas Poignant <[email protected]> * remove trailing line Signed-off-by: Thomas Poignant <[email protected]> * Adding a warning log Signed-off-by: Thomas Poignant <[email protected]> --------- Signed-off-by: Thomas Poignant <[email protected]>
1 parent c4059d1 commit bafe9dc

9 files changed

+87
-9
lines changed

cmd/relayproxy/api/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func (s *Server) initRoutes() {
9090
cAllFlags := controller.NewAllFlags(s.services.GOFeatureFlagService, s.services.Metrics)
9191
cFlagEval := controller.NewFlagEval(s.services.GOFeatureFlagService, s.services.Metrics)
9292
cFlagEvalOFREP := ofrep.NewOFREPEvaluate(s.services.GOFeatureFlagService, s.services.Metrics)
93-
cEvalDataCollector := controller.NewCollectEvalData(s.services.GOFeatureFlagService, s.services.Metrics)
93+
cEvalDataCollector := controller.NewCollectEvalData(s.services.GOFeatureFlagService, s.services.Metrics, s.zapLog)
9494
cRetrieverRefresh := controller.NewForceFlagsRefresh(s.services.GOFeatureFlagService, s.services.Metrics)
9595
cFlagChangeAPI := controller.NewAPIFlagChange(s.services.GOFeatureFlagService, s.services.Metrics)
9696

cmd/relayproxy/controller/collect_eval_data.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package controller
33
import (
44
"fmt"
55
"net/http"
6+
"strconv"
67

78
"github.com/labstack/echo/v4"
89
ffclient "github.com/thomaspoignant/go-feature-flag"
@@ -11,18 +12,21 @@ import (
1112
"github.com/thomaspoignant/go-feature-flag/cmd/relayproxy/model"
1213
"go.opentelemetry.io/otel"
1314
"go.opentelemetry.io/otel/attribute"
15+
"go.uber.org/zap"
1416
)
1517

1618
type collectEvalData struct {
1719
goFF *ffclient.GoFeatureFlag
1820
metrics metric.Metrics
21+
logger *zap.Logger
1922
}
2023

2124
// NewCollectEvalData initialize the controller for the /data/collector endpoint
22-
func NewCollectEvalData(goFF *ffclient.GoFeatureFlag, metrics metric.Metrics) Controller {
25+
func NewCollectEvalData(goFF *ffclient.GoFeatureFlag, metrics metric.Metrics, logger *zap.Logger) Controller {
2326
return &collectEvalData{
2427
goFF: goFF,
2528
metrics: metrics,
29+
logger: logger,
2630
}
2731
}
2832

@@ -51,7 +55,6 @@ func (h *collectEvalData) Handler(c echo.Context) error {
5155
if reqBody == nil || reqBody.Events == nil {
5256
return echo.NewHTTPError(http.StatusBadRequest, "collectEvalData: invalid input data")
5357
}
54-
5558
tracer := otel.GetTracerProvider().Tracer(config.OtelTracerName)
5659
_, span := tracer.Start(c.Request().Context(), "collectEventData")
5760
defer span.End()
@@ -60,6 +63,17 @@ func (h *collectEvalData) Handler(c echo.Context) error {
6063
if event.Source == "" {
6164
event.Source = "PROVIDER_CACHE"
6265
}
66+
// force the creation date to be a unix timestamp
67+
if event.CreationDate > 9999999999 {
68+
h.logger.Warn(
69+
"creationDate received is in milliseconds, we convert it to seconds",
70+
zap.Int64("creationDate", event.CreationDate))
71+
// if we receive a timestamp in milliseconds, we convert it to seconds
72+
// but since it is totally possible to have a timestamp in seconds that is bigger than 9999999999
73+
// we will accept timestamp up to 9999999999 (2286-11-20 18:46:39 +0100 CET)
74+
event.CreationDate, _ = strconv.ParseInt(
75+
strconv.FormatInt(event.CreationDate, 10)[:10], 10, 64)
76+
}
6377
h.goFF.CollectEventData(event)
6478
}
6579

cmd/relayproxy/controller/collect_eval_data_test.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@ import (
1414

1515
"github.com/labstack/echo/v4"
1616
"github.com/stretchr/testify/assert"
17+
"github.com/stretchr/testify/require"
1718
ffclient "github.com/thomaspoignant/go-feature-flag"
1819
"github.com/thomaspoignant/go-feature-flag/cmd/relayproxy/controller"
1920
"github.com/thomaspoignant/go-feature-flag/cmd/relayproxy/metric"
2021
"github.com/thomaspoignant/go-feature-flag/exporter/fileexporter"
2122
"github.com/thomaspoignant/go-feature-flag/retriever/fileretriever"
23+
"go.uber.org/zap"
2224
)
2325

2426
func Test_collect_eval_data_Handler(t *testing.T) {
@@ -86,6 +88,17 @@ func Test_collect_eval_data_Handler(t *testing.T) {
8688
errorCode: http.StatusBadRequest,
8789
},
8890
},
91+
{
92+
name: "be sure that the creation date is a unix timestamp",
93+
args: args{
94+
"../testdata/controller/collect_eval_data/valid_request_with_timestamp_ms.json",
95+
},
96+
want: want{
97+
httpCode: http.StatusOK,
98+
bodyFile: "../testdata/controller/collect_eval_data/valid_response.json",
99+
collectedDataFile: "../testdata/controller/collect_eval_data/valid_collected_data_with_timestamp_ms.json",
100+
},
101+
},
89102
}
90103
for _, tt := range tests {
91104
t.Run(tt.name, func(t *testing.T) {
@@ -107,7 +120,9 @@ func Test_collect_eval_data_Handler(t *testing.T) {
107120
Exporter: &fileexporter.Exporter{Filename: exporterFile.Name()},
108121
},
109122
})
110-
ctrl := controller.NewCollectEvalData(goFF, metric.Metrics{})
123+
logger, err := zap.NewDevelopment()
124+
require.NoError(t, err)
125+
ctrl := controller.NewCollectEvalData(goFF, metric.Metrics{}, logger)
111126

112127
e := echo.New()
113128
rec := httptest.NewRecorder()
@@ -154,7 +169,7 @@ func Test_collect_eval_data_Handler(t *testing.T) {
154169
assert.NoError(t, err, "Impossible the expected wantBody file %s", tt.want.bodyFile)
155170
assert.Equal(t, tt.want.httpCode, rec.Code, "Invalid HTTP Code")
156171
assert.JSONEq(t, string(wantBody), replacedStr, "Invalid response wantBody")
157-
assert.Equal(t, string(wantCollectData), string(exportedData), "Invalid exported data")
172+
assert.JSONEq(t, string(wantCollectData), string(exportedData), "Invalid exported data")
158173
})
159174
}
160175
}
Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,12 @@
1-
{"kind":"feature","contextKind":"user","userKey":"94a25909-20d8-40cc-8500-fee99b569345","creationDate":1680246000011,"key":"my-feature-flag","variation":"admin-variation","value":"string","default":false,"version":"v1.0.0","source":"EDGE"}
1+
{
2+
"kind": "feature",
3+
"contextKind": "user",
4+
"userKey": "94a25909-20d8-40cc-8500-fee99b569345",
5+
"creationDate": 1680246000,
6+
"key": "my-feature-flag",
7+
"variation": "admin-variation",
8+
"value": "string",
9+
"default": false,
10+
"version": "v1.0.0",
11+
"source": "EDGE"
12+
}

cmd/relayproxy/testdata/controller/collect_eval_data/request_with_source_field.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"events": [
33
{
44
"contextKind": "user",
5-
"creationDate": 1680246000011,
5+
"creationDate": 1680246000,
66
"default": false,
77
"key": "my-feature-flag",
88
"kind": "feature",
Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,12 @@
1-
{"kind":"feature","contextKind":"user","userKey":"94a25909-20d8-40cc-8500-fee99b569345","creationDate":1680246000011,"key":"my-feature-flag","variation":"admin-variation","value":"string","default":false,"version":"v1.0.0","source":"PROVIDER_CACHE"}
1+
{
2+
"kind": "feature",
3+
"contextKind": "user",
4+
"userKey": "94a25909-20d8-40cc-8500-fee99b569345",
5+
"creationDate": 1680246000,
6+
"key": "my-feature-flag",
7+
"variation": "admin-variation",
8+
"value": "string",
9+
"default": false,
10+
"version": "v1.0.0",
11+
"source": "PROVIDER_CACHE"
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"kind": "feature",
3+
"contextKind": "user",
4+
"userKey": "94a25909-20d8-40cc-8500-fee99b569345",
5+
"creationDate": 1733230547,
6+
"key": "my-feature-flag",
7+
"variation": "admin-variation",
8+
"value": "string",
9+
"default": false,
10+
"version": "v1.0.0",
11+
"source": "PROVIDER_CACHE"
12+
}

cmd/relayproxy/testdata/controller/collect_eval_data/valid_request.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"events": [
33
{
44
"contextKind": "user",
5-
"creationDate": 1680246000011,
5+
"creationDate": 1680246000,
66
"default": false,
77
"key": "my-feature-flag",
88
"kind": "feature",
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"events": [
3+
{
4+
"contextKind": "user",
5+
"creationDate": 1733230547728,
6+
"default": false,
7+
"key": "my-feature-flag",
8+
"kind": "feature",
9+
"userKey": "94a25909-20d8-40cc-8500-fee99b569345",
10+
"value": "string",
11+
"variation": "admin-variation",
12+
"version": "v1.0.0"
13+
}
14+
]
15+
}

0 commit comments

Comments
 (0)