diff --git a/cnms/cnmspackage/api.go b/cnms/cnmspackage/api.go index 01979756e4..baf83e09cc 100644 --- a/cnms/cnmspackage/api.go +++ b/cnms/cnmspackage/api.go @@ -1,6 +1,9 @@ package cnms +import "github.com/Azure/azure-container-networking/telemetry" + type NetworkMonitor struct { AddRulesToBeValidated map[string]int DeleteRulesToBeValidated map[string]int + CNIReport *telemetry.CNIReport } diff --git a/cnms/cnmspackage/monitor2rules_linux.go b/cnms/cnmspackage/monitor2rules_linux.go index f2180b83d3..23d95bdf3d 100644 --- a/cnms/cnmspackage/monitor2rules_linux.go +++ b/cnms/cnmspackage/monitor2rules_linux.go @@ -1,6 +1,8 @@ package cnms import ( + "fmt" + "github.com/Azure/azure-container-networking/ebtables" "github.com/Azure/azure-container-networking/log" ) @@ -14,11 +16,14 @@ func (networkMonitor *NetworkMonitor) deleteRulesNotExistInMap(chainRules map[st for rule, chain := range chainRules { if _, ok := stateRules[rule]; !ok { if itr, ok := networkMonitor.DeleteRulesToBeValidated[rule]; ok && itr > 0 { - log.Printf("[monitor] Deleting Ebtable rule as it didn't exist in state for %d iterations chain %v rule %v", itr, chain, rule) + buf := fmt.Sprintf("[monitor] Deleting Ebtable rule as it didn't exist in state for %d iterations chain %v rule %v", itr, chain, rule) if err := ebtables.SetEbRule(table, action, chain, rule); err != nil { - log.Printf("[monitor] Error while deleting ebtable rule %v", err) + buf = fmt.Sprintf("[monitor] Error while deleting ebtable rule %v", err) } + log.Printf(buf) + networkMonitor.CNIReport.ErrorMessage = buf + networkMonitor.CNIReport.OperationType = "EBTableDelete" delete(networkMonitor.DeleteRulesToBeValidated, rule) } else { log.Printf("[DELETE] Found unmatched rule chain %v rule %v itr %d. Giving one more iteration.", chain, rule, itr) @@ -39,14 +44,17 @@ func (networkMonitor *NetworkMonitor) addRulesNotExistInMap( for rule, chain := range stateRules { if _, ok := chainRules[rule]; !ok { if itr, ok := networkMonitor.AddRulesToBeValidated[rule]; ok && itr > 0 { - log.Printf("[monitor] Adding Ebtable rule as it existed in state rules but not in current chain rules for %d iterations chain %v rule %v", itr, chain, rule) + buf := fmt.Sprintf("[monitor] Adding Ebtable rule as it existed in state rules but not in current chain rules for %d iterations chain %v rule %v", itr, chain, rule) if err := ebtables.SetEbRule(table, action, chain, rule); err != nil { - log.Printf("[monitor] Error while adding ebtable rule %v", err) + buf = fmt.Sprintf("[monitor] Error while adding ebtable rule %v", err) } + log.Printf(buf) + networkMonitor.CNIReport.ErrorMessage = buf + networkMonitor.CNIReport.OperationType = "EBTableAdd" delete(networkMonitor.AddRulesToBeValidated, rule) } else { - log.Printf("[ADD] Found unmatched rule chain %v rule %v itr %d. Giving one more iteration", chain, rule, itr) + log.Printf("[ADD] Found unmatched rule chain %v rule %v itr %d. Giving one more iteration.", chain, rule, itr) networkMonitor.AddRulesToBeValidated[rule] = itr + 1 } } diff --git a/cnms/service/networkmonitor.go b/cnms/service/networkmonitor.go index a75bae2b94..f1564f0dba 100644 --- a/cnms/service/networkmonitor.go +++ b/cnms/service/networkmonitor.go @@ -14,13 +14,16 @@ import ( "github.com/Azure/azure-container-networking/network" "github.com/Azure/azure-container-networking/platform" "github.com/Azure/azure-container-networking/store" + "github.com/Azure/azure-container-networking/telemetry" ) const ( // Service name. - name = "azure-cnimonitor" - pluginName = "azure-vnet" - DEFAULT_TIMEOUT_IN_SECS = "10" + name = "azure-cnimonitor" + pluginName = "azure-vnet" + DEFAULT_TIMEOUT_IN_SECS = "10" + telemetryNumRetries = 5 + telemetryWaitTimeInMilliseconds = 200 ) // Version is populated by make during build. @@ -113,11 +116,29 @@ func main() { // Log platform information. log.Printf("[monitor] Running on %v", platform.GetOSInfo()) + reportManager := &telemetry.ReportManager{ + ContentType: telemetry.ContentType, + Report: &telemetry.CNIReport{ + Context: "AzureCNINetworkMonitor", + Version: version, + SystemDetails: telemetry.SystemInfo{}, + InterfaceDetails: telemetry.InterfaceInfo{}, + BridgeDetails: telemetry.BridgeInfo{}, + }, + } + + reportManager.Report.(*telemetry.CNIReport).GetOSDetails() + netMonitor := &cnms.NetworkMonitor{ AddRulesToBeValidated: make(map[string]int), DeleteRulesToBeValidated: make(map[string]int), + CNIReport: reportManager.Report.(*telemetry.CNIReport), } + tb := telemetry.NewTelemetryBuffer("") + tb.ConnectToTelemetryService(telemetryNumRetries, telemetryWaitTimeInMilliseconds) + defer tb.Close() + for true { config.Store, err = store.NewJsonFileStore(platform.CNIRuntimePath + pluginName + ".json") if err != nil { @@ -141,6 +162,18 @@ func main() { log.Printf("[monitor] Failed while calling SetupNetworkUsingState with error %v", err) } + if netMonitor.CNIReport.ErrorMessage != "" { + log.Printf("[monitor] Reporting discrepancy in rules") + netMonitor.CNIReport.Timestamp = time.Now().Format("2006-01-02 15:04:05") + if err := reportManager.SendReport(tb); err != nil { + log.Errorf("[monitor] SendReport failed due to %v", err) + } else { + log.Printf("[monitor] Reported successfully") + } + + netMonitor.CNIReport.ErrorMessage = "" + } + log.Printf("[monitor] Going to sleep for %v seconds", timeout) time.Sleep(time.Duration(timeout) * time.Second) nm = nil diff --git a/cnms/service/networkmonitor_test.go b/cnms/service/networkmonitor_test.go index b3c6700d7f..71887ee990 100644 --- a/cnms/service/networkmonitor_test.go +++ b/cnms/service/networkmonitor_test.go @@ -6,6 +6,7 @@ import ( cnms "github.com/Azure/azure-container-networking/cnms/cnmspackage" "github.com/Azure/azure-container-networking/ebtables" + "github.com/Azure/azure-container-networking/telemetry" ) const ( @@ -38,6 +39,7 @@ func TestAddMissingRule(t *testing.T) { netMonitor := &cnms.NetworkMonitor{ AddRulesToBeValidated: make(map[string]int), DeleteRulesToBeValidated: make(map[string]int), + CNIReport: &telemetry.CNIReport{}, } currentStateRulesMap := addStateRulesToMap() @@ -78,6 +80,7 @@ func TestDeleteInvalidRule(t *testing.T) { netMonitor := &cnms.NetworkMonitor{ AddRulesToBeValidated: make(map[string]int), DeleteRulesToBeValidated: make(map[string]int), + CNIReport: &telemetry.CNIReport{}, } currentStateRulesMap := addStateRulesToMap()