1 // Copyright 2019 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.
13 // Rlog contains the processed logs
15 Logs []*Logmsg // In the order in the log file
16 ServerCall map[string]*Logmsg // ID->Request, client->server
17 ServerReply map[string]*Logmsg // ID->Response, server->client (includes Errors)
18 ClientCall map[string]*Logmsg
19 ClientReply map[string]*Logmsg
20 ClientNotifs []*Logmsg
21 ServerNotifs []*Logmsg
25 func newRlog(x []*Logmsg) *Rlog {
27 ServerCall: make(map[string]*Logmsg),
28 ServerReply: make(map[string]*Logmsg),
29 ClientCall: make(map[string]*Logmsg),
30 ClientReply: make(map[string]*Logmsg),
31 ClientNotifs: []*Logmsg{},
32 ServerNotifs: []*Logmsg{},
33 Histogram: &LogHist{},
37 // Counts returns a one-line summary of an Rlog
38 func (r *Rlog) Counts() string {
39 return fmt.Sprintf("logs:%d srvC:%d srvR:%d clC:%d clR:%d clN:%d srvN:%d",
41 len(r.ServerCall), len(r.ServerReply), len(r.ClientCall), len(r.ClientReply),
42 len(r.ClientNotifs), len(r.ServerNotifs))
45 // ToRlog reads a log file and returns a *Rlog
46 func ToRlog(fname string) (*Rlog, error) {
47 x, err := ReadLogs(fname)
55 ans.ServerCall[l.ID] = l
57 ans.ServerReply[l.ID] = l
58 if l.Type != ReportErr {
60 fmt.Sscanf(l.Elapsed, "%d", &n)
64 ans.ClientCall[l.ID] = l
66 ans.ClientReply[l.ID] = l
68 ans.ClientNotifs = append(ans.ClientNotifs, l)
70 ans.ServerNotifs = append(ans.ServerNotifs, l)
72 ans.ServerReply[l.ID] = l
73 l.Method = ans.ServerCall[l.ID].Method // Method not in log message
75 log.Fatalf("eh? %s/%s (%s)", l.Type, l.Method, l.ID)
81 // LogHist gets ints, and puts them into buckets:
82 // <=10, <=30, 100, 300, 1000, ...
83 // It produces a historgram of elapsed times in milliseconds
88 func (l *LogHist) add(n int) {
93 for ; n > 0; n /= 10 {
103 if len(l.cnts) <= bucket {
104 for j := len(l.cnts); j < bucket+10; j++ {
105 l.cnts = append(l.cnts, 0)
111 // String returns a string describing a histogram
112 func (l *LogHist) String() string {
113 top := len(l.cnts) - 1
114 for ; top > 0 && l.cnts[top] == 0; top-- {
116 labs := []string{"10", "30"}
117 out := strings.Builder{}
119 for i := 0; i <= top; i++ {
122 fmt.Fprintf(&out, "%s:%d ", label, l.cnts[i])