Skip to content

Commit 3e8cdb6

Browse files
committed
Add TO Go cdns/health, cdns/name/health
1 parent e3c48b6 commit 3e8cdb6

File tree

9 files changed

+337
-106
lines changed

9 files changed

+337
-106
lines changed

lib/go-tc/traffic_monitor.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,3 +229,15 @@ func TrafficMonitorTransformToMap(tmConfig *TrafficMonitorConfig) (*TrafficMonit
229229

230230
return &tm, nil
231231
}
232+
233+
type HealthData struct {
234+
TotalOffline uint64 `json:"totalOffline"`
235+
TotalOnline uint64 `json:"totalOnline"`
236+
CacheGroups []HealthDataCacheGroup `json:"cachegroups"`
237+
}
238+
239+
type HealthDataCacheGroup struct {
240+
Offline int64 `json:"offline"`
241+
Online int64 `json:"online"`
242+
Name CacheGroupName `json:"name"`
243+
}

lib/go-util/num.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,3 +177,12 @@ func HashInts(ints []int, sortIntsBeforeHashing bool) []byte {
177177
bts := sha512.Sum512(buf)
178178
return bts[:]
179179
}
180+
181+
// IntSliceToMap creates an int set from an array.
182+
func IntSliceToMap(s []int) map[int]struct{} {
183+
m := map[int]struct{}{}
184+
for _, v := range s {
185+
m[v] = struct{}{}
186+
}
187+
return m
188+
}

traffic_ops/traffic_ops_golang/cachesstats/cachesstats.go

Lines changed: 5 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,18 @@ package cachesstats
2020
*/
2121

2222
import (
23-
"crypto/tls"
2423
"database/sql"
2524
"encoding/json"
2625
"errors"
2726
"net/http"
28-
"net/url"
2927
"strconv"
3028
"time"
3129

3230
"github.com/apache/trafficcontrol/lib/go-log"
3331
"github.com/apache/trafficcontrol/lib/go-tc"
3432
"github.com/apache/trafficcontrol/lib/go-util"
3533
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
34+
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/util/monitorhlp"
3635
)
3736

3837
func Get(w http.ResponseWriter, r *http.Request) {
@@ -56,25 +55,9 @@ func getCachesStats(tx *sql.Tx) ([]CacheData, error) {
5655
return nil, errors.New("getting monitors: " + err.Error())
5756
}
5857

59-
monitorForwardProxy, monitorForwardProxyExists, err := getGlobalParam(tx, MonitorProxyParameter)
58+
client, err := monitorhlp.GetClient(tx)
6059
if err != nil {
61-
return nil, errors.New("getting global monitor proxy parameter: " + err.Error())
62-
}
63-
64-
client := &http.Client{Timeout: MonitorRequestTimeout}
65-
if monitorForwardProxyExists {
66-
proxyURI, err := url.Parse(monitorForwardProxy)
67-
if err != nil {
68-
return nil, errors.New("monitor forward proxy '" + monitorForwardProxy + "' in parameter '" + MonitorProxyParameter + "' not a URI: " + err.Error())
69-
}
70-
clientTransport := &http.Transport{Proxy: http.ProxyURL(proxyURI)}
71-
if proxyURI.Scheme == "https" {
72-
// TM does not support HTTP/2 and golang when connecting to https will use HTTP/2 by default causing a conflict
73-
// The result will be an unsupported scheme error
74-
// Setting TLSNextProto to any empty map will disable using HTTP/2 per https://golang.org/src/net/http/doc.go
75-
clientTransport.TLSNextProto = make(map[string]func(authority string, c *tls.Conn) http.RoundTripper)
76-
}
77-
client = &http.Client{Timeout: MonitorRequestTimeout, Transport: clientTransport}
60+
return nil, errors.New("getting monitor client: " + err.Error())
7861
}
7962

8063
cacheData, err := getCacheData(tx)
@@ -91,7 +74,7 @@ func getCachesStats(tx *sql.Tx) ([]CacheData, error) {
9174
success := false
9275
errs := []error{}
9376
for _, monitorFQDN := range monitorFQDNs {
94-
crStates, err := getCRStates(monitorFQDN, client)
77+
crStates, err := monitorhlp.GetCRStates(monitorFQDN, client)
9578
if err != nil {
9679
errs = append(errs, errors.New("getting CRStates for CDN '"+string(cdn)+"' monitor '"+monitorFQDN+"': "+err.Error()))
9780
continue
@@ -197,31 +180,7 @@ func addStats(cacheData []CacheData, stats CacheStats) []CacheData {
197180
return cacheData
198181
}
199182

200-
// CRStates contains the Monitor CRStates needed by Cachedata. It is NOT the full object served by the Monitor, but only the data required by the caches stats endpoint.
201-
type CRStates struct {
202-
Caches map[tc.CacheName]Available `json:"caches"`
203-
}
204-
205-
type Available struct {
206-
IsAvailable bool `json:"isAvailable"`
207-
}
208-
209-
func getCRStates(monitorFQDN string, client *http.Client) (CRStates, error) {
210-
path := `/publish/CrStates`
211-
resp, err := client.Get("http://" + monitorFQDN + path)
212-
if err != nil {
213-
return CRStates{}, errors.New("getting CRStates from Monitor '" + monitorFQDN + "': " + err.Error())
214-
}
215-
defer resp.Body.Close()
216-
217-
crs := CRStates{}
218-
if err := json.NewDecoder(resp.Body).Decode(&crs); err != nil {
219-
return CRStates{}, errors.New("decoding CRStates from monitor '" + monitorFQDN + "': " + err.Error())
220-
}
221-
return crs, nil
222-
}
223-
224-
func addHealth(cacheData []CacheData, crStates CRStates) []CacheData {
183+
func addHealth(cacheData []CacheData, crStates tc.CRStates) []CacheData {
225184
if crStates.Caches == nil {
226185
return cacheData // TODO warn?
227186
}

traffic_ops/traffic_ops_golang/cdn/capacity.go

Lines changed: 15 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
"github.com/apache/trafficcontrol/lib/go-log"
3434
"github.com/apache/trafficcontrol/lib/go-tc"
3535
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
36+
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/util/monitorhlp"
3637
)
3738

3839
func GetCapacity(w http.ResponseWriter, r *http.Request) {
@@ -50,27 +51,6 @@ const MonitorProxyParameter = "tm.traffic_mon_fwd_proxy"
5051
const MonitorRequestTimeout = time.Second * 10
5152
const MonitorOnlineStatus = "ONLINE"
5253

53-
// CRStates contains the Monitor CRStates members needed for health. It is NOT the full object served by the Monitor, but only the data required by this endpoint.
54-
type CRStates struct {
55-
Caches map[tc.CacheName]Available `json:"caches"`
56-
}
57-
58-
type Available struct {
59-
IsAvailable bool `json:"isAvailable"`
60-
}
61-
62-
// CRConfig contains the Monitor CRConfig members needed for health. It is NOT the full object served by the Monitor, but only the data required by this endpoint.
63-
type CRConfig struct {
64-
ContentServers map[tc.CacheName]CRConfigServer `json:"contentServers"`
65-
}
66-
67-
type CRConfigServer struct {
68-
CacheGroup tc.CacheGroupName `json:"locationId"`
69-
Status tc.CacheStatus `json:"status"`
70-
Type tc.CacheType `json:"type"`
71-
Profile string `json:"profile"`
72-
}
73-
7454
func getCapacity(tx *sql.Tx) (CapacityResp, error) {
7555
monitors, err := getCDNMonitorFQDNs(tx)
7656
if err != nil {
@@ -144,15 +124,15 @@ func getCapacityData(monitors map[tc.CDNName][]string, thresholds map[string]flo
144124
for cdn, monitorFQDNs := range monitors {
145125
err := error(nil)
146126
for _, monitorFQDN := range monitorFQDNs {
147-
crStates := CRStates{}
148-
crConfig := CRConfig{}
127+
crStates := tc.CRStates{}
128+
crConfig := tc.CRConfig{}
149129
cacheStats := CacheStats{}
150-
if crStates, err = getCRStates(monitorFQDN, client); err != nil {
130+
if crStates, err = monitorhlp.GetCRStates(monitorFQDN, client); err != nil {
151131
err = errors.New("getting CRStates for CDN '" + string(cdn) + "' monitor '" + monitorFQDN + "': " + err.Error())
152132
log.Warnln("getCapacity failed to get CRStates from cdn '" + string(cdn) + " monitor '" + monitorFQDN + "', trying next monitor: " + err.Error())
153133
continue
154134
}
155-
if crConfig, err = getCRConfig(monitorFQDN, client); err != nil {
135+
if crConfig, err = monitorhlp.GetCRConfig(monitorFQDN, client); err != nil {
156136
err = errors.New("getting CRConfig for CDN '" + string(cdn) + "' monitor '" + monitorFQDN + "': " + err.Error())
157137
log.Warnln("getCapacity failed to get CRConfig from cdn '" + string(cdn) + " monitor '" + monitorFQDN + "', trying next monitor: " + err.Error())
158138
continue
@@ -172,30 +152,34 @@ func getCapacityData(monitors map[tc.CDNName][]string, thresholds map[string]flo
172152
return cap, nil
173153
}
174154

175-
func addCapacity(cap CapData, cacheStats CacheStats, crStates CRStates, crConfig CRConfig, thresholds map[string]float64) CapData {
155+
func addCapacity(cap CapData, cacheStats CacheStats, crStates tc.CRStates, crConfig tc.CRConfig, thresholds map[string]float64) CapData {
176156
for cacheName, stats := range cacheStats.Caches {
177-
cache, ok := crConfig.ContentServers[cacheName]
157+
cache, ok := crConfig.ContentServers[string(cacheName)]
178158
if !ok {
179159
continue
180160
}
181-
if !strings.HasPrefix(string(cache.Type), string(tc.CacheTypeEdge)) {
161+
if cache.ServerType == nil || cache.ServerStatus == nil || cache.Profile == nil {
162+
log.Warnln("addCapacity got cache with nil values! Skipping!")
163+
continue
164+
}
165+
if !strings.HasPrefix(*cache.ServerType, string(tc.CacheTypeEdge)) {
182166
continue
183167
}
184168
if len(stats.KBPS) < 1 || len(stats.MaxKBPS) < 1 {
185169
continue
186170
}
187-
if cache.Status == "REPORTED" || cache.Status == "ONLINE" {
171+
if string(*cache.ServerStatus) == string(tc.CacheStatusReported) || string(*cache.ServerStatus) == string(tc.CacheStatusOnline) {
188172
if crStates.Caches[cacheName].IsAvailable {
189173
cap.Available += float64(stats.KBPS[0].Value)
190174
} else {
191175
cap.Unavailable += float64(stats.KBPS[0].Value)
192176
}
193-
} else if cache.Status == "ADMIN_DOWN" {
177+
} else if string(*cache.ServerStatus) == string(tc.CacheStatusAdminDown) {
194178
cap.Maintenance += float64(stats.KBPS[0].Value)
195179
} else {
196180
continue // don't add capacity for OFFLINE or other statuses
197181
}
198-
cap.Capacity += float64(stats.MaxKBPS[0].Value) - thresholds[cache.Profile]
182+
cap.Capacity += float64(stats.MaxKBPS[0].Value) - thresholds[*cache.Profile]
199183
}
200184
return cap
201185
}
@@ -234,35 +218,6 @@ AND pa.name = 'health.threshold.availableBandwidthInKbps'
234218
return profileThresholds, nil
235219
}
236220

237-
func getCRStates(monitorFQDN string, client *http.Client) (CRStates, error) {
238-
path := `/publish/CrStates`
239-
resp, err := client.Get("http://" + monitorFQDN + path)
240-
if err != nil {
241-
return CRStates{}, errors.New("getting CRStates from Monitor '" + monitorFQDN + "': " + err.Error())
242-
}
243-
defer resp.Body.Close()
244-
245-
crs := CRStates{}
246-
if err := json.NewDecoder(resp.Body).Decode(&crs); err != nil {
247-
return CRStates{}, errors.New("decoding CRStates from monitor '" + monitorFQDN + "': " + err.Error())
248-
}
249-
return crs, nil
250-
}
251-
252-
func getCRConfig(monitorFQDN string, client *http.Client) (CRConfig, error) {
253-
path := `/publish/CrConfig`
254-
resp, err := client.Get("http://" + monitorFQDN + path)
255-
if err != nil {
256-
return CRConfig{}, errors.New("getting CRConfig from Monitor '" + monitorFQDN + "': " + err.Error())
257-
}
258-
defer resp.Body.Close()
259-
crs := CRConfig{}
260-
if err := json.NewDecoder(resp.Body).Decode(&crs); err != nil {
261-
return CRConfig{}, errors.New("decoding CRConfig from monitor '" + monitorFQDN + "': " + err.Error())
262-
}
263-
return crs, nil
264-
}
265-
266221
// CacheStats contains the Monitor CacheStats needed by Cachedata. It is NOT the full object served by the Monitor, but only the data required by the caches stats endpoint.
267222
type CacheStats struct {
268223
Caches map[tc.CacheName]CacheStat `json:"caches"`

0 commit comments

Comments
 (0)