mirror of https://github.com/golang/go.git
internal/trace/v2: add gotraceeventstats utility
Change-Id: Ibf83d74a76edf2fe2896fa1e7f93ab1296fc5d75 Reviewed-on: https://go-review.googlesource.com/c/go/+/583378 Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
parent
724bab1505
commit
c3bd543cc3
|
|
@ -0,0 +1,136 @@
|
|||
// Copyright 2023 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 (
|
||||
"cmp"
|
||||
"encoding/binary"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"slices"
|
||||
"text/tabwriter"
|
||||
|
||||
"internal/trace/v2/event"
|
||||
"internal/trace/v2/raw"
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.Usage = func() {
|
||||
fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s [mode]\n", os.Args[0])
|
||||
fmt.Fprintf(flag.CommandLine.Output(), "\n")
|
||||
fmt.Fprintf(flag.CommandLine.Output(), "Accepts a trace at stdin.\n")
|
||||
fmt.Fprintf(flag.CommandLine.Output(), "\n")
|
||||
fmt.Fprintf(flag.CommandLine.Output(), "Supported modes:")
|
||||
fmt.Fprintf(flag.CommandLine.Output(), "\n")
|
||||
fmt.Fprintf(flag.CommandLine.Output(), "* size - dumps size stats\n")
|
||||
fmt.Fprintf(flag.CommandLine.Output(), "\n")
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
log.SetFlags(0)
|
||||
}
|
||||
|
||||
func main() {
|
||||
log.SetPrefix("")
|
||||
flag.Parse()
|
||||
|
||||
if flag.NArg() != 1 {
|
||||
log.Print("missing mode argument")
|
||||
flag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
var err error
|
||||
switch mode := flag.Arg(0); mode {
|
||||
case "size":
|
||||
err = printSizeStats(os.Stdin)
|
||||
default:
|
||||
log.Printf("unknown mode %q", mode)
|
||||
flag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func printSizeStats(r io.Reader) error {
|
||||
cr := countingReader{Reader: r}
|
||||
tr, err := raw.NewReader(&cr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
type eventStats struct {
|
||||
typ event.Type
|
||||
count int
|
||||
bytes int
|
||||
}
|
||||
var stats [256]eventStats
|
||||
for i := range stats {
|
||||
stats[i].typ = event.Type(i)
|
||||
}
|
||||
eventsRead := 0
|
||||
for {
|
||||
e, err := tr.ReadEvent()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s := &stats[e.Ev]
|
||||
s.count++
|
||||
s.bytes += encodedSize(&e)
|
||||
eventsRead++
|
||||
}
|
||||
slices.SortFunc(stats[:], func(a, b eventStats) int {
|
||||
return cmp.Compare(b.bytes, a.bytes)
|
||||
})
|
||||
specs := tr.Version().Specs()
|
||||
w := tabwriter.NewWriter(os.Stdout, 3, 8, 2, ' ', 0)
|
||||
fmt.Fprintf(w, "Event\tBytes\t%%\tCount\t%%\n")
|
||||
fmt.Fprintf(w, "-\t-\t-\t-\t-\n")
|
||||
for i := range stats {
|
||||
stat := &stats[i]
|
||||
name := ""
|
||||
if int(stat.typ) >= len(specs) {
|
||||
name = fmt.Sprintf("<unknown (%d)>", stat.typ)
|
||||
} else {
|
||||
name = specs[stat.typ].Name
|
||||
}
|
||||
bytesPct := float64(stat.bytes) / float64(cr.bytesRead) * 100
|
||||
countPct := float64(stat.count) / float64(eventsRead) * 100
|
||||
fmt.Fprintf(w, "%s\t%d\t%.2f%%\t%d\t%.2f%%\n", name, stat.bytes, bytesPct, stat.count, countPct)
|
||||
}
|
||||
w.Flush()
|
||||
return nil
|
||||
}
|
||||
|
||||
func encodedSize(e *raw.Event) int {
|
||||
size := 1
|
||||
var buf [binary.MaxVarintLen64]byte
|
||||
for _, arg := range e.Args {
|
||||
size += binary.PutUvarint(buf[:], arg)
|
||||
}
|
||||
spec := e.Version.Specs()[e.Ev]
|
||||
if spec.HasData {
|
||||
size += binary.PutUvarint(buf[:], uint64(len(e.Data)))
|
||||
size += len(e.Data)
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
type countingReader struct {
|
||||
io.Reader
|
||||
bytesRead int
|
||||
}
|
||||
|
||||
func (r *countingReader) Read(b []byte) (int, error) {
|
||||
n, err := r.Reader.Read(b)
|
||||
r.bytesRead += n
|
||||
return n, err
|
||||
}
|
||||
Loading…
Reference in New Issue