// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"bufio"
	"cmd/internal/browser"
	"flag"
	"fmt"
	"html/template"
	"internal/trace"
	"io"
	"log"
	"net"
	"net/http"
	"os"
	"runtime"
	"runtime/debug"
	"sync"

	_ "net/http/pprof" // Required to use pprof
)

const usageMessage = "" +
	`Usage of 'go tool trace':
Given a trace file produced by 'go test':
	go test -trace=trace.out pkg

Open a web browser displaying trace:
	go tool trace [flags] [pkg.test] trace.out

Generate a pprof-like profile from the trace:
    go tool trace -pprof=TYPE [pkg.test] trace.out

[pkg.test] argument is required for traces produced by Go 1.6 and below.
Go 1.7 does not require the binary argument.

Supported profile types are:
    - net: network blocking profile
    - sync: synchronization blocking profile
    - syscall: syscall blocking profile
    - sched: scheduler latency profile

Flags:
	-http=addr: HTTP service address (e.g., ':6060')
	-pprof=type: print a pprof-like profile instead
	-d: print debug info such as parsed events

Note that while the various profiles available when launching
'go tool trace' work on every browser, the trace viewer itself
(the 'view trace' page) comes from the Chrome/Chromium project
and is only actively tested on that browser.
`

var (
	httpFlag  = flag.String("http", "localhost:0", "HTTP service address (e.g., ':6060')")
	pprofFlag = flag.String("pprof", "", "print a pprof-like profile instead")
	debugFlag = flag.Bool("d", false, "print debug information such as parsed events list")

	// The binary file name, left here for serveSVGProfile.
	programBinary string
	traceFile     string
)

func main() {
	flag.Usage = func() {
		fmt.Fprint(os.Stderr, usageMessage)
		os.Exit(2)
	}
	flag.Parse()

	// Go 1.7 traces embed symbol info and does not require the binary.
	// But we optionally accept binary as first arg for Go 1.5 traces.
	switch flag.NArg() {
	case 1:
		traceFile = flag.Arg(0)
	case 2:
		programBinary = flag.Arg(0)
		traceFile = flag.Arg(1)
	default:
		flag.Usage()
	}

	var pprofFunc func(io.Writer, *http.Request) error
	switch *pprofFlag {
	case "net":
		pprofFunc = pprofByGoroutine(computePprofIO)
	case "sync":
		pprofFunc = pprofByGoroutine(computePprofBlock)
	case "syscall":
		pprofFunc = pprofByGoroutine(computePprofSyscall)
	case "sched":
		pprofFunc = pprofByGoroutine(computePprofSched)
	}
	if pprofFunc != nil {
		if err := pprofFunc(os.Stdout, &http.Request{}); err != nil {
			dief("failed to generate pprof: %v\n", err)
		}
		os.Exit(0)
	}
	if *pprofFlag != "" {
		dief("unknown pprof type %s\n", *pprofFlag)
	}

	ln, err := net.Listen("tcp", *httpFlag)
	if err != nil {
		dief("failed to create server socket: %v\n", err)
	}

	log.Print("Parsing trace...")
	res, err := parseTrace()
	if err != nil {
		dief("%v\n", err)
	}

	if *debugFlag {
		trace.Print(res.Events)
		os.Exit(0)
	}
	reportMemoryUsage("after parsing trace")
	debug.FreeOSMemory()

	log.Print("Splitting trace...")
	ranges = splitTrace(res)
	reportMemoryUsage("after splitting trace")
	debug.FreeOSMemory()

	addr := "http://" + ln.Addr().String()
	log.Printf("Opening browser. Trace viewer is listening on %s", addr)
	browser.Open(addr)

	// Start http server.
	http.HandleFunc("/", httpMain)
	err = http.Serve(ln, nil)
	dief("failed to start http server: %v\n", err)
}

var ranges []Range

var loader struct {
	once sync.Once
	res  trace.ParseResult
	err  error
}

// parseEvents is a compatibility wrapper that returns only
// the Events part of trace.ParseResult returned by parseTrace.
func parseEvents() ([]*trace.Event, error) {
	res, err := parseTrace()
	if err != nil {
		return nil, err
	}
	return res.Events, err
}

