79 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			79 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Go
		
	
	
package httpsr
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"fmt"
 | 
						|
	"git.makemake.in/kzkzzzz/mycommon/graceful"
 | 
						|
	"github.com/gin-contrib/pprof"
 | 
						|
	"github.com/gin-gonic/gin"
 | 
						|
	"log"
 | 
						|
	"net"
 | 
						|
	"net/http"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
var _ graceful.IRunner = (*PProf)(nil)
 | 
						|
 | 
						|
type PProf struct {
 | 
						|
	conf *pprofConf
 | 
						|
	hs   *http.Server
 | 
						|
}
 | 
						|
type pprofConf struct {
 | 
						|
	Port int
 | 
						|
}
 | 
						|
 | 
						|
type PProfOpt func(*pprofConf)
 | 
						|
 | 
						|
func NewPProf(opts ...PProfOpt) *PProf {
 | 
						|
	engine := gin.Default()
 | 
						|
	pprof.Register(engine)
 | 
						|
 | 
						|
	p := &PProf{
 | 
						|
		conf: &pprofConf{},
 | 
						|
		hs: &http.Server{
 | 
						|
			Handler: engine,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for _, opt := range opts {
 | 
						|
		opt(p.conf)
 | 
						|
	}
 | 
						|
 | 
						|
	return p
 | 
						|
}
 | 
						|
 | 
						|
func (p *PProf) Run(ctx context.Context) error {
 | 
						|
	// 端口如果=0, 监听随机端口
 | 
						|
	addr0 := fmt.Sprintf(":%d", p.conf.Port)
 | 
						|
	lis, err := net.Listen("tcp", addr0)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	// 获取监听的端口
 | 
						|
	port := lis.Addr().(*net.TCPAddr).Port
 | 
						|
 | 
						|
	addr := fmt.Sprintf(":%d", port)
 | 
						|
	log.Printf("http pprof server listen on %s", addr)
 | 
						|
 | 
						|
	p.hs.Addr = addr
 | 
						|
 | 
						|
	err = p.hs.Serve(lis)
 | 
						|
	if err != nil {
 | 
						|
		log.Printf("start http pprof server err: %s", err)
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (p *PProf) Stop() {
 | 
						|
	tCtx, tCancel := context.WithTimeout(context.Background(), time.Millisecond*100)
 | 
						|
	defer tCancel()
 | 
						|
	p.hs.Shutdown(tCtx)
 | 
						|
}
 | 
						|
 | 
						|
func PProfPort(v int) PProfOpt {
 | 
						|
	return func(p *pprofConf) {
 | 
						|
		p.Port = v
 | 
						|
	}
 | 
						|
}
 |