1package csm
2
3import (
4	"fmt"
5	"sync"
6)
7
8var (
9	lock sync.Mutex
10)
11
12// Client side metric handler names
13const (
14	APICallMetricHandlerName        = "awscsm.SendAPICallMetric"
15	APICallAttemptMetricHandlerName = "awscsm.SendAPICallAttemptMetric"
16)
17
18// Start will start the a long running go routine to capture
19// client side metrics. Calling start multiple time will only
20// start the metric listener once and will panic if a different
21// client ID or port is passed in.
22//
23//	Example:
24//		r, err := csm.Start("clientID", "127.0.0.1:8094")
25//		if err != nil {
26//			panic(fmt.Errorf("expected no error, but received %v", err))
27//		}
28//		sess := session.NewSession()
29//		r.InjectHandlers(sess.Handlers)
30//
31//		svc := s3.New(sess)
32//		out, err := svc.GetObject(&s3.GetObjectInput{
33//			Bucket: aws.String("bucket"),
34//			Key: aws.String("key"),
35//		})
36func Start(clientID string, url string) (*Reporter, error) {
37	lock.Lock()
38	defer lock.Unlock()
39
40	if sender == nil {
41		sender = newReporter(clientID, url)
42	} else {
43		if sender.clientID != clientID {
44			panic(fmt.Errorf("inconsistent client IDs. %q was expected, but received %q", sender.clientID, clientID))
45		}
46
47		if sender.url != url {
48			panic(fmt.Errorf("inconsistent URLs. %q was expected, but received %q", sender.url, url))
49		}
50	}
51
52	if err := connect(url); err != nil {
53		sender = nil
54		return nil, err
55	}
56
57	return sender, nil
58}
59
60// Get will return a reporter if one exists, if one does not exist, nil will
61// be returned.
62func Get() *Reporter {
63	lock.Lock()
64	defer lock.Unlock()
65
66	return sender
67}
68