github.com/tiagovtristao/plz@v13.4.0+incompatible/src/output/trace.go (about)

     1  // For writing out JSON trace files which Chrome can interpret nicely for us.
     2  // See https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU
     3  
     4  package output
     5  
     6  import "encoding/json"
     7  import "fmt"
     8  import "os"
     9  
    10  import "github.com/thought-machine/please/src/core"
    11  
    12  var traces = make([]traceEntry, 0, 1000)
    13  
    14  func addTrace(result *core.BuildResult, previous core.BuildLabel, active bool) {
    15  	// It's a bit fiddly to keep all the phases in line here.
    16  	if !active {
    17  		traces = append(traces, translateEvent(result, "E"))
    18  	} else if result.Label != previous {
    19  		traces = append(traces, translateEvent(result, "B"))
    20  	} else {
    21  		traces = append(traces, translateEvent(result, "E"))
    22  		traces = append(traces, translateEvent(result, "B"))
    23  	}
    24  }
    25  
    26  func writeTrace(traceFile string) {
    27  	file, err := os.Create(traceFile)
    28  	if err != nil {
    29  		log.Errorf("Couldn't create trace file: %s", err)
    30  		return
    31  	}
    32  	defer file.Close()
    33  	file.Write(formatTrace())
    34  }
    35  
    36  func formatTrace() []byte {
    37  	var out traceObjectFormat
    38  	out.OtherData.Version = "Please v" + core.PleaseVersion.String()
    39  	out.TraceEvents = traces
    40  	data, err := json.Marshal(out)
    41  	if err != nil {
    42  		log.Errorf("Error serialising JSON trace data: %s", err)
    43  	}
    44  	return data
    45  }
    46  
    47  func translateEvent(result *core.BuildResult, phase string) traceEntry {
    48  	entry := traceEntry{
    49  		Name:  result.Label.String(),
    50  		Cat:   result.Status.Category(),
    51  		Ph:    phase,
    52  		Pid:   0, // This isn't really important, there's only one process.
    53  		Ts:    result.Time.UnixNano() / 1000,
    54  		Cname: "thread_state_runnable", // Colours have to fit available names, this is blueish.
    55  	}
    56  	entry.Tid = fmt.Sprintf("Builder %d", result.ThreadID)
    57  	entry.Args.Description = result.Description
    58  	if result.Err != nil {
    59  		entry.Args.Err = fmt.Sprintf("%s", result.Err)
    60  		entry.Cname = "terrible"
    61  	} else if entry.Cat == "Test" {
    62  		entry.Cname = "good"
    63  	}
    64  	return entry
    65  }
    66  
    67  type traceObjectFormat struct {
    68  	TraceEvents []traceEntry `json:"traceEvents"`
    69  	OtherData   struct {
    70  		Version string `json:"version"`
    71  	} `json:"otherData"`
    72  	// Ignoring other properties for now.
    73  }
    74  
    75  type traceEntry struct {
    76  	Name  string `json:"name"`
    77  	Cat   string `json:"cat"`
    78  	Ph    string `json:"ph"`
    79  	Pid   int32  `json:"pid"`
    80  	Tid   string `json:"tid"`
    81  	Ts    int64  `json:"ts"`
    82  	Cname string `json:"cname,omitempty"`
    83  	Args  struct {
    84  		Description string `json:"description"`
    85  		Err         string `json:"err,omitempty"`
    86  	} `json:"args"`
    87  }