forked from gomods/athens
-
Notifications
You must be signed in to change notification settings - Fork 0
/
stats.go
executable file
·110 lines (94 loc) · 3.04 KB
/
stats.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
package observ
import (
"fmt"
"net/http"
"time"
"contrib.go.opencensus.io/exporter/prometheus"
"contrib.go.opencensus.io/exporter/stackdriver"
datadog "github.com/DataDog/opencensus-go-exporter-datadog"
"github.com/gomods/athens/pkg/errors"
"github.com/gorilla/mux"
"go.opencensus.io/plugin/ochttp"
"go.opencensus.io/stats/view"
)
// RegisterStatsExporter determines the type of StatsExporter service for exporting stats from Opencensus
// Currently it supports: prometheus.
func RegisterStatsExporter(r *mux.Router, statsExporter, service string) (func(), error) {
const op errors.Op = "observ.RegisterStatsExporter"
stop := func() {}
var err error
switch statsExporter {
case "prometheus":
if err := registerPrometheusExporter(r, service); err != nil {
return nil, errors.E(op, err)
}
case "stackdriver":
if stop, err = registerStatsStackDriverExporter(service); err != nil {
return nil, errors.E(op, err)
}
case "datadog":
if stop, err = registerStatsDataDogExporter(service); err != nil {
return nil, errors.E(op, err)
}
case "":
return nil, errors.E(op, "StatsExporter not specified. Stats won't be collected")
default:
return nil, errors.E(op, fmt.Sprintf("StatsExporter %s not supported. Please open PR or an issue at github.com/gomods/athens", statsExporter))
}
if err = registerViews(); err != nil {
return nil, errors.E(op, err)
}
return stop, nil
}
// registerPrometheusExporter creates exporter that collects stats for Prometheus.
func registerPrometheusExporter(r *mux.Router, service string) error {
const op errors.Op = "observ.registerPrometheusExporter"
prom, err := prometheus.NewExporter(prometheus.Options{
Namespace: service,
})
if err != nil {
return errors.E(op, err)
}
r.Handle("/metrics", prom).Methods(http.MethodGet)
view.RegisterExporter(prom)
return nil
}
func registerStatsDataDogExporter(service string) (func(), error) {
const op errors.Op = "observ.registerStatsDataDogExporter"
dd := datadog.NewExporter(datadog.Options{Service: service})
if dd == nil {
return nil, errors.E(op, "Failed to initialize data dog exporter")
}
view.RegisterExporter(dd)
return dd.Stop, nil
}
func registerStatsStackDriverExporter(projectID string) (func(), error) {
const op errors.Op = "observ.registerStatsStackDriverExporter"
sd, err := stackdriver.NewExporter(stackdriver.Options{
ProjectID: projectID,
})
if err != nil {
return nil, errors.E(op, err)
}
view.RegisterExporter(sd)
view.SetReportingPeriod(60 * time.Second)
return sd.Flush, nil
}
// registerViews register stats which should be collected in Athens.
func registerViews() error {
const op errors.Op = "observ.registerViews"
if err := view.Register(
ochttp.ServerRequestCountView,
ochttp.ServerResponseBytesView,
ochttp.ServerLatencyView,
ochttp.ServerResponseCountByStatusCode,
ochttp.ServerRequestBytesView,
ochttp.ServerRequestCountByMethod,
ochttp.ClientReceivedBytesDistribution,
ochttp.ClientRoundtripLatencyDistribution,
ochttp.ClientCompletedCount,
); err != nil {
return errors.E(op, err)
}
return nil
}