func parseTrace() (trace.ParseResult, error) {
	loader.once.Do(func() {
		tracef, err := os.Open(traceFile)
		if err != nil {
			loader.err = fmt.Errorf("failed to open trace file: %v", err)
			return
		}
		defer tracef.Close()

		// Parse and symbolize.
		res, err := trace.Parse(bufio.NewReader(tracef), programBinary)
		if err != nil {
			loader.err = fmt.Errorf("failed to parse trace: %v", err)
			return
		}
		loader.res = res
	})
	return loader.res, loader.err
}

// httpMain serves the starting page.
func httpMain(w http.ResponseWriter, r *http.Request) {
	if err := templMain.Execute(w, ranges); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

var templMain = template.Must(template.New("").Parse(`
<html>
<style>
/* See https://github.com/golang/pkgsite/blob/master/static/shared/typography/typography.css */
body {
  font-family:	-apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
  font-size:	1rem;
  line-height:	normal;
  max-width:	9in;
  margin:	1em;
}
h1 { font-size: 1.5rem; }
h2 { font-size: 1.375rem; }
h1,h2 {
  font-weight: 600;
  line-height: 1.25em;
  word-break: break-word;
}
p  { color: grey85; font-size:85%; }
</style>
<body>
<h1>cmd/trace: the Go trace event viewer</h1>
<p>
  This web server provides various visualizations of an event log gathered during
  the execution of a Go program that uses the <a href='https://pkg.go.dev/runtime/trace'>runtime/trace</a> package.
</p>

<h2>Event timelines for running goroutines</h2>
{{if $}}
<p>
  Large traces are split into multiple sections of equal data size
  (not duration) to avoid overwhelming the visualizer.
</p>
<ul>
	{{range $e := $}}
		<li><a href="{{$e.URL}}">View trace ({{$e.Name}})</a></li>
	{{end}}
</ul>
{{else}}
<ul>
	<li><a href="/trace">View trace</a></li>
</ul>
{{end}}
<p>
  This view displays a timeline for each of the GOMAXPROCS logical
  processors, showing which goroutine (if any) was running on that
  logical processor at each moment.

  Each goroutine has an identifying number (e.g. G123), main function,
  and color.

  A colored bar represents an uninterrupted span of execution.

  Execution of a goroutine may migrate from one logical processor to another,
  causing a single colored bar to be horizontally continuous but
  vertically displaced.
</p>
<p>
  Clicking on a span reveals information about it, such as its
  duration, its causal predecessors and successors, and the stack trace
  at the final moment when it yielded the logical processor, for example
  because it made a system call or tried to acquire a mutex.

  Directly underneath each bar, a smaller bar or more commonly a fine
  vertical line indicates an event occurring during its execution.
  Some of these are related to garbage collection; most indicate that
  a goroutine yielded its logical processor but then immediately resumed execution
  on the same logical processor. Clicking on the event displays the stack trace
  at the moment it occurred.
</p>
<p>
  The causal relationships between spans of goroutine execution
  can be displayed by clicking the Flow Events button at the top.
</p>
<p>
  At the top ("STATS"), there are three additional timelines that
  display statistical information.

  "Goroutines" is a time series of the count of existing goroutines;
  clicking on it displays their breakdown by state at that moment:
  running, runnable, or waiting.

  "Heap" is a time series of the amount of heap memory allocated (in orange)
  and (in green) the allocation limit at which the next GC cycle will begin.

  "Threads" shows the number of kernel threads in existence: there is
  always one kernel thread per logical processor, and additional threads
  are created for calls to non-Go code such as a system call or a
  function written in C.
</p>
<p>
  Above the event trace for the first logical processor are
  traces for various runtime-internal events.

  The "GC" bar shows when the garbage collector is running, and in which stage.
  Garbage collection may temporarily affect all the logical processors
  and the other metrics.

  The "Network", "Timers", and "Syscalls" traces indicate events in
  the runtime that cause goroutines to wake up.
</p>
<p>
  The visualization allows you to navigate events at scales ranging from several
  seconds to a handful of nanoseconds.

  Consult the documentation for the Chromium <a href='https://www.chromium.org/developers/how-tos/trace-event-profiling-tool/'>Trace Event Profiling Tool<a/>
  for help navigating the view.
</p>

<ul>
<li><a href="/goroutines">Goroutine analysis</a></li>
</ul>
<p>
  This view displays information about each set of goroutines that
  shares the same main function.

  Clicking on a main function shows links to the four types of
  blocking profile (see below) applied to that subset of goroutines.

  It also shows a table of specific goroutine instances, with various
  execution statistics and a link to the event timeline for each one.

  The timeline displays only the selected goroutine and any others it
  interacts with via block/unblock events. (The timeline is
  goroutine-oriented rather than logical processor-oriented.)
</p>

<h2>Profiles</h2>
<p>
  Each link below displays a global profile in zoomable graph form as
  produced by <a href='https://go.dev/blog/pprof'>pprof</a>'s "web" command.

  In addition there is a link to download the profile for offline
  analysis with pprof.

  All four profiles represent causes of delay that prevent a goroutine
  from running on a logical processor: because it was waiting for the network,
  for a synchronization operation on a mutex or channel, for a system call,
  or for a logical processor to become available.
</p>
<ul>
<li><a href="/io">Network blocking profile</a> (<a href="/io?raw=1" download="io.profile">⬇</a>)</li>
<li><a href="/block">Synchronization blocking profile</a> (<a href="/block?raw=1" download="block.profile">⬇</a>)</li>
<li><a href="/syscall">Syscall blocking profile</a> (<a href="/syscall?raw=1" download="syscall.profile">⬇</a>)</li>
<li><a href="/sched">Scheduler latency profile</a> (<a href="/sche?raw=1" download="sched.profile">⬇</a>)</li>
</ul>

<h2>User-defined tasks and regions</h2>
<p>
  The trace API allows a target program to annotate a <a
  href='https://pkg.go.dev/runtime/trace#Region'>region</a> of code
  within a goroutine, such as a key function, so that its performance
  can be analyzed.

  <a href='https://pkg.go.dev/runtime/trace#Log'>Log events</a> may be
  associated with a region to record progress and relevant values.

  The API also allows annotation of higher-level
  <a href='https://pkg.go.dev/runtime/trace#Task'>tasks</a>,
  which may involve work across many goroutines.
</p>
<p>
  The links below display, for each region and task, a histogram of its execution times.

  Each histogram bucket contains a sample trace that records the
  sequence of events such as goroutine creations, log events, and
  subregion start/end times.

  For each task, you can click through to a logical-processor or
  goroutine-oriented view showing the tasks and regions on the
  timeline.

  Such information may help uncover which steps in a region are
  unexpectedly slow, or reveal relationships between the data values
  logged in a request and its running time.
</p>
<ul>
<li><a href="/usertasks">User-defined tasks</a></li>
<li><a href="/userregions">User-defined regions</a></li>
</ul>

<h2>Garbage collection metrics</h2>
<ul>
<li><a href="/mmu">Minimum mutator utilization</a></li>
</ul>
<p>
  This chart indicates the maximum GC pause time (the largest x value
  for which y is zero), and more generally, the fraction of time that
  the processors are available to application goroutines ("mutators"),
  for any time window of a specified size, in the worst case.
</p>
</body>
</html>
`))

func dief(msg string, args ...any) {
	fmt.Fprintf(os.Stderr, msg, args...)
	os.Exit(1)
}

var debugMemoryUsage bool

func init() {
	v := os.Getenv("DEBUG_MEMORY_USAGE")
	debugMemoryUsage = v != ""
}

func reportMemoryUsage(msg string) {
	if !debugMemoryUsage {
		return
	}
	var s runtime.MemStats
	runtime.ReadMemStats(&s)
	w := os.Stderr
	fmt.Fprintf(w, "%s\n", msg)
	fmt.Fprintf(w, " Alloc:\t%d Bytes\n", s.Alloc)
	fmt.Fprintf(w, " Sys:\t%d Bytes\n", s.Sys)
	fmt.Fprintf(w, " HeapReleased:\t%d Bytes\n", s.HeapReleased)
	fmt.Fprintf(w, " HeapSys:\t%d Bytes\n", s.HeapSys)
	fmt.Fprintf(w, " HeapInUse:\t%d Bytes\n", s.HeapInuse)
	fmt.Fprintf(w, " HeapAlloc:\t%d Bytes\n", s.HeapAlloc)
	var dummy string
	fmt.Printf("Enter to continue...")
	fmt.Scanf("%s", &dummy)
}
