code: func parseTracingData(scanner *bufio.Scanner, job string, buildNumber int, result TestToBuildData) {
  	buff := &bytes.Buffer{}
  	state := scanning
  	build := fmt.Sprintf("%d", buildNumber)
  
  	for scanner.Scan() {
  		line := scanner.Text()
  		if state == processing {
  			if strings.Contains(line, timeSeriesEnd) {
  				state = scanning
  
  				obj := nodeperftype.NodeTimeSeries{}
  				if err := json.Unmarshal(buff.Bytes(), &obj); err != nil {
  					fmt.Fprintf(os.Stderr, "error parsing JSON in build %d: %v\n%s\n", buildNumber, err, buff.String())
  					continue
  				}
  
  				// We do not check the obj's version against
  				// the supportedMetricVersion because this data
  				// is generated internally by
  				// ParseKubeletLog().
  
  				testName, nodeName := obj.Labels["test"], formatNodeName(obj.Labels, job)
  
  				if _, found := result[testName]; !found {
  					fmt.Fprintf(os.Stderr, "Error: tracing data have no test result: %s\n", testName)
  					continue
  				}
  				if _, found := result[testName].Data[nodeName]; !found {
  					fmt.Fprintf(os.Stderr, "Error: tracing data have no test result: %s\n", nodeName)
  					continue
  				}
  				if _, found := result[testName].Data[nodeName][build]; !found {
  					fmt.Fprintf(os.Stderr, "Error: tracing data have not test result: %s\n", build)
  					continue
  				}
  
  				data := result.GetDataPerBuild(job, build, testName, nodeName)
  				data.Series = append(data.Series, obj)
  
  				buff.Reset()
  			}
  		}
  		if strings.Contains(line, timeSeriesTag) {
  			state = processing
  			line = line[strings.Index(line, "{"):]
  		}
  		if state == processing {
  			buff.WriteString(line + " ")
  		}
  	}
  }
docs: // parseTracingData extracts and converts tracing data into time series data.