You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by sr...@apache.org on 2023/05/31 23:09:49 UTC

[trafficcontrol] branch master updated: Use SOH timestamp to calculate bandwidth in TM (#7539)

This is an automated email from the ASF dual-hosted git repository.

srijeet0406 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git


The following commit(s) were added to refs/heads/master by this push:
     new f3c124f6d9 Use SOH timestamp to calculate bandwidth in TM (#7539)
f3c124f6d9 is described below

commit f3c124f6d90c3ec19b9c89845e187b3195b768b8
Author: Rima Shah <22...@users.noreply.github.com>
AuthorDate: Wed May 31 17:09:42 2023 -0600

    Use SOH timestamp to calculate bandwidth in TM (#7539)
    
    * Added current_time_epoch_ms and changes calculation for timestamp for ms
    
    * assigning current_time_epoch_ms to result.Time in Handler
    
    * updated CHANGELOG.md
    
    * Added check for elapsedTime.
    
    * Addressed review comments.
    
    * Added prevResult check back
    
    * pointer assignment for structure.
    
    * updated cache unite test with another check.
---
 CHANGELOG.md                               |  1 +
 traffic_monitor/cache/cache.go             | 12 +++++++++
 traffic_monitor/cache/cache_test.go        | 42 ++++++++++++++++++++++++++++--
 traffic_monitor/cache/stats_over_http.json |  1 +
 traffic_monitor/health/cache.go            | 11 ++++++--
 traffic_monitor/health/cache_test.go       |  8 ++++++
 6 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0418990302..b5b7bde146 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -57,6 +57,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
 - [#7469](https://github.com/apache/trafficcontrol/pull/7469) *Traffic Ops* Changed logic to not report empty or missing cookies into TO error.log.
 
 ### Fixed
+- [#7539](https://github.com/apache/trafficcontrol/pull/7539) *Traffic Monitor* Use stats_over_http timestamp to calculate bandwidth for TM's health. 
 - [#7542](https://github.com/apache/trafficcontrol/pull/7542) *Traffic Ops* Fixed `CDN Locks` documentation to reflect the correct RFC3339 timestamps.
 - [#6340](https://github.com/apache/trafficcontrol/issues/6340) *Traffic Ops* Fixed alert messages for POST and PUT invalidation job APIs.
 - [#7511](https://github.com/apache/trafficcontrol/pull/7511) *Traffic Ops* Fixed the changelog registration message to include the username instead of duplicate email entry.
diff --git a/traffic_monitor/cache/cache.go b/traffic_monitor/cache/cache.go
index 339c4a5f5c..4d443c4088 100644
--- a/traffic_monitor/cache/cache.go
+++ b/traffic_monitor/cache/cache.go
@@ -23,6 +23,7 @@ import (
 	"fmt"
 	"io"
 	"regexp"
+	"strconv"
 	"time"
 
 	"github.com/apache/trafficcontrol/lib/go-log"
@@ -306,6 +307,17 @@ func (handler Handler) Handle(id string, rdr io.Reader, format string, reqTime t
 		handler.resultChan <- result
 		return
 	}
+	if val, ok := miscStats["current_time_epoch_ms"]; ok {
+		valString := fmt.Sprintf("%s", val)
+		valInt, valErr := strconv.ParseInt(valString, 10, 64)
+		if valErr != nil {
+			log.Errorf("parse error '%v'", valErr)
+			result.Error = valErr
+			handler.resultChan <- result
+			return
+		}
+		result.Time = time.UnixMilli(valInt)
+	}
 	if value, ok := miscStats[rfc.Via]; ok {
 		result.ID = fmt.Sprintf("%v", value)
 	}
diff --git a/traffic_monitor/cache/cache_test.go b/traffic_monitor/cache/cache_test.go
index b20a392507..077592ffca 100644
--- a/traffic_monitor/cache/cache_test.go
+++ b/traffic_monitor/cache/cache_test.go
@@ -20,11 +20,15 @@ package cache
  */
 
 import (
-	"testing"
-
+	"bytes"
+	"fmt"
 	"github.com/apache/trafficcontrol/lib/go-tc"
 	"github.com/apache/trafficcontrol/lib/go-util"
+	"github.com/apache/trafficcontrol/traffic_monitor/poller"
 	"github.com/apache/trafficcontrol/traffic_monitor/todata"
+	"io/ioutil"
+	"net/http"
+	"testing"
 )
 
 func TestHandlerPrecompute(t *testing.T) {
@@ -95,3 +99,37 @@ func TestComputeStatGbps(t *testing.T) {
 		}
 	}
 }
+
+func TestParseAndDecode(t *testing.T) {
+	file, err := ioutil.ReadFile("stats_over_http.json")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	pl := &poller.HTTPPollCtx{HTTPHeader: http.Header{}}
+	ctx := interface{}(pl)
+	ctx.(*poller.HTTPPollCtx).HTTPHeader.Set("Content-Type", "text/json")
+
+	decoder, err := GetDecoder("stats_over_http")
+	if err != nil {
+		t.Errorf("decoder error, expected: nil, got: %v", err)
+	}
+
+	_, miscStats, err := decoder.Parse("1", bytes.NewReader(file), ctx)
+	if err != nil {
+		t.Errorf("decoder parse error, expected: nil, got: %v", err)
+	}
+
+	if len(miscStats) < 1 {
+		t.Errorf("empty miscStats structure")
+	}
+
+	if val, ok := miscStats["current_time_epoch_ms"]; ok {
+		valString := fmt.Sprintf("%s", val)
+		if valString != "1684784878894" {
+			t.Errorf("unable to read `current_time_epoch_ms`")
+		}
+	} else {
+		t.Errorf("current_time_epoch_ms field was not found in the json file")
+	}
+}
diff --git a/traffic_monitor/cache/stats_over_http.json b/traffic_monitor/cache/stats_over_http.json
index 70cce951b4..a7d8ed4b20 100644
--- a/traffic_monitor/cache/stats_over_http.json
+++ b/traffic_monitor/cache/stats_over_http.json
@@ -533,6 +533,7 @@
 		"plugin.system_stats.net.docker0.rx_length_errors": "0",
 		"proxy.process.cache.volume_0.span.offline": "0",
 		"proxy.process.cache.volume_0.span.online": "0",
+		"current_time_epoch_ms": "1684784878894",
 		"server": "10.0.0"
 	}
 }
diff --git a/traffic_monitor/health/cache.go b/traffic_monitor/health/cache.go
index 94489884db..53f932285c 100644
--- a/traffic_monitor/health/cache.go
+++ b/traffic_monitor/health/cache.go
@@ -60,6 +60,7 @@ func (t Threshold) String() string {
 
 // GetVitals Gets the vitals to decide health on in the right format
 func GetVitals(newResult *cache.Result, prevResult *cache.Result, mc *tc.TrafficMonitorConfigMap) {
+	var elapsedTimeInSecs float64
 	if newResult.Error != nil {
 		log.Errorf("cache_health.GetVitals() called with an errored Result!")
 		return
@@ -87,6 +88,14 @@ func GetVitals(newResult *cache.Result, prevResult *cache.Result, mc *tc.Traffic
 		return
 	}
 
+	if prevResult != nil {
+		elapsedTimeInSecs = float64(newResult.Time.UnixMilli()-prevResult.Time.UnixMilli()) / 1000
+		if elapsedTimeInSecs <= 0 {
+			*newResult = *prevResult
+			return
+		}
+	}
+
 	var monitoredInterfaces []tc.ServerInterfaceInfo
 	for _, srvrIfaceInfo := range mc.TrafficServer[newResult.ID].Interfaces {
 		if srvrIfaceInfo.Monitor {
@@ -115,7 +124,6 @@ func GetVitals(newResult *cache.Result, prevResult *cache.Result, mc *tc.Traffic
 		}
 
 		if prevResult != nil && prevResult.InterfaceVitals != nil && prevResult.InterfaceVitals[ifaceName].BytesOut != 0 {
-			elapsedTimeInSecs := float64(newResult.Time.UnixNano()-prevResult.Time.UnixNano()) / 1000000000
 			ifaceVitals.KbpsOut = int64(float64((ifaceVitals.BytesOut-prevResult.InterfaceVitals[ifaceName].BytesOut)*8/1000) / elapsedTimeInSecs)
 		}
 		newResult.InterfaceVitals[ifaceName] = ifaceVitals
@@ -128,7 +136,6 @@ func GetVitals(newResult *cache.Result, prevResult *cache.Result, mc *tc.Traffic
 	}
 
 	if prevResult != nil && prevResult.Vitals.BytesOut != 0 {
-		elapsedTimeInSecs := float64(newResult.Time.UnixNano()-prevResult.Time.UnixNano()) / 1000000000
 		newResult.Vitals.KbpsOut = int64(float64((newResult.Vitals.BytesOut-prevResult.Vitals.BytesOut)*8/1000) / elapsedTimeInSecs)
 	}
 
diff --git a/traffic_monitor/health/cache_test.go b/traffic_monitor/health/cache_test.go
index 847d82931a..3b3c151eb5 100644
--- a/traffic_monitor/health/cache_test.go
+++ b/traffic_monitor/health/cache_test.go
@@ -310,6 +310,14 @@ func TestDualHomingMonitoredInterfacesGetVitals(t *testing.T) {
 	if firstResult.Vitals != expectedFirstVitals {
 		t.Errorf("Vitals do not match expected output. expected: %v actual: %v:", expectedFirstVitals, firstResult.Vitals)
 	}
+
+	//Test if elapsedTimeInSecs == 0
+	secondResult.Time = firstResult.Time
+	GetVitals(&secondResult, &firstResult, &tmcm)
+	if firstResult.Statistics.Interfaces["bond0"] != secondResult.Statistics.Interfaces["bond0"] {
+		t.Errorf("Load avg statistics do not match. expected: %v, got: %v", firstResult.Statistics.Interfaces["bond0"], secondResult.Statistics.Interfaces["bond0"])
+	}
+
 }
 
 func TestCalcAvailabilityThresholds(t *testing.T) {