profile.go
// Package profile provides a simple way to manage runtime/pprof
// profiling of your Go application.
package profile
import (
"io/ioutil"
"log"
"os"
"os/signal"
"path/filepath"
"runtime"
"runtime/pprof"
"sync/atomic"
)
const (
cpuMode = iota
memMode
blockMode
traceMode
)
// Profile represents an active profiling session.
type Profile struct {
// quiet suppresses informational messages during profiling.
quiet bool
// noShutdownHook controls whether the profiling package should
// hook SIGINT to write profiles cleanly.
noShutdownHook bool
// mode holds the type of profiling that will be made
mode int
// path holds the base path where various profiling files are written.
// If blank, the base path will be generated by ioutil.TempDir.
path string
// memProfileRate holds the rate for the memory profile.
memProfileRate int
// closer holds a cleanup function that run after each profile
closer func()
// stopped records if a call to profile.Stop has been made
stopped uint32
}
// NoShutdownHook controls whether the profiling package should
// hook SIGINT to write profiles cleanly.
// Programs with more sophisticated signal handling should set
// this to true and ensure the Stop() function returned from Start()
// is called during shutdown.
func NoShutdownHook(p *Profile) { p.noShutdownHook = true }
// Quiet suppresses informational messages during profiling.
func Quiet(p *Profile) { p.quiet = true }
// CPUProfile enables cpu profiling.
// It disables any previous profiling settings.
func CPUProfile(p *Profile) { p.mode = cpuMode }
// DefaultMemProfileRate is the default memory profiling rate.
// See also http://golang.org/pkg/runtime/#pkg-variables
const DefaultMemProfileRate = 4096
// MemProfile enables memory profiling.
// It disables any previous profiling settings.
func MemProfile(p *Profile) {
p.memProfileRate = DefaultMemProfileRate
p.mode = memMode
}
// MemProfileRate enables memory profiling at the preferred rate.
// It disables any previous profiling settings.
func MemProfileRate(rate int) func(*Profile) {
return func(p *Profile) {
p.memProfileRate = rate
p.mode = memMode
}
}
// BlockProfile enables block (contention) profiling.
// It disables any previous profiling settings.
func BlockProfile(p *Profile) { p.mode = blockMode }
// Trace profile controls if execution tracing will be enabled. It disables any previous profiling settings.
func TraceProfile(p *Profile) { p.mode = traceMode }
// ProfilePath controls the base path where various profiling
// files are written. If blank, the base path will be generated
// by ioutil.TempDir.
func ProfilePath(path string) func(*Profile) {
return func(p *Profile) {
p.path = path
}
}
// Stop stops the profile and flushes any unwritten data.
func (p *Profile) Stop() {
if !atomic.CompareAndSwapUint32(&p.stopped, 0, 1) {
// someone has already called close
return
}
p.closer()
atomic.StoreUint32(&started, 0)
}
// started is non zero if a profile is running.
var started uint32
// Start starts a new profiling session.
// The caller should call the Stop method on the value returned
// to cleanly stop profiling.
func Start(options ...func(*Profile)) interface {
Stop()
} {
if !atomic.CompareAndSwapUint32(&started, 0, 1) {
log.Fatal("profile: Start() already called")
}
var prof Profile
for _, option := range options {
option(&prof)
}
path, err := func() (string, error) {
if p := prof.path; p != "" {
return p, os.MkdirAll(p, 0777)
}
return ioutil.TempDir("", "profile")
}()
if err != nil {
log.Fatalf("profile: could not create initial output directory: %v", err)
}
logf := func(format string, args ...interface{}) {
if !prof.quiet {
log.Printf(format, args...)
}
}
switch prof.mode {
case cpuMode:
fn := filepath.Join(path, "cpu.pprof")
f, err := os.Create(fn)
if err != nil {
log.Fatalf("profile: could not create cpu profile %q: %v", fn, err)
}
logf("profile: cpu profiling enabled, %s", fn)
pprof.StartCPUProfile(f)
prof.closer = func() {
pprof.StopCPUProfile()
f.Close()
logf("profile: cpu profiling disabled, %s", fn)
}
case memMode:
fn := filepath.Join(path, "mem.pprof")
f, err := os.Create(fn)
if err != nil {
log.Fatalf("profile: could not create memory profile %q: %v", fn, err)
}
old := runtime.MemProfileRate
runtime.MemProfileRate = prof.memProfileRate
logf("profile: memory profiling enabled (rate %d), %s", runtime.MemProfileRate, fn)
prof.closer = func() {
pprof.Lookup("heap").WriteTo(f, 0)
f.Close()
runtime.MemProfileRate = old
logf("profile: memory profiling disabled, %s", fn)
}
case blockMode:
fn := filepath.Join(path, "block.pprof")
f, err := os.Create(fn)
if err != nil {
log.Fatalf("profile: could not create block profile %q: %v", fn, err)
}
runtime.SetBlockProfileRate(1)
logf("profile: block profiling enabled, %s", fn)
prof.closer = func() {
pprof.Lookup("block").WriteTo(f, 0)
f.Close()
runtime.SetBlockProfileRate(0)
logf("profile: block profiling disabled, %s", fn)
}
case traceMode:
fn := filepath.Join(path, "trace.out")
f, err := os.Create(fn)
if err != nil {
log.Fatalf("profile: could not create trace output file %q: %v", fn, err)
}
if err := startTrace(f); err != nil {
log.Fatalf("profile: could not start trace: %v", err)
}
logf("profile: trace enabled, %s", fn)
prof.closer = func() {
stopTrace()
logf("profile: trace disabled, %s", fn)
}
}
if !prof.noShutdownHook {
go func() {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
<-c
log.Println("profile: caught interrupt, stopping profiles")
prof.Stop()
os.Exit(0)
}()
}
return &prof
}
profile.go的更多相关文章
- CoreCRM 开发实录 —— Profile
再简单的功能,也需要一坨代码的支持.Profile 的编辑功能主要就是修改个人的信息.比如用户名.头像.性别.电话--虽然只是一个编辑界面,但添加下来,涉及了6个文件的修改和7个新创建的文件.各种生成 ...
- Xamarin+Prism开发详解一:PCL跨平台类库与Profile的关系
在[Xamarin+Prism小试牛刀:定制跨平台Outlook邮箱应用]中提到过以下错误,不知道大伙还记得不: 无法安装程序包"Microsoft.Identity.Client 1.0. ...
- source /etc/profile报错-bash: id:command is not found
由于误操作导致 source /etc/profile 报错 -bash: id:command is not found 此时,linux下很多命令到不能能用,包括vi ls 等... 可以使用 e ...
- 【译】Spring 4 @Profile注解示例
前言 译文链接:http://websystique.com/spring/spring-profile-example/ 本文将探索Spring中的@Profile注解,可以实现不同环境(开发.测试 ...
- Linix登录报"/etc/profile: line 11: syntax error near unexpected token `$'{\r''"
同事反馈他在一测试服务器(CentOS Linux release 7.2.1511)上修改了/etc/profile文件后,使用source命令不能生效,让我帮忙看看,结果使用SecureCRT一登 ...
- Spring profile配置应用
spring配置文件中可以配置多套不同环境配置,如下: <beans xml.....> <beans profile="dev"> < ...
- 项目实现不同环境不同配置文件-maven profile
最近接触的项目都是在很多地方都落地的项目,需要支持不同的环境使用不同的配置文件.一直以来都以为是人工的去写不同的配置文件,手动的去修改运用的配置文件.感觉自己还是太low呀.maven的使用的还停留在 ...
- 修改/etc/profile和/etc/environment导致图形界面无法登陆的问题
在使用ubuntu开发时,往往要修改PATH变量,有时会通过修改/etc/profile和/etc/environment来修改默认的PATH变量,但是一旦出错,很容易造成无法登陆进入图形界面的问题. ...
- RF Firefox Profile
默认情况下,robot framework是启动不带任何配置信息的firefox,如果需要启动带有profile的话,增加一个参数即可,如 Open Browser https://aws-qa5.i ...
- Linux知识:/root/.bashrc与/etc/profile的异同
Linux知识:/root/.bashrc与/etc/profile的异同 要搞清bashrc与profile的区别,首先要弄明白什么是交互式shell和非交互式shell,什么是login shel ...
随机推荐
- JVM terminated. Exit code=8096
http://www-01.ibm.com/support/docview.wss?uid=swg21303648 Technote (troubleshooting) Problem(Abstrac ...
- 从Freelancer的热门Skill看看你应该学什么?
以下数据是2012-1-31号数据. Websites, IT & Software: PHP (2402)HTML (1639)SEO(877)MySQL (836)Link Buildin ...
- java基本数据类型及其包装类
1.String类 String s1 = "hello world"; String s2 = "hello world"; String s3 = s1 + ...
- phone number
problem description: you should change the given digits string into possible letter string according ...
- developers.google.com上的开发者文档如何切换显示语言
一个小的tip,搜索到developers.google.com上的开发者文档,有些被翻译了的会自动显示中本版,如果想看英文版,可以在当前url后面加?hl=en,就会变成英文版.估计是根据地区直接推 ...
- 架构之Nginx(负载均衡/反向代理)
Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器 ,也是一个 IMAP/POP3/SMTP 代理 服务器 . Nginx 是由 Igor Sys ...
- MySQL中的外键约束
- TCP分组交换详解
TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种标 ...
- 阿里Java架构师谈谈架构和如何成为一个Java架构师
架构的定义 我们来看看软件架构的一般定义: 程序和计算系统软件体系结构是指系统的一个或多个结构. 该结构包括软件的构建,构建的外部可见属性以及它们之间的相互关系. 该体系结构不是可操作的软件. 具体来 ...
- 微信小程序开发问题汇总
前言 经过将近一个多月的开发,我们团队开发的微信小程序 "出发吧一起" 终于开发完成,现在的线上版本为 2.2.4-beta 版 本文档主要介绍该小程序在开发中所用到的技术,已经在 ...