mirror of
https://github.com/weaveworks/scope.git
synced 2026-07-28 17:51:21 +00:00
Make it stop
This commit is contained in:
@@ -24,6 +24,13 @@ type tracer struct {
|
||||
docker docker.Registry
|
||||
}
|
||||
|
||||
func (t *tracer) Stop() {
|
||||
log.Printf("Shutting down...")
|
||||
t.ptrace.Stop()
|
||||
t.docker.Stop()
|
||||
log.Printf("Done.")
|
||||
}
|
||||
|
||||
func main() {
|
||||
dockerRegistry, err := docker.NewRegistry(pollInterval)
|
||||
if err != nil {
|
||||
@@ -35,20 +42,28 @@ func main() {
|
||||
store: newStore(),
|
||||
docker: dockerRegistry,
|
||||
}
|
||||
defer tracer.Stop()
|
||||
|
||||
go tracer.http(6060)
|
||||
handleSignals()
|
||||
<-handleSignals()
|
||||
}
|
||||
|
||||
func handleSignals() {
|
||||
sigs := make(chan os.Signal, 1)
|
||||
signal.Notify(sigs, syscall.SIGQUIT)
|
||||
buf := make([]byte, 1<<20)
|
||||
for {
|
||||
sig := <-sigs
|
||||
switch sig {
|
||||
case syscall.SIGQUIT:
|
||||
stacklen := runtime.Stack(buf, true)
|
||||
log.Printf("=== received SIGQUIT ===\n*** goroutine dump...\n%s\n*** end\n", buf[:stacklen])
|
||||
func handleSignals() chan struct{} {
|
||||
quit := make(chan struct{}, 10)
|
||||
go func() {
|
||||
sigs := make(chan os.Signal, 1)
|
||||
signal.Notify(sigs, syscall.SIGQUIT, syscall.SIGINT, syscall.SIGTERM)
|
||||
buf := make([]byte, 1<<20)
|
||||
for {
|
||||
sig := <-sigs
|
||||
switch sig {
|
||||
case syscall.SIGINT, syscall.SIGTERM:
|
||||
quit <- struct{}{}
|
||||
case syscall.SIGQUIT:
|
||||
stacklen := runtime.Stack(buf, true)
|
||||
log.Printf("=== received SIGQUIT ===\n*** goroutine dump...\n%s\n*** end\n", buf[:stacklen])
|
||||
}
|
||||
}
|
||||
}
|
||||
} ()
|
||||
return quit
|
||||
}
|
||||
|
||||
@@ -52,6 +52,21 @@ func NewPTracer() PTracer {
|
||||
return t
|
||||
}
|
||||
|
||||
func (t *PTracer) Stop() {
|
||||
out := make(chan []int)
|
||||
t.ops <- func() {
|
||||
pids := []int{}
|
||||
for pid := range t.processes {
|
||||
pids = append(pids, pid)
|
||||
}
|
||||
out <- pids
|
||||
}
|
||||
for _, pid := range <-out {
|
||||
t.StopTracing(pid)
|
||||
}
|
||||
t.quit <- struct{}{}
|
||||
}
|
||||
|
||||
// TraceProcess starts tracing the given pid
|
||||
func (t *PTracer) TraceProcess(pid int) *process {
|
||||
result := make(chan *process)
|
||||
@@ -149,7 +164,10 @@ func (t *PTracer) traceThread(pid int, process *process) *thread {
|
||||
|
||||
t.threads[pid] = thread
|
||||
result <- thread
|
||||
t.childAttached <- struct{}{}
|
||||
select {
|
||||
case t.childAttached <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
}
|
||||
return <-result
|
||||
}
|
||||
@@ -162,19 +180,20 @@ func (t *PTracer) waitLoop() {
|
||||
)
|
||||
|
||||
for {
|
||||
log.Printf("Waiting...")
|
||||
pid, err = syscall.Wait4(-1, &status, syscall.WALL, nil)
|
||||
if err != nil && err.(syscall.Errno) == syscall.ECHILD {
|
||||
log.Printf("No children to wait4")
|
||||
log.Printf( "No children to wait4")
|
||||
<-t.childAttached
|
||||
continue
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Wait failed: %v %d", err, err.(syscall.Errno))
|
||||
log.Printf(" Wait failed: %v %d", err, err.(syscall.Errno))
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("PID %d stopped", pid)
|
||||
log.Printf(" PID %d stopped with signal %#x", pid, status)
|
||||
t.stopped <- stopped{pid, status}
|
||||
}
|
||||
}
|
||||
@@ -235,6 +254,7 @@ func (t *PTracer) handleStopped(pid int, status syscall.WaitStatus) {
|
||||
}
|
||||
|
||||
// Restart stopped caller in syscall trap mode.
|
||||
log.Printf("Restarting pid %d with signal %d", pid, int(signal))
|
||||
err = syscall.PtraceSyscall(pid, int(signal))
|
||||
if err != nil {
|
||||
log.Printf("PtraceSyscall failed, pid=%d, err=%v", pid, err)
|
||||
|
||||
@@ -16,11 +16,8 @@ shift 1
|
||||
case "$COMMAND" in
|
||||
|
||||
launch)
|
||||
docker run --privileged --net=host --pid=host -d -v /var/run/docker.sock:/var/run/docker.sock \
|
||||
docker run --privileged --net=host --pid=host -ti -v /var/run/docker.sock:/var/run/docker.sock \
|
||||
--name $CONTAINER_NAME weaveworks/tracer
|
||||
for ip in $(hostname -I); do
|
||||
echo http://$ip:6060
|
||||
done
|
||||
;;
|
||||
|
||||
stop)
|
||||
|
||||
@@ -21,14 +21,29 @@
|
||||
var containers = {};
|
||||
var traces = {}
|
||||
|
||||
$.get("/containers").done(function (data) {
|
||||
$.each(data, function(i, container) {
|
||||
containers[container.Id] = container
|
||||
$("ol.containers").append(sprintf("<li id='%s'>%s</li>", container.Id, container.Name))
|
||||
});
|
||||
});
|
||||
function updateContainers() {
|
||||
$.get("/containers").done(function (data) {
|
||||
$("ul.containers").html("")
|
||||
data.sort(function (a, b) {
|
||||
if (a.Name > b.Name) {
|
||||
return 1;
|
||||
}
|
||||
if (a.Name < b.Name) {
|
||||
return -1;
|
||||
}
|
||||
// a must be equal to b
|
||||
return 0;
|
||||
});
|
||||
$.each(data, function(i, container) {
|
||||
containers[container.Id] = container
|
||||
$("ul.containers").append(sprintf("<li id='%s'>%s</li>", container.Id, container.Name.substring(1)))
|
||||
});
|
||||
window.setTimeout(updateContainers, 5 * 1000)
|
||||
});
|
||||
}
|
||||
updateContainers()
|
||||
|
||||
$("ol.containers").on("click", "li", function() {
|
||||
$("ul.containers").on("click", "li", function() {
|
||||
var container = containers[$(this).attr("id")]
|
||||
var containerTraces = traces[$(this).attr("id")] || []
|
||||
|
||||
@@ -56,7 +71,7 @@
|
||||
</script>
|
||||
|
||||
<style>
|
||||
ol.containers li {
|
||||
ul.containers li {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
@@ -86,8 +101,8 @@
|
||||
<div class="container-fluid">
|
||||
<div class="col-md-4">
|
||||
<h1>Weave Tracer</h1>
|
||||
<ol class="containers">
|
||||
</ol>
|
||||
<ul class="containers">
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="col-md-8 mainview">
|
||||
|
||||
Reference in New Issue
Block a user