go.uber.org/yarpc@v1.72.1/transport/internal/tls/metrics/observer.go (about) 1 // Copyright (c) 2022 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package metrics 22 23 import ( 24 "crypto/tls" 25 26 "go.uber.org/net/metrics" 27 yarpctls "go.uber.org/yarpc/api/transport/tls" 28 "go.uber.org/zap" 29 ) 30 31 const ( 32 _serviceTag = "service" 33 _transportTag = "transport" 34 _versionTag = "version" 35 _destTag = "dest" 36 _directionTag = "direction" 37 _modeTag = "mode" 38 _componentTag = "component" 39 ) 40 41 // Params holds parameters needed for creating new observer. 42 type Params struct { 43 Meter *metrics.Scope 44 Logger *zap.Logger 45 ServiceName string // Name of the service. 46 TransportName string // Name of the transport. 47 Direction string // Inbound or Outbound. 48 Dest string // Name of the dest, only for outbound. 49 Mode yarpctls.Mode 50 } 51 52 // Observer holds connection metrics. 53 type Observer struct { 54 plaintextConnectionsCounter *metrics.Counter 55 tlsConnectionsCounter *metrics.CounterVector 56 tlsFailuresCounter *metrics.Counter 57 } 58 59 // NewObserver returns observer for emitting connection metrics. 60 func NewObserver(p Params) *Observer { 61 tags := metrics.Tags{ 62 _componentTag: "yarpc", 63 _serviceTag: p.ServiceName, 64 _transportTag: p.TransportName, 65 _modeTag: p.Mode.String(), 66 _directionTag: p.Direction, 67 _destTag: p.Dest, 68 } 69 70 plaintextConns, err := p.Meter.Counter(metrics.Spec{ 71 Name: "plaintext_connections", 72 Help: "Total number of plaintext connections established.", 73 ConstTags: tags, 74 }) 75 if err != nil { 76 p.Logger.Error("failed to create plaintext connections counter", zap.Error(err)) 77 } 78 79 tlsConns, err := p.Meter.CounterVector(metrics.Spec{ 80 Name: "tls_connections", 81 Help: "Total number of TLS connections established.", 82 ConstTags: tags, 83 VarTags: []string{_versionTag}, 84 }) 85 if err != nil { 86 p.Logger.Error("failed to create tls connections counter", zap.Error(err)) 87 } 88 89 tlsHandshakeFailures, err := p.Meter.Counter(metrics.Spec{ 90 Name: "tls_handshake_failures", 91 Help: "Total number of TLS handshake failures.", 92 ConstTags: tags, 93 }) 94 if err != nil { 95 p.Logger.Error("failed to create tls handshake failures counter", zap.Error(err)) 96 } 97 98 return &Observer{ 99 tlsConnectionsCounter: tlsConns, 100 tlsFailuresCounter: tlsHandshakeFailures, 101 plaintextConnectionsCounter: plaintextConns, 102 } 103 } 104 105 // IncPlaintextConnections increments plaintext connections metric. 106 func (o *Observer) IncPlaintextConnections() { 107 o.plaintextConnectionsCounter.Inc() 108 } 109 110 // IncTLSConnections increments TLS connections metric. 111 func (o *Observer) IncTLSConnections(version uint16) { 112 o.tlsConnectionsCounter.MustGet(_versionTag, tlsVersionString(version)).Inc() 113 } 114 115 // IncTLSHandshakeFailures increments TLS handshake failures metric. 116 func (o *Observer) IncTLSHandshakeFailures() { 117 o.tlsFailuresCounter.Inc() 118 } 119 120 func tlsVersionString(version uint16) string { 121 switch version { 122 case tls.VersionTLS10: 123 return "1.0" 124 case tls.VersionTLS11: 125 return "1.1" 126 case tls.VersionTLS12: 127 return "1.2" 128 case tls.VersionTLS13: 129 return "1.3" 130 default: 131 return "unknown" 132 } 133 }