...

Source file src/internal/trace/testdata/cmd/gotraceeventstats/main.go

Documentation: internal/trace/testdata/cmd/gotraceeventstats

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"cmp"
     9  	"encoding/binary"
    10  	"flag"
    11  	"fmt"
    12  	"io"
    13  	"log"
    14  	"os"
    15  	"slices"
    16  	"text/tabwriter"
    17  
    18  	"internal/trace/event"
    19  	"internal/trace/raw"
    20  )
    21  
    22  func init() {
    23  	flag.Usage = func() {
    24  		fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s [mode]\n", os.Args[0])
    25  		fmt.Fprintf(flag.CommandLine.Output(), "\n")
    26  		fmt.Fprintf(flag.CommandLine.Output(), "Accepts a trace at stdin.\n")
    27  		fmt.Fprintf(flag.CommandLine.Output(), "\n")
    28  		fmt.Fprintf(flag.CommandLine.Output(), "Supported modes:")
    29  		fmt.Fprintf(flag.CommandLine.Output(), "\n")
    30  		fmt.Fprintf(flag.CommandLine.Output(), "* size  - dumps size stats\n")
    31  		fmt.Fprintf(flag.CommandLine.Output(), "\n")
    32  		flag.PrintDefaults()
    33  	}
    34  	log.SetFlags(0)
    35  }
    36  
    37  func main() {
    38  	log.SetPrefix("")
    39  	flag.Parse()
    40  
    41  	if flag.NArg() != 1 {
    42  		log.Print("missing mode argument")
    43  		flag.Usage()
    44  		os.Exit(1)
    45  	}
    46  	var err error
    47  	switch mode := flag.Arg(0); mode {
    48  	case "size":
    49  		err = printSizeStats(os.Stdin)
    50  	default:
    51  		log.Printf("unknown mode %q", mode)
    52  		flag.Usage()
    53  		os.Exit(1)
    54  	}
    55  	if err != nil {
    56  		log.Fatalf("error: %v", err)
    57  		os.Exit(1)
    58  	}
    59  }
    60  
    61  func printSizeStats(r io.Reader) error {
    62  	cr := countingReader{Reader: r}
    63  	tr, err := raw.NewReader(&cr)
    64  	if err != nil {
    65  		return err
    66  	}
    67  	type eventStats struct {
    68  		typ   event.Type
    69  		count int
    70  		bytes int
    71  	}
    72  	var stats [256]eventStats
    73  	for i := range stats {
    74  		stats[i].typ = event.Type(i)
    75  	}
    76  	eventsRead := 0
    77  	for {
    78  		e, err := tr.ReadEvent()
    79  		if err == io.EOF {
    80  			break
    81  		}
    82  		if err != nil {
    83  			return err
    84  		}
    85  		s := &stats[e.Ev]
    86  		s.count++
    87  		s.bytes += encodedSize(&e)
    88  		eventsRead++
    89  	}
    90  	slices.SortFunc(stats[:], func(a, b eventStats) int {
    91  		return cmp.Compare(b.bytes, a.bytes)
    92  	})
    93  	specs := tr.Version().Specs()
    94  	w := tabwriter.NewWriter(os.Stdout, 3, 8, 2, ' ', 0)
    95  	fmt.Fprintf(w, "Event\tBytes\t%%\tCount\t%%\n")
    96  	fmt.Fprintf(w, "-\t-\t-\t-\t-\n")
    97  	for i := range stats {
    98  		stat := &stats[i]
    99  		name := ""
   100  		if int(stat.typ) >= len(specs) {
   101  			name = fmt.Sprintf("<unknown (%d)>", stat.typ)
   102  		} else {
   103  			name = specs[stat.typ].Name
   104  		}
   105  		bytesPct := float64(stat.bytes) / float64(cr.bytesRead) * 100
   106  		countPct := float64(stat.count) / float64(eventsRead) * 100
   107  		fmt.Fprintf(w, "%s\t%d\t%.2f%%\t%d\t%.2f%%\n", name, stat.bytes, bytesPct, stat.count, countPct)
   108  	}
   109  	w.Flush()
   110  	return nil
   111  }
   112  
   113  func encodedSize(e *raw.Event) int {
   114  	size := 1
   115  	var buf [binary.MaxVarintLen64]byte
   116  	for _, arg := range e.Args {
   117  		size += binary.PutUvarint(buf[:], arg)
   118  	}
   119  	spec := e.Version.Specs()[e.Ev]
   120  	if spec.HasData {
   121  		size += binary.PutUvarint(buf[:], uint64(len(e.Data)))
   122  		size += len(e.Data)
   123  	}
   124  	return size
   125  }
   126  
   127  type countingReader struct {
   128  	io.Reader
   129  	bytesRead int
   130  }
   131  
   132  func (r *countingReader) Read(b []byte) (int, error) {
   133  	n, err := r.Reader.Read(b)
   134  	r.bytesRead += n
   135  	return n, err
   136  }
   137  

View as plain text