github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/mongo/mongometrics/dialmetrics.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package mongometrics 5 6 import ( 7 "net" 8 "time" 9 10 "github.com/prometheus/client_golang/prometheus" 11 ) 12 13 const ( 14 serverLabel = "server" 15 timeoutLabel = "timeout" 16 ) 17 18 var dialLabels = []string{serverLabel, failedLabel, timeoutLabel} 19 20 // DalCollector is a prometheus.Collector that collects MongoDB 21 // connection dialing metrics from Juju code. 22 type DialCollector struct { 23 dialsTotal *prometheus.CounterVec 24 dialDuration *prometheus.SummaryVec 25 } 26 27 // NewDialCollector returns a new DialCollector. 28 func NewDialCollector() *DialCollector { 29 return &DialCollector{ 30 dialsTotal: prometheus.NewCounterVec(prometheus.CounterOpts{ 31 Namespace: "juju", 32 Name: "mongo_dials_total", 33 Help: "Total number of MongoDB server dials.", 34 }, dialLabels), 35 36 dialDuration: prometheus.NewSummaryVec(prometheus.SummaryOpts{ 37 Namespace: "juju", 38 Name: "mongo_dial_duration_seconds", 39 Help: "Time taken dialng MongoDB server.", 40 }, dialLabels), 41 } 42 } 43 44 // Describe is part of the prometheus.Collector interface. 45 func (c *DialCollector) Describe(ch chan<- *prometheus.Desc) { 46 c.dialsTotal.Describe(ch) 47 c.dialDuration.Describe(ch) 48 } 49 50 // Collect is part of the prometheus.Collector interface. 51 func (c *DialCollector) Collect(ch chan<- prometheus.Metric) { 52 c.dialsTotal.Collect(ch) 53 c.dialDuration.Collect(ch) 54 } 55 56 // PostDialServer is a function that may be used in 57 // mongo.DialOpts.PostDialServer, to update metrics. 58 func (c *DialCollector) PostDialServer(server string, duration time.Duration, dialErr error) { 59 var failedValue, timeoutValue string 60 if dialErr != nil { 61 // TODO(axw) attempt to distinguish more types of 62 // errors, e.g. failure due to TLS handshake vs. net 63 // dial. 64 failedValue = "failed" 65 if err, ok := dialErr.(*net.OpError); ok { 66 failedValue = err.Op 67 } 68 if err, ok := dialErr.(net.Error); ok { 69 if err.Timeout() { 70 timeoutValue = "timed out" 71 } 72 } 73 } 74 labels := prometheus.Labels{ 75 serverLabel: server, 76 failedLabel: failedValue, 77 timeoutLabel: timeoutValue, 78 } 79 c.dialsTotal.With(labels).Inc() 80 c.dialDuration.With(labels).Observe(duration.Seconds()) 81 }