From 31cadac623476047f0dc1f1aa2c0c09eb1a63dbf Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Wed, 16 Sep 2015 09:01:09 +0000 Subject: [PATCH] Make it stop --- experimental/tracer/main/main.go | 39 ++++++++++++++++++--------- experimental/tracer/ptrace/ptracer.go | 28 ++++++++++++++++--- experimental/tracer/tracer | 5 +--- experimental/tracer/ui/index.html | 35 +++++++++++++++++------- 4 files changed, 77 insertions(+), 30 deletions(-) diff --git a/experimental/tracer/main/main.go b/experimental/tracer/main/main.go index 2d6675245..6e3b07d34 100644 --- a/experimental/tracer/main/main.go +++ b/experimental/tracer/main/main.go @@ -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 } diff --git a/experimental/tracer/ptrace/ptracer.go b/experimental/tracer/ptrace/ptracer.go index 431a0bf61..2530bccb7 100644 --- a/experimental/tracer/ptrace/ptracer.go +++ b/experimental/tracer/ptrace/ptracer.go @@ -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) diff --git a/experimental/tracer/tracer b/experimental/tracer/tracer index 4fba8b179..3a35f0e5a 100755 --- a/experimental/tracer/tracer +++ b/experimental/tracer/tracer @@ -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) diff --git a/experimental/tracer/ui/index.html b/experimental/tracer/ui/index.html index 141fc38da..c8a95dfb1 100644 --- a/experimental/tracer/ui/index.html +++ b/experimental/tracer/ui/index.html @@ -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("
  • %s
  • ", 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("
  • %s
  • ", 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 @@ @@ -86,8 +101,8 @@

    Weave Tracer

    -
      -
    +
      +