add net/http/pprof profiler
This commit is contained in:
parent
a9be1288d2
commit
e2b2a30668
78
debug/profile/http/http.go
Normal file
78
debug/profile/http/http.go
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
// Package http enables the http profiler
|
||||||
|
package http
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"net/http/pprof"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/micro/go-micro/debug/profile"
|
||||||
|
)
|
||||||
|
|
||||||
|
type httpProfile struct {
|
||||||
|
sync.Mutex
|
||||||
|
running bool
|
||||||
|
server *http.Server
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
DefaultAddress = ":6060"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Start the profiler
|
||||||
|
func (h *httpProfile) Start() error {
|
||||||
|
h.Lock()
|
||||||
|
defer h.Unlock()
|
||||||
|
|
||||||
|
if h.running {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
if err := h.server.ListenAndServe(); err != nil {
|
||||||
|
h.Lock()
|
||||||
|
h.running = false
|
||||||
|
h.Unlock()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
h.running = true
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop the profiler
|
||||||
|
func (h *httpProfile) Stop() error {
|
||||||
|
h.Lock()
|
||||||
|
defer h.Unlock()
|
||||||
|
|
||||||
|
if !h.running {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
h.running = false
|
||||||
|
|
||||||
|
return h.server.Shutdown(context.TODO())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *httpProfile) String() string {
|
||||||
|
return "http"
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProfile(opts ...profile.Option) profile.Profile {
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
|
||||||
|
mux.HandleFunc("/debug/pprof/", pprof.Index)
|
||||||
|
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
|
||||||
|
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
|
||||||
|
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
|
||||||
|
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
|
||||||
|
|
||||||
|
return &httpProfile{
|
||||||
|
server: &http.Server{
|
||||||
|
Addr: DefaultAddress,
|
||||||
|
Handler: mux,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -107,6 +107,10 @@ func (p *profiler) Stop() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *profiler) String() string {
|
||||||
|
return "pprof"
|
||||||
|
}
|
||||||
|
|
||||||
func NewProfile(opts ...profile.Option) profile.Profile {
|
func NewProfile(opts ...profile.Option) profile.Profile {
|
||||||
var options profile.Options
|
var options profile.Options
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
|
@ -6,6 +6,8 @@ type Profile interface {
|
|||||||
Start() error
|
Start() error
|
||||||
// Stop the profiler
|
// Stop the profiler
|
||||||
Stop() error
|
Stop() error
|
||||||
|
// Name of the profiler
|
||||||
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
|
27
service.go
27
service.go
@ -3,6 +3,7 @@ package micro
|
|||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
@ -10,6 +11,7 @@ import (
|
|||||||
"github.com/micro/go-micro/client"
|
"github.com/micro/go-micro/client"
|
||||||
"github.com/micro/go-micro/config/cmd"
|
"github.com/micro/go-micro/config/cmd"
|
||||||
"github.com/micro/go-micro/debug/profile"
|
"github.com/micro/go-micro/debug/profile"
|
||||||
|
"github.com/micro/go-micro/debug/profile/http"
|
||||||
"github.com/micro/go-micro/debug/profile/pprof"
|
"github.com/micro/go-micro/debug/profile/pprof"
|
||||||
"github.com/micro/go-micro/debug/service/handler"
|
"github.com/micro/go-micro/debug/service/handler"
|
||||||
"github.com/micro/go-micro/plugin"
|
"github.com/micro/go-micro/plugin"
|
||||||
@ -151,12 +153,25 @@ func (s *service) Run() error {
|
|||||||
// start the profiler
|
// start the profiler
|
||||||
// TODO: set as an option to the service, don't just use pprof
|
// TODO: set as an option to the service, don't just use pprof
|
||||||
if prof := os.Getenv("MICRO_DEBUG_PROFILE"); len(prof) > 0 {
|
if prof := os.Getenv("MICRO_DEBUG_PROFILE"); len(prof) > 0 {
|
||||||
service := s.opts.Server.Options().Name
|
var profiler profile.Profile
|
||||||
version := s.opts.Server.Options().Version
|
|
||||||
id := s.opts.Server.Options().Id
|
// to view mutex contention
|
||||||
profiler := pprof.NewProfile(
|
runtime.SetMutexProfileFraction(5)
|
||||||
profile.Name(service + "." + version + "." + id),
|
// to view blocking profile
|
||||||
)
|
runtime.SetBlockProfileRate(1)
|
||||||
|
|
||||||
|
switch prof {
|
||||||
|
case "http":
|
||||||
|
profiler = http.NewProfile()
|
||||||
|
default:
|
||||||
|
service := s.opts.Server.Options().Name
|
||||||
|
version := s.opts.Server.Options().Version
|
||||||
|
id := s.opts.Server.Options().Id
|
||||||
|
profiler = pprof.NewProfile(
|
||||||
|
profile.Name(service + "." + version + "." + id),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if err := profiler.Start(); err != nil {
|
if err := profiler.Start(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user