TUN-8767: include raw output from network collector in diagnostic zipfile

## Summary

Export raw format of traceroute is widely known and useful for debugging. This raw output is written to the zipfile's root at the end of the diagnostic.

Closes TUN-8767
This commit is contained in:
Luis Neto 2024-12-04 04:40:51 -08:00
parent 7bd86762a7
commit 520e266411
3 changed files with 66 additions and 6 deletions

View File

@ -29,5 +29,6 @@ const (
heapPprofBaseName = "heap.pprof" heapPprofBaseName = "heap.pprof"
goroutinePprofBaseName = "goroutine.pprof" goroutinePprofBaseName = "goroutine.pprof"
networkBaseName = "network.json" networkBaseName = "network.json"
rawNetworkBaseName = "raw-network.txt"
tunnelStateBaseName = "tunnelstate.json" tunnelStateBaseName = "tunnelstate.json"
) )

View File

@ -141,7 +141,7 @@ func collectNetworkResultRoutine(
} }
} }
func collectNetworkInformation(ctx context.Context) (string, error) { func gatherNetworkInformation(ctx context.Context) map[string]networkCollectionResult {
networkCollector := network.NetworkCollectorImpl{} networkCollector := network.NetworkCollectorImpl{}
hostAndIPversionPairs := []struct { hostAndIPversionPairs := []struct {
@ -171,11 +171,64 @@ func collectNetworkInformation(ctx context.Context) (string, error) {
// Wait for routines to end. // Wait for routines to end.
wgroup.Wait() wgroup.Wait()
resultMap := make(map[string][]*network.Hop) resultMap := make(map[string]networkCollectionResult)
for range len(hostAndIPversionPairs) { for range len(hostAndIPversionPairs) {
result := <-results result := <-results
resultMap[result.name] = result.info if result.err != nil {
continue
}
resultMap[result.name] = result
}
return resultMap
}
func networkInformationCollectors() (rawNetworkCollector, jsonNetworkCollector collectFunc) {
// The network collector is an operation that takes most of the diagnostic time, thus,
// the sync.Once is used to memoize the result of the collector and then create different
// outputs.
var once sync.Once
var resultMap map[string]networkCollectionResult
rawNetworkCollector = func(ctx context.Context) (string, error) {
once.Do(func() { resultMap = gatherNetworkInformation(ctx) })
return rawNetworkInformationWriter(resultMap)
}
jsonNetworkCollector = func(ctx context.Context) (string, error) {
once.Do(func() { resultMap = gatherNetworkInformation(ctx) })
return jsonNetworkInformationWriter(resultMap)
}
return rawNetworkCollector, jsonNetworkCollector
}
func rawNetworkInformationWriter(resultMap map[string]networkCollectionResult) (string, error) {
networkDumpHandle, err := os.Create(filepath.Join(os.TempDir(), rawNetworkBaseName))
if err != nil {
return "", ErrCreatingTemporaryFile
}
defer networkDumpHandle.Close()
for k, v := range resultMap {
_, err := networkDumpHandle.WriteString(k + "\n" + v.raw + "\n")
if err != nil {
return "", fmt.Errorf("error writing raw network information: %w", err)
}
}
return networkDumpHandle.Name(), nil
}
func jsonNetworkInformationWriter(resultMap map[string]networkCollectionResult) (string, error) {
jsonMap := make(map[string][]*network.Hop, len(resultMap))
for k, v := range resultMap {
jsonMap[k] = v.info
} }
networkDumpHandle, err := os.Create(filepath.Join(os.TempDir(), networkBaseName)) networkDumpHandle, err := os.Create(filepath.Join(os.TempDir(), networkBaseName))
@ -185,7 +238,7 @@ func collectNetworkInformation(ctx context.Context) (string, error) {
defer networkDumpHandle.Close() defer networkDumpHandle.Close()
err = json.NewEncoder(networkDumpHandle).Encode(resultMap) err = json.NewEncoder(networkDumpHandle).Encode(jsonMap)
if err != nil { if err != nil {
return "", fmt.Errorf("error encoding network information results: %w", err) return "", fmt.Errorf("error encoding network information results: %w", err)
} }
@ -279,6 +332,7 @@ func createJobs(
noDiagLogs bool, noDiagLogs bool,
noDiagNetwork bool, noDiagNetwork bool,
) []collectJob { ) []collectJob {
rawNetworkCollectorFunc, jsonNetworkCollectorFunc := networkInformationCollectors()
jobs := []collectJob{ jobs := []collectJob{
{ {
jobName: "tunnel state", jobName: "tunnel state",
@ -312,9 +366,14 @@ func createJobs(
}, },
bypass: noDiagLogs, bypass: noDiagLogs,
}, },
{
jobName: "raw network information",
fn: rawNetworkCollectorFunc,
bypass: noDiagNetwork,
},
{ {
jobName: "network information", jobName: "network information",
fn: collectNetworkInformation, fn: jsonNetworkCollectorFunc,
bypass: noDiagNetwork, bypass: noDiagNetwork,
}, },
} }

View File

@ -39,7 +39,7 @@ func decodeNetworkOutputToFile(command *exec.Cmd, decodeLine DecodeLineFunc) ([]
return nil, buf.String(), err return nil, buf.String(), err
} }
return hops, "", nil return hops, buf.String(), nil
} }
func Decode(reader io.Reader, decodeLine DecodeLineFunc) ([]*Hop, error) { func Decode(reader io.Reader, decodeLine DecodeLineFunc) ([]*Hop, error) {