forked from pachyderm/pachyderm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.go
67 lines (62 loc) · 1.6 KB
/
server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package server
import (
"fmt"
"runtime/pprof"
etcd "github.com/coreos/etcd/clientv3"
"github.com/pachyderm/pachyderm/src/client/debug"
"github.com/pachyderm/pachyderm/src/client/pkg/grpcutil"
"github.com/pachyderm/pachyderm/src/server/worker"
)
// NewDebugServer creates a new server that serves the debug api over GRPC
func NewDebugServer(name string, etcdClient *etcd.Client, etcdPrefix string, workerGrpcPort uint16) debug.DebugServer {
return &debugServer{
name: name,
etcdClient: etcdClient,
etcdPrefix: etcdPrefix,
workerGrpcPort: workerGrpcPort,
}
}
type debugServer struct {
name string
etcdClient *etcd.Client
etcdPrefix string
workerGrpcPort uint16
}
func (s *debugServer) Dump(request *debug.DumpRequest, server debug.Debug_DumpServer) error {
profile := pprof.Lookup("goroutine")
if profile == nil {
return fmt.Errorf("unable to find goroutine profile")
}
w := grpcutil.NewStreamingBytesWriter(server)
if s.name != "" {
if _, err := fmt.Fprintf(w, "== %s ==\n\n", s.name); err != nil {
return err
}
}
if err := profile.WriteTo(w, 2); err != nil {
return err
}
if !request.Recursed {
request.Recursed = true
cs, err := worker.Clients(server.Context(), "", s.etcdClient, s.etcdPrefix, s.workerGrpcPort)
if err != nil {
return err
}
for _, c := range cs {
if _, err := fmt.Fprintf(w, "\n"); err != nil {
return err
}
dumpC, err := c.Dump(
server.Context(),
request,
)
if err != nil {
return err
}
if err := grpcutil.WriteFromStreamingBytesClient(dumpC, w); err != nil {
return err
}
}
}
return nil
}