@@ -3,6 +3,10 @@ package ofrep
3
3
import (
4
4
"encoding/json"
5
5
"fmt"
6
+ "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
7
+ "go.opentelemetry.io/otel"
8
+ "go.opentelemetry.io/otel/attribute"
9
+ "go.opentelemetry.io/otel/trace"
6
10
"net/http"
7
11
8
12
"github.com/gorilla/mux"
@@ -23,25 +27,29 @@ type handler struct {
23
27
Logger * logger.Logger
24
28
evaluator evaluator.IEvaluator
25
29
contextValues map [string ]any
30
+ tracer trace.Tracer
26
31
}
27
32
28
33
func NewOfrepHandler (logger * logger.Logger , evaluator evaluator.IEvaluator , contextValues map [string ]any ) http.Handler {
29
34
h := handler {
30
35
Logger : logger ,
31
36
evaluator : evaluator ,
32
37
contextValues : contextValues ,
38
+ tracer : otel .Tracer ("flagd.ofrep.v1" ),
33
39
}
34
40
35
41
router := mux .NewRouter ()
36
42
router .HandleFunc (singleEvaluation , h .HandleFlagEvaluation ).Methods ("POST" )
37
43
router .HandleFunc (bulkEvaluation , h .HandleBulkEvaluation ).Methods ("POST" )
38
- return router
44
+ return otelhttp . NewHandler ( router , "flagd.ofrep" )
39
45
}
40
46
41
47
func (h * handler ) HandleFlagEvaluation (w http.ResponseWriter , r * http.Request ) {
42
48
requestID := xid .New ().String ()
43
49
defer h .Logger .ClearFields (requestID )
44
50
51
+ rCtx , span := h .tracer .Start (r .Context (), "flagEvaluation" , trace .WithSpanKind (trace .SpanKindServer ))
52
+ defer span .End ()
45
53
// obtain flag key
46
54
vars := mux .Vars (r )
47
55
if vars == nil {
@@ -57,9 +65,10 @@ func (h *handler) HandleFlagEvaluation(w http.ResponseWriter, r *http.Request) {
57
65
h .writeJSONToResponse (http .StatusBadRequest , ofrep .ContextErrorResponseFrom (flagKey ), w )
58
66
return
59
67
}
60
-
61
68
context := flagdContext (h .Logger , requestID , request , h .contextValues )
62
- evaluation := h .evaluator .ResolveAsAnyValue (r .Context (), requestID , flagKey , context )
69
+ evaluation := h .evaluator .ResolveAsAnyValue (rCtx , requestID , flagKey , context )
70
+ span .SetAttributes (attribute .String ("feature_flag.key" , evaluation .FlagKey ))
71
+ span .SetAttributes (attribute .String ("feature_flag.variant" , evaluation .Variant ))
63
72
if evaluation .Error != nil {
64
73
status , evaluationError := ofrep .EvaluationErrorResponseFrom (evaluation )
65
74
h .writeJSONToResponse (status , evaluationError , w )
@@ -72,21 +81,24 @@ func (h *handler) HandleBulkEvaluation(w http.ResponseWriter, r *http.Request) {
72
81
requestID := xid .New ().String ()
73
82
defer h .Logger .ClearFields (requestID )
74
83
84
+ rCtx , span := h .tracer .Start (r .Context (), "bulkEvaluation" , trace .WithSpanKind (trace .SpanKindServer ))
85
+ defer span .End ()
75
86
request , err := extractOfrepRequest (r )
76
87
if err != nil {
77
88
h .writeJSONToResponse (http .StatusBadRequest , ofrep .BulkEvaluationContextError (), w )
78
89
return
79
90
}
80
91
81
92
context := flagdContext (h .Logger , requestID , request , h .contextValues )
82
- evaluations , metadata , err := h .evaluator .ResolveAllValues (r . Context () , requestID , context )
93
+ evaluations , metadata , err := h .evaluator .ResolveAllValues (rCtx , requestID , context )
83
94
if err != nil {
84
95
h .Logger .WarnWithID (requestID , fmt .Sprintf ("error from resolver: %v" , err ))
85
96
86
97
res := ofrep .BulkEvaluationContextErrorFrom (model .GeneralErrorCode ,
87
98
fmt .Sprintf ("Bulk evaluation failed. Tracking ID: %s" , requestID ))
88
99
h .writeJSONToResponse (http .StatusInternalServerError , res , w )
89
100
} else {
101
+ span .SetAttributes (attribute .Int ("feature_flag.count" , len (evaluations )))
90
102
h .writeJSONToResponse (http .StatusOK , ofrep .BulkEvaluationResponseFrom (evaluations , metadata ), w )
91
103
}
92
104
}
0 commit comments