This is an automated email from the ASF dual-hosted git repository. ocket8888 pushed a commit to branch 5.1.x in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git
commit 924138d143febb66e926f0e6be82b22d450bfbd9 Author: Srijeet Chatterjee <[email protected]> AuthorDate: Tue Apr 6 08:26:26 2021 -0600 Ensure that 5.x TS is not logging all 0's for cache_stats, when linked with a 5.x TM/TO (#5714) * Add fixes to ensure that TS is not logging all 0's for cache_stats * change log msg modification (cherry picked from commit ff7984842b143212e27460bcf4243786d5098b94) --- CHANGELOG.md | 8 +- traffic_stats/traffic_stats.go | 16 +++- traffic_stats/traffic_stats_test.go | 157 ++++++++++++++++++++++++++++++++++++ 3 files changed, 177 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 738fc5e..d5759f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). +## [5.1.2] - 2021-04-07 +### Fixed +- Fixed the return error for GET api `cdns/routing` to avoid incorrect success response. +- [#5712](https://github.com/apache/trafficcontrol/issues/5712) - Ensure that 5.x Traffic Stats is compatible with 5.x Traffic Monitor and 5.x Traffic Ops, and that it doesn't log all 0's for `cache_stats` +- Fixed ORT being unable to update URLSIG keys for Delivery Services +- Fixed an issue where Traffic Ops becoming unavailable caused Traffic Monitor to segfault and crash + ## [5.1.1] - 2021-03-19 ### Added - Atscfg: Added a rule to ip_allow such that PURGE requests are allowed over localhost @@ -16,7 +23,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - [#5604](https://github.com/apache/trafficcontrol/issues/5604) - traffic_monitor.log is no longer truncated when restarting Traffic Monitor - [#1624](https://github.com/apache/trafficcontrol/issues/1624) - Fixed ORT to reload Traffic Server if LUA scripts are added or changed. - #5554 - TM UI overflows screen width and hides table data -- Fixed the return error for GET api `cdns/routing` to avoid incorrect success response. ## [5.1.0] - 2021-02-21 diff --git a/traffic_stats/traffic_stats.go b/traffic_stats/traffic_stats.go index a4aef4e..5088a19 100644 --- a/traffic_stats/traffic_stats.go +++ b/traffic_stats/traffic_stats.go @@ -654,10 +654,14 @@ func calcCacheValues(trafmonData []byte, cdnName string, sampleTime int64, cache if err != nil { errHndlr(err, ERROR) } + for cacheName, cacheData := range jData.Caches { cache := cacheMap[string(cacheName)] for statName, statData := range cacheData { + if len(statData) == 0 { + continue + } //Get the stat time and make sure it's greater than the time 24 hours ago. If not, skip it so influxdb doesn't throw retention policy errors. validTime := time.Now().AddDate(0, 0, -1) if statData[0].Time.Before(validTime) { @@ -669,10 +673,16 @@ func calcCacheValues(trafmonData []byte, cdnName string, sampleTime int64, cache dataKey = strings.Replace(dataKey, "-", "_", -1) //Get the stat value and convert to float - statFloatValue, ok := statData[0].Val.(float64) - if !ok { - statFloatValue = 0.00 + statFloatValue := 0.0 + if statsValue, ok := statData[0].Val.(string); !ok { + log.Warnf("stat data %s with value %v couldn't be converted into string", statName, statData[0].Val) + } else { + statFloatValue, err = strconv.ParseFloat(statsValue, 64) + if err != nil { + log.Warnf("stat %s with value %v couldn't be converted into a float", statName, statsValue) + } } + tags := map[string]string{ "cachegroup": cache.Cachegroup, "hostname": string(cacheName), diff --git a/traffic_stats/traffic_stats_test.go b/traffic_stats/traffic_stats_test.go new file mode 100644 index 0000000..735023a --- /dev/null +++ b/traffic_stats/traffic_stats_test.go @@ -0,0 +1,157 @@ +package main + +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +import ( + "encoding/json" + "testing" + "time" + + "github.com/apache/trafficcontrol/lib/go-tc" + influx "github.com/influxdata/influxdb/client/v2" +) + +func TestCalcCacheValuesWithInvalidValue(t *testing.T) { + stats := make(map[string][]tc.ResultStatVal) + caches := make(map[tc.CacheName]map[string][]tc.ResultStatVal) + cacheMap := make(map[string]tc.Server) + resultSatsVal := []tc.ResultStatVal{ + { + Span: 0, + Time: time.Now(), + Val: "invalid stat", + }, + } + stats["maxKbps"] = resultSatsVal + caches["cache1"] = stats + cacheMap["cache1"] = tc.Server{} + config := StartupConfig{ + BpsChan: make(chan influx.BatchPoints), + } + legacyStats := tc.LegacyStats{ + CommonAPIData: tc.CommonAPIData{}, + Caches: caches, + } + data, err := json.Marshal(legacyStats) + if err != nil { + t.Fatalf("couldn't marshal struct %v", caches) + } + go calcCacheValues(data, "cdn", 0, cacheMap, config) + result := <-config.BpsChan + if len(result.Points()) == 0 { + t.Fatalf("expected one point in the result, got none") + } + fields, err := result.Points()[0].Fields() + if err != nil { + t.Fatalf("couldn't read the fields of the result: %v", err.Error()) + } + if val, ok := fields["value"]; !ok { + t.Fatalf("couldn't find a 'value' field") + } else { + if val.(float64) != 0.0 { + t.Errorf("expected invalid stat to result in a value of 0.0, but got %v instead", val.(float64)) + } + } +} + +func TestCalcCacheValuesWithEmptyInterface(t *testing.T) { + stats := make(map[string][]tc.ResultStatVal) + caches := make(map[tc.CacheName]map[string][]tc.ResultStatVal) + cacheMap := make(map[string]tc.Server) + resultSatsVal := []tc.ResultStatVal{ + { + Span: 0, + Time: time.Now(), + }, + } + stats["maxKbps"] = resultSatsVal + caches["cache1"] = stats + cacheMap["cache1"] = tc.Server{} + config := StartupConfig{ + BpsChan: make(chan influx.BatchPoints), + } + legacyStats := tc.LegacyStats{ + CommonAPIData: tc.CommonAPIData{}, + Caches: caches, + } + data, err := json.Marshal(legacyStats) + if err != nil { + t.Fatalf("couldn't marshal struct %v", caches) + } + go calcCacheValues(data, "cdn", 0, cacheMap, config) + result := <-config.BpsChan + if len(result.Points()) == 0 { + t.Fatalf("expected one point in the result, got none") + } + fields, err := result.Points()[0].Fields() + if err != nil { + t.Fatalf("couldn't read the fields of the result: %v", err.Error()) + } + if val, ok := fields["value"]; !ok { + t.Fatalf("couldn't find a 'value' field") + } else { + if val.(float64) != 0.0 { + t.Errorf("expected invalid stat to result in a value of 0.0, but got %v instead", val.(float64)) + } + } +} + +func TestCalcCacheValues(t *testing.T) { + stats := make(map[string][]tc.ResultStatVal) + caches := make(map[tc.CacheName]map[string][]tc.ResultStatVal) + cacheMap := make(map[string]tc.Server) + resultSatsVal := []tc.ResultStatVal{ + { + Span: 0, + Time: time.Now(), + Val: "25.56", + }, + } + stats["maxKbps"] = resultSatsVal + caches["cache1"] = stats + cacheMap["cache1"] = tc.Server{} + config := StartupConfig{ + BpsChan: make(chan influx.BatchPoints), + } + legacyStats := tc.LegacyStats{ + CommonAPIData: tc.CommonAPIData{}, + Caches: caches, + } + data, err := json.Marshal(legacyStats) + if err != nil { + t.Fatalf("couldn't marshal struct %v", caches) + } + go calcCacheValues(data, "cdn", 0, cacheMap, config) + result := <-config.BpsChan + if len(result.Points()) == 0 { + t.Fatalf("expected one point in the result, got none") + } + fields, err := result.Points()[0].Fields() + if err != nil { + t.Fatalf("couldn't read the fields of the result: %v", err.Error()) + } + if val, ok := fields["value"]; !ok { + t.Fatalf("couldn't find a 'value' field") + } else { + if val.(float64) != 25.56 { + t.Errorf("expected invalid stat to result in a value of 0.0, but got %v instead", val.(float64)) + } + } +}
