This repository has been archived by the owner on Jan 25, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtracer.go
78 lines (63 loc) · 2.15 KB
/
tracer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package highlight
// This schema/arch is taken from: https://github.com/99designs/gqlgen/blob/master/graphql/handler/apollotracing/tracer.go
import (
"context"
"fmt"
"github.com/99designs/gqlgen/graphql"
)
type GraphqlTracer interface {
graphql.HandlerExtension
graphql.ResponseInterceptor
graphql.FieldInterceptor
}
type Tracer struct {
graphName string
}
func NewGraphqlTracer(graphName string) GraphqlTracer {
return Tracer{graphName: graphName}
}
func (t Tracer) ExtensionName() string {
return "HighlightTracer"
}
func (t Tracer) Validate(graphql.ExecutableSchema) error {
return nil
}
// InterceptField instruments timing of individual fields resolved.
func (t Tracer) InterceptField(ctx context.Context, next graphql.Resolver) (interface{}, error) {
// if we don't have a highlight session in the context, no point trying to
// instrument since we won't be able to store the metric
if _, _, err := validateRequest(ctx); err != nil {
return next(ctx)
}
fc := graphql.GetFieldContext(ctx)
name := fmt.Sprintf("operation.field.%s", fc.Field.Name)
start := graphql.Now()
res, err := next(ctx)
end := graphql.Now()
RecordMetric(ctx, name+".duration", end.Sub(start).Seconds())
return res, err
}
// InterceptResponse instruments timing, payload size, and error information
// of the response handler. The metric is grouped by the corresponding operation name.
func (t Tracer) InterceptResponse(ctx context.Context, next graphql.ResponseHandler) *graphql.Response {
// if we don't have a highlight session in the context, no point trying to
// instrument since we won't be able to store the metric
if _, _, err := validateRequest(ctx); err != nil {
return next(ctx)
}
rc := graphql.GetOperationContext(ctx)
opName := "undefined"
if rc != nil && rc.Operation != nil {
opName = rc.OperationName
}
name := fmt.Sprintf("graphql.operation.%s", opName)
RecordMetric(ctx, name+".size", float64(len(rc.RawQuery)))
start := graphql.Now()
resp := next(ctx)
end := graphql.Now()
RecordMetric(ctx, name+".duration", end.Sub(start).Seconds())
if resp.Errors != nil {
RecordMetric(ctx, name+".errorsCount", float64(len(resp.Errors)))
}
return resp
}