vitess.io/vitess@v0.16.2/go/vt/discovery/tablet_health.go (about) 1 /* 2 Copyright 2020 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package discovery 18 19 import ( 20 "bytes" 21 "encoding/json" 22 "strings" 23 24 "vitess.io/vitess/go/vt/topo/topoproto" 25 26 "vitess.io/vitess/go/vt/vttablet/queryservice" 27 28 "google.golang.org/protobuf/proto" 29 30 "vitess.io/vitess/go/netutil" 31 "vitess.io/vitess/go/vt/proto/query" 32 "vitess.io/vitess/go/vt/proto/topodata" 33 ) 34 35 // TabletHealth represents simple tablet health data that is returned to users of healthcheck. 36 // No synchronization is required because we always return a copy. 37 type TabletHealth struct { 38 Conn queryservice.QueryService 39 Tablet *topodata.Tablet 40 Target *query.Target 41 Stats *query.RealtimeStats 42 PrimaryTermStartTime int64 43 LastError error 44 Serving bool 45 } 46 47 func (th *TabletHealth) MarshalJSON() ([]byte, error) { 48 return json.Marshal(&struct { 49 Key string 50 Tablet *topodata.Tablet 51 Name string 52 Target *query.Target 53 Up bool 54 Serving bool 55 PrimaryTermStartTime int64 56 TabletExternallyReparentedTimestamp int64 57 Stats *query.RealtimeStats 58 LastError error 59 }{ 60 // The Key and Name fields are fields that used to live in the legacy tablet health 61 // TODO: remove Key and Name in v15 62 Key: TabletToMapKey(th.Tablet), 63 Tablet: th.Tablet, 64 Name: topoproto.TabletAliasString(th.Tablet.Alias), 65 Target: th.Target, 66 67 // Setting Up to true to ensure backward compatibility 68 // TODO: remove Up in v15 69 Up: true, 70 71 Serving: th.Serving, 72 73 // We copy the PrimaryTermStartTime value onto TabletExternallyReparentedTimestamp to 74 // ensure backward compatibility. 75 // TODO: remove Up in v15 76 PrimaryTermStartTime: th.PrimaryTermStartTime, 77 TabletExternallyReparentedTimestamp: th.PrimaryTermStartTime, 78 79 Stats: th.Stats, 80 LastError: th.LastError, 81 }) 82 } 83 84 // DeepEqual compares two TabletHealth. Since we include protos, we 85 // need to use proto.Equal on these. 86 func (th *TabletHealth) DeepEqual(other *TabletHealth) bool { 87 return proto.Equal(th.Tablet, other.Tablet) && 88 proto.Equal(th.Target, other.Target) && 89 th.Serving == other.Serving && 90 th.PrimaryTermStartTime == other.PrimaryTermStartTime && 91 proto.Equal(th.Stats, other.Stats) && 92 ((th.LastError == nil && other.LastError == nil) || 93 (th.LastError != nil && other.LastError != nil && th.LastError.Error() == other.LastError.Error())) 94 } 95 96 // GetTabletHostPort formats a tablet host port address. 97 func (th *TabletHealth) GetTabletHostPort() string { 98 hostname := th.Tablet.Hostname 99 vtPort := th.Tablet.PortMap["vt"] 100 return netutil.JoinHostPort(hostname, vtPort) 101 } 102 103 // GetHostNameLevel returns the specified hostname level. If the level does not exist it will pick the closest level. 104 // This seems unused but can be utilized by certain url formatting templates. See getTabletDebugURL for more details. 105 func (th *TabletHealth) GetHostNameLevel(level int) string { 106 hostname := th.Tablet.Hostname 107 chunkedHostname := strings.Split(hostname, ".") 108 109 if level < 0 { 110 return chunkedHostname[0] 111 } else if level >= len(chunkedHostname) { 112 return chunkedHostname[len(chunkedHostname)-1] 113 } else { 114 return chunkedHostname[level] 115 } 116 } 117 118 // getTabletDebugURL formats a debug url to the tablet. 119 // It uses a format string that can be passed into the app to format 120 // the debug URL to accommodate different network setups. It applies 121 // the html/template string defined to a tabletHealthCheck object. The 122 // format string can refer to members and functions of tabletHealthCheck 123 // like a regular html/template string. 124 // 125 // For instance given a tablet with hostname:port of host.dc.domain:22 126 // could be configured as follows: 127 // http://{{.GetTabletHostPort}} -> http://host.dc.domain:22 128 // https://{{.Tablet.Hostname}} -> https://host.dc.domain 129 // https://{{.GetHostNameLevel 0}}.bastion.corp -> https://host.bastion.corp 130 func (th *TabletHealth) getTabletDebugURL() string { 131 var buffer bytes.Buffer 132 _ = tabletURLTemplate.Execute(&buffer, th) 133 return buffer.String() 134 }