blob: aced1d6220cdd7bdb5e51f12058deaf5f94e8a45 [file] [log] [blame]
Shinichiro Hamajib69bf8a2015-06-10 14:52:06 +09001// Copyright 2015 Google Inc. All rights reserved
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Fumitoshi Ukai6ac7f692015-04-15 17:13:51 +090015package main
16
17import (
18 "fmt"
Fumitoshi Ukai432a2422015-06-11 15:16:29 +090019 "io"
20 "os"
Fumitoshi Ukai6ac7f692015-04-15 17:13:51 +090021 "sort"
22 "time"
23)
24
Fumitoshi Ukai432a2422015-06-11 15:16:29 +090025type traceEventT struct {
26 f io.WriteCloser
27 t0 time.Time
28 pid int
29}
30
31var traceEvent traceEventT
32
33func (t *traceEventT) start(f io.WriteCloser) {
34 t.f = f
35 t.t0 = time.Now()
36 fmt.Fprint(t.f, "[ ")
37}
38
39func (t *traceEventT) enabled() bool {
40 return t.f != nil
41}
42
43func (t *traceEventT) stop() {
44 fmt.Fprint(t.f, "\n]\n")
45 t.f.Close()
46}
47
48type event struct {
49 name, v string
50 t time.Time
Fumitoshi Ukaicb393c52015-06-11 15:34:10 +090051 emit bool
Fumitoshi Ukai432a2422015-06-11 15:16:29 +090052}
53
54func (t *traceEventT) begin(name string, v Value) event {
55 var e event
56 e.t = time.Now()
57 if t.f != nil {
Fumitoshi Ukaicb393c52015-06-11 15:34:10 +090058 e.emit = name == "include" || name == "shell"
Fumitoshi Ukai432a2422015-06-11 15:16:29 +090059 if t.pid == 0 {
60 t.pid = os.Getpid()
Fumitoshi Ukaicb393c52015-06-11 15:34:10 +090061 } else if e.emit {
Fumitoshi Ukai432a2422015-06-11 15:16:29 +090062 fmt.Fprint(t.f, ",\n")
63 }
64 e.name = name
65 e.v = v.String()
Fumitoshi Ukaicb393c52015-06-11 15:34:10 +090066 if e.emit {
Fumitoshi Ukai432a2422015-06-11 15:16:29 +090067 ts := e.t.Sub(t.t0)
68 fmt.Fprintf(t.f, `{"pid":%d,"tid":1,"ts":%d,"ph":"B","cat":%q,"name":%q,"args":{}}`,
69 t.pid,
70 ts.Nanoseconds()/1e3,
71 e.name,
72 e.v,
73 )
74 }
75 }
76 return e
77}
78
79func (t *traceEventT) end(e event) {
80 if t.f != nil {
81 now := time.Now()
82 ts := now.Sub(t.t0)
Fumitoshi Ukaicb393c52015-06-11 15:34:10 +090083 if e.emit {
Fumitoshi Ukai432a2422015-06-11 15:16:29 +090084 fmt.Fprint(t.f, ",\n")
85 fmt.Fprintf(t.f, `{"pid":%d,"tid":1,"ts":%d,"ph":"E","cat":%q,"name":%q}`,
86 t.pid,
87 ts.Nanoseconds()/1e3,
88 e.name,
89 e.v,
90 )
91 }
92 }
93 addStats(e.name, e.v, e.t)
94}
95
Fumitoshi Ukai6ac7f692015-04-15 17:13:51 +090096type statsData struct {
97 Name string
98 Count int
99 Longest time.Duration
100 Total time.Duration
101}
102
103var stats = map[string]statsData{}
104
Fumitoshi Ukai432a2422015-06-11 15:16:29 +0900105func addStats(name, v string, t time.Time) {
Fumitoshi Ukai586b02a2015-05-08 00:23:10 +0900106 if !katiEvalStatsFlag {
Fumitoshi Ukai6ac7f692015-04-15 17:13:51 +0900107 return
108 }
Fumitoshi Ukai358c68a2015-06-08 13:12:55 +0900109 d := time.Since(t)
Fumitoshi Ukai432a2422015-06-11 15:16:29 +0900110 key := fmt.Sprintf("%s:%s", name, v)
Fumitoshi Ukai6ac7f692015-04-15 17:13:51 +0900111 s := stats[key]
112 if d > s.Longest {
113 s.Longest = d
114 }
115 s.Total += d
116 s.Count++
117 stats[key] = s
118}
119
120func dumpStats() {
Fumitoshi Ukai586b02a2015-05-08 00:23:10 +0900121 if !katiEvalStatsFlag {
Fumitoshi Ukai6ac7f692015-04-15 17:13:51 +0900122 return
123 }
124 var sv byTotalTime
125 for k, v := range stats {
126 v.Name = k
127 sv = append(sv, v)
128 }
129 sort.Sort(sv)
Fumitoshi Ukai47f401f2015-04-30 17:29:50 +0900130 fmt.Println("count,longest(ns),total(ns),longest,total,name")
Fumitoshi Ukai6ac7f692015-04-15 17:13:51 +0900131 for _, s := range sv {
Fumitoshi Ukai47f401f2015-04-30 17:29:50 +0900132 fmt.Printf("%d,%d,%d,%v,%v,%s\n", s.Count, s.Longest, s.Total, s.Longest, s.Total, s.Name)
Fumitoshi Ukai6ac7f692015-04-15 17:13:51 +0900133 }
134}
135
136type byTotalTime []statsData
137
138func (b byTotalTime) Len() int { return len(b) }
139func (b byTotalTime) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
140func (b byTotalTime) Less(i, j int) bool {
141 return b[i].Total > b[j].Total
142}