Added all required dependencies
This commit is contained in:
parent
78f86abba4
commit
1ebb35b988
660 changed files with 502447 additions and 0 deletions
163
vendor/github.com/go-macaron/toolbox/profile.go
generated
vendored
Normal file
163
vendor/github.com/go-macaron/toolbox/profile.go
generated
vendored
Normal file
|
@ -0,0 +1,163 @@
|
|||
// Copyright 2013 Beego Authors
|
||||
// Copyright 2014 The Macaron Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package toolbox
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"runtime/pprof"
|
||||
"time"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
"gopkg.in/macaron.v1"
|
||||
)
|
||||
|
||||
var (
|
||||
profilePath string
|
||||
pid int
|
||||
startTime = time.Now()
|
||||
inCPUProfile bool
|
||||
)
|
||||
|
||||
// StartCPUProfile starts CPU profile monitor.
|
||||
func StartCPUProfile() error {
|
||||
if inCPUProfile {
|
||||
return errors.New("CPU profile has alreday been started!")
|
||||
}
|
||||
inCPUProfile = true
|
||||
|
||||
os.MkdirAll(profilePath, os.ModePerm)
|
||||
f, err := os.Create(path.Join(profilePath, "cpu-"+com.ToStr(pid)+".pprof"))
|
||||
if err != nil {
|
||||
panic("fail to record CPU profile: " + err.Error())
|
||||
}
|
||||
pprof.StartCPUProfile(f)
|
||||
return nil
|
||||
}
|
||||
|
||||
// StopCPUProfile stops CPU profile monitor.
|
||||
func StopCPUProfile() error {
|
||||
if !inCPUProfile {
|
||||
return errors.New("CPU profile hasn't been started!")
|
||||
}
|
||||
pprof.StopCPUProfile()
|
||||
inCPUProfile = false
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
pid = os.Getpid()
|
||||
}
|
||||
|
||||
// DumpMemProf dumps memory profile in pprof.
|
||||
func DumpMemProf(w io.Writer) {
|
||||
pprof.WriteHeapProfile(w)
|
||||
}
|
||||
|
||||
func dumpMemProf() {
|
||||
os.MkdirAll(profilePath, os.ModePerm)
|
||||
f, err := os.Create(path.Join(profilePath, "mem-"+com.ToStr(pid)+".memprof"))
|
||||
if err != nil {
|
||||
panic("fail to record memory profile: " + err.Error())
|
||||
}
|
||||
runtime.GC()
|
||||
DumpMemProf(f)
|
||||
f.Close()
|
||||
}
|
||||
|
||||
func avg(items []time.Duration) time.Duration {
|
||||
var sum time.Duration
|
||||
for _, item := range items {
|
||||
sum += item
|
||||
}
|
||||
return time.Duration(int64(sum) / int64(len(items)))
|
||||
}
|
||||
|
||||
func dumpGC(memStats *runtime.MemStats, gcstats *debug.GCStats, w io.Writer) {
|
||||
|
||||
if gcstats.NumGC > 0 {
|
||||
lastPause := gcstats.Pause[0]
|
||||
elapsed := time.Now().Sub(startTime)
|
||||
overhead := float64(gcstats.PauseTotal) / float64(elapsed) * 100
|
||||
allocatedRate := float64(memStats.TotalAlloc) / elapsed.Seconds()
|
||||
|
||||
fmt.Fprintf(w, "NumGC:%d Pause:%s Pause(Avg):%s Overhead:%3.2f%% Alloc:%s Sys:%s Alloc(Rate):%s/s Histogram:%s %s %s \n",
|
||||
gcstats.NumGC,
|
||||
com.ToStr(lastPause),
|
||||
com.ToStr(avg(gcstats.Pause)),
|
||||
overhead,
|
||||
com.HumaneFileSize(memStats.Alloc),
|
||||
com.HumaneFileSize(memStats.Sys),
|
||||
com.HumaneFileSize(uint64(allocatedRate)),
|
||||
com.ToStr(gcstats.PauseQuantiles[94]),
|
||||
com.ToStr(gcstats.PauseQuantiles[98]),
|
||||
com.ToStr(gcstats.PauseQuantiles[99]))
|
||||
} else {
|
||||
// while GC has disabled
|
||||
elapsed := time.Now().Sub(startTime)
|
||||
allocatedRate := float64(memStats.TotalAlloc) / elapsed.Seconds()
|
||||
|
||||
fmt.Fprintf(w, "Alloc:%s Sys:%s Alloc(Rate):%s/s\n",
|
||||
com.HumaneFileSize(memStats.Alloc),
|
||||
com.HumaneFileSize(memStats.Sys),
|
||||
com.HumaneFileSize(uint64(allocatedRate)))
|
||||
}
|
||||
}
|
||||
|
||||
// DumpGCSummary dumps GC information to io.Writer
|
||||
func DumpGCSummary(w io.Writer) {
|
||||
memStats := &runtime.MemStats{}
|
||||
runtime.ReadMemStats(memStats)
|
||||
gcstats := &debug.GCStats{PauseQuantiles: make([]time.Duration, 100)}
|
||||
debug.ReadGCStats(gcstats)
|
||||
|
||||
dumpGC(memStats, gcstats, w)
|
||||
}
|
||||
|
||||
func handleProfile(ctx *macaron.Context) string {
|
||||
switch ctx.Query("op") {
|
||||
case "startcpu":
|
||||
if err := StartCPUProfile(); err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
case "stopcpu":
|
||||
if err := StopCPUProfile(); err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
case "mem":
|
||||
dumpMemProf()
|
||||
case "gc":
|
||||
var buf bytes.Buffer
|
||||
DumpGCSummary(&buf)
|
||||
return string(buf.Bytes())
|
||||
default:
|
||||
return fmt.Sprintf(`<p>Available operations:</p>
|
||||
<ol>
|
||||
<li><a href="%[1]s?op=startcpu">Start CPU profile</a></li>
|
||||
<li><a href="%[1]s?op=stopcpu">Stop CPU profile</a></li>
|
||||
<li><a href="%[1]s?op=mem">Dump memory profile</a></li>
|
||||
<li><a href="%[1]s?op=gc">Dump GC summary</a></li>
|
||||
</ol>`, opt.ProfileURLPrefix)
|
||||
}
|
||||
ctx.Redirect(opt.ProfileURLPrefix)
|
||||
return ""
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue