-
Notifications
You must be signed in to change notification settings - Fork 23
/
client.go
155 lines (129 loc) · 3.59 KB
/
client.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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package xray
import (
"net/http"
"time"
"github.com/aws/aws-sdk-go/aws/session"
SDK "github.com/aws/aws-sdk-go/service/xray"
"github.com/evalphobia/aws-sdk-go-wrapper/config"
"github.com/evalphobia/aws-sdk-go-wrapper/log"
"github.com/evalphobia/aws-sdk-go-wrapper/private/errors"
)
const (
serviceName = "X-Ray"
)
// sampling all request and set sampling limit to 1000 req/s.
var defaultSamplingPolicy, _ = NewLimitedSampler(1, 1000)
// XRay has XRay client.
type XRay struct {
client *SDK.XRay
daemon *Daemon
sampling SamplingPolicy
logger log.Logger
prefix string
}
// New returns initialized *XRay.
func New(conf config.Config) (*XRay, error) {
sess, err := conf.Session()
if err != nil {
return nil, err
}
svc := NewFromSession(sess)
svc.prefix = conf.DefaultPrefix
return svc, nil
}
// NewFromSession returns initialized *XRay from aws.Session.
func NewFromSession(sess *session.Session) *XRay {
return &XRay{
client: SDK.New(sess),
logger: log.DefaultLogger,
sampling: defaultSamplingPolicy,
}
}
// GetClient gets aws client.
func (svc *XRay) GetClient() *SDK.XRay {
return svc.client
}
// SetLogger sets logger.
func (svc *XRay) SetLogger(logger log.Logger) {
svc.logger = logger
}
// SetPrefix sets prefix.
func (svc *XRay) SetPrefix(prefix string) {
svc.prefix = prefix
}
// SetSamplingPolicy sets sampling policy.
func (svc *XRay) SetSamplingPolicy(fraction, qps float64) error {
s, err := NewLimitedSampler(fraction, qps)
if err != nil {
svc.Errorf("error on SetSamplingPolicy; fraction=%f; qps=%f; error=%s;", fraction, qps, err.Error())
return err
}
svc.sampling = s
return nil
}
// AddSegment adds the segment dat into background daemon.
func (svc *XRay) AddSegment(segments ...*Segment) {
svc.daemon.Add(segments...)
}
// RunDaemon creates and runs background daemon.
func (svc *XRay) RunDaemon(size int, interval time.Duration) {
svc.daemon = NewDaemon(size, interval, svc.PutTraceSegments)
svc.daemon.Run()
}
// PutTraceSegments executes PutTraceSegments operation.
func (svc *XRay) PutTraceSegments(segments []*Segment) error {
if len(segments) == 0 {
return nil
}
errList := newErrors()
// divide segments slice into multiple slices to avoid 64kb limitation on X-Ray.
sep, err := createSegmentDivider(segments)
if err != nil {
svc.Errorf("error on createSegmentDivider(segments); error=%s;", err.Error())
errList.Add(err)
}
for _, list := range sep.list {
notProcessed, err := svc.client.PutTraceSegments(&SDK.PutTraceSegmentsInput{
TraceSegmentDocuments: list,
})
if err != nil {
_list := make([]string, len(list))
for i, s := range list {
_list[i] = *s
}
svc.Errorf("error on `PutTraceSegments` operation; segments=%v; error=%s;", _list, err.Error())
errList.Add(err)
}
_ = notProcessed // TODO
}
if errList.HasError() {
return errList
}
return nil
}
// NewSegment creates new Segment data with given name.
func (svc *XRay) NewSegment(name string) *Segment {
s := NewSegment(name)
s.service = svc
return s
}
// NewSegmentFromRequest creates new Segment data from *http.Request.
func (svc *XRay) NewSegmentFromRequest(r *http.Request) *Segment {
if !svc.sampling.CanSample() {
return NewEmptySegment()
}
s := NewSegmentFromRequest(r)
s.service = svc
return s
}
// Infof logging information.
func (svc *XRay) Infof(format string, v ...interface{}) {
svc.logger.Infof(serviceName, format, v...)
}
// Errorf logging error information.
func (svc *XRay) Errorf(format string, v ...interface{}) {
svc.logger.Errorf(serviceName, format, v...)
}
func newErrors() *errors.Errors {
return errors.NewErrors(serviceName)
}