@@ -100,7 +100,8 @@ func (as *AnalyticsService) startTimer(ctx context.Context) {
100100 for {
101101 select {
102102 case <- time .After (as .timeout ):
103- as .sendDataAndResetCache (ctx )
103+ timeStamp := time .Now ().UnixNano () / (int64 (time .Millisecond ) / int64 (time .Nanosecond ))
104+ as .sendDataAndResetCache (ctx , timeStamp )
104105 case <- ctx .Done ():
105106 as .logger .Infof ("%s Metrics stopped" , sdk_codes .MetricsStopped )
106107 return
@@ -197,7 +198,7 @@ func convertInterfaceToString(i interface{}) string {
197198 }
198199}
199200
200- func (as * AnalyticsService ) sendDataAndResetCache (ctx context.Context ) {
201+ func (as * AnalyticsService ) sendDataAndResetCache (ctx context.Context , timeStamp int64 ) {
201202
202203 // Clone and reset the evaluation analytics cache to minimise the duration
203204 // for which locks are held, so that metrics processing does not affect flag evaluations performance.
@@ -215,45 +216,11 @@ func (as *AnalyticsService) sendDataAndResetCache(ctx context.Context) {
215216 as .logEvaluationLimitReached .Store (false )
216217 as .logTargetLimitReached .Store (false )
217218
218- metricData := make ([]metricsclient.MetricsData , 0 , evaluationAnalyticsClone .size ())
219- targetData := make ([]metricsclient.TargetData , 0 , targetAnalyticsClone .size ())
220-
221219 // Process evaluation metrics
222- evaluationAnalyticsClone .iterate (func (key string , analytic analyticsEvent ) {
223- metricAttributes := []metricsclient.KeyValue {
224- {Key : featureIdentifierAttribute , Value : analytic .featureConfig .Feature },
225- {Key : featureNameAttribute , Value : analytic .featureConfig .Feature },
226- {Key : variationIdentifierAttribute , Value : analytic .variation .Identifier },
227- {Key : variationValueAttribute , Value : analytic .variation .Value },
228- {Key : sdkTypeAttribute , Value : sdkType },
229- {Key : sdkLanguageAttribute , Value : sdkLanguage },
230- {Key : sdkVersionAttribute , Value : SdkVersion },
231- {Key : targetAttribute , Value : globalTarget },
232- }
233-
234- md := metricsclient.MetricsData {
235- Timestamp : time .Now ().UnixNano () / (int64 (time .Millisecond ) / int64 (time .Nanosecond )),
236- Count : analytic .count ,
237- MetricsType : metricsclient .MetricsDataMetricsType (ffMetricType ),
238- Attributes : metricAttributes ,
239- }
240- metricData = append (metricData , md )
241- })
220+ metricData := as .processEvaluationMetrics (evaluationAnalyticsClone , timeStamp )
242221
243222 // Process target metrics
244- targetAnalyticsClone .iterate (func (key string , target evaluation.Target ) {
245- targetAttributes := make ([]metricsclient.KeyValue , 0 )
246- for key , value := range * target .Attributes {
247- targetAttributes = append (targetAttributes , metricsclient.KeyValue {Key : key , Value : convertInterfaceToString (value )})
248- }
249-
250- td := metricsclient.TargetData {
251- Identifier : target .Identifier ,
252- Name : target .Name ,
253- Attributes : targetAttributes ,
254- }
255- targetData = append (targetData , td )
256- })
223+ targetData := as .processTargetMetrics (targetAnalyticsClone )
257224
258225 analyticsPayload := metricsclient.PostMetricsJSONRequestBody {
259226 MetricsData : & metricData ,
@@ -298,6 +265,55 @@ func (as *AnalyticsService) sendDataAndResetCache(ctx context.Context) {
298265 }
299266}
300267
268+ func (as * AnalyticsService ) processEvaluationMetrics (evaluationAnalytics SafeAnalyticsCache [string , analyticsEvent ], timeStamp int64 ) []metricsclient.MetricsData {
269+ metricData := make ([]metricsclient.MetricsData , 0 , evaluationAnalytics .size ())
270+ evaluationAnalytics .iterate (func (key string , analytic analyticsEvent ) {
271+ metricAttributes := []metricsclient.KeyValue {
272+ {Key : featureIdentifierAttribute , Value : analytic .featureConfig .Feature },
273+ {Key : featureNameAttribute , Value : analytic .featureConfig .Feature },
274+ {Key : variationIdentifierAttribute , Value : analytic .variation .Identifier },
275+ {Key : variationValueAttribute , Value : analytic .variation .Value },
276+ {Key : sdkTypeAttribute , Value : sdkType },
277+ {Key : sdkLanguageAttribute , Value : sdkLanguage },
278+ {Key : sdkVersionAttribute , Value : SdkVersion },
279+ {Key : targetAttribute , Value : globalTarget },
280+ }
281+
282+ md := metricsclient.MetricsData {
283+ Timestamp : timeStamp ,
284+ Count : analytic .count ,
285+ MetricsType : metricsclient .MetricsDataMetricsType (ffMetricType ),
286+ Attributes : metricAttributes ,
287+ }
288+ metricData = append (metricData , md )
289+ })
290+
291+ return metricData
292+ }
293+
294+ func (as * AnalyticsService ) processTargetMetrics (targetAnalytics SafeAnalyticsCache [string , evaluation.Target ]) []metricsclient.TargetData {
295+ targetData := make ([]metricsclient.TargetData , 0 , targetAnalytics .size ())
296+
297+ targetAnalytics .iterate (func (key string , target evaluation.Target ) {
298+ targetAttributes := make ([]metricsclient.KeyValue , 0 )
299+ if target .Attributes != nil {
300+ targetAttributes = make ([]metricsclient.KeyValue , 0 , len (* target .Attributes ))
301+ for k , v := range * target .Attributes {
302+ targetAttributes = append (targetAttributes , metricsclient.KeyValue {Key : k , Value : convertInterfaceToString (v )})
303+ }
304+ }
305+
306+ td := metricsclient.TargetData {
307+ Identifier : target .Identifier ,
308+ Name : target .Name ,
309+ Attributes : targetAttributes ,
310+ }
311+ targetData = append (targetData , td )
312+ })
313+
314+ return targetData
315+ }
316+
301317func getEvaluationAnalyticKey (event analyticsEvent ) string {
302318 return fmt .Sprintf ("%s-%s-%s-%s" , event .featureConfig .Feature , event .variation .Identifier , event .variation .Value , globalTarget )
303319}
0 commit comments