summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pkg/api/handlers/compat/containers_stats.go43
1 files changed, 32 insertions, 11 deletions
diff --git a/pkg/api/handlers/compat/containers_stats.go b/pkg/api/handlers/compat/containers_stats.go
index 3d7d49ad3..16bd0518a 100644
--- a/pkg/api/handlers/compat/containers_stats.go
+++ b/pkg/api/handlers/compat/containers_stats.go
@@ -75,32 +75,48 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
}
}
- for ok := true; ok; ok = query.Stream {
+ // Write header and content type.
+ w.WriteHeader(http.StatusOK)
+ w.Header().Add("Content-Type", "application/json")
+ if flusher, ok := w.(http.Flusher); ok {
+ flusher.Flush()
+ }
+
+ // Setup JSON encoder for streaming.
+ coder := json.NewEncoder(w)
+ coder.SetEscapeHTML(true)
+
+streamLabel: // A label to flatten the scope
+ select {
+ case <-r.Context().Done():
+ logrus.Debugf("Client connection (container stats) cancelled")
+
+ default:
// Container stats
stats, err := ctnr.GetContainerStats(stats)
if err != nil {
- utils.InternalServerError(w, err)
+ logrus.Errorf("Unable to get container stats: %v", err)
return
}
inspect, err := ctnr.Inspect(false)
if err != nil {
- utils.InternalServerError(w, err)
+ logrus.Errorf("Unable to inspect container: %v", err)
return
}
// Cgroup stats
cgroupPath, err := ctnr.CGroupPath()
if err != nil {
- utils.InternalServerError(w, err)
+ logrus.Errorf("Unable to get cgroup path of container: %v", err)
return
}
cgroup, err := cgroups.Load(cgroupPath)
if err != nil {
- utils.InternalServerError(w, err)
+ logrus.Errorf("Unable to load cgroup: %v", err)
return
}
cgroupStat, err := cgroup.Stat()
if err != nil {
- utils.InternalServerError(w, err)
+ logrus.Errorf("Unable to get cgroup stats: %v", err)
return
}
@@ -175,11 +191,18 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
Networks: net,
}
- utils.WriteJSON(w, http.StatusOK, s)
+ if err := coder.Encode(s); err != nil {
+ logrus.Errorf("Unable to encode stats: %v", err)
+ return
+ }
if flusher, ok := w.(http.Flusher); ok {
flusher.Flush()
}
+ if !query.Stream {
+ return
+ }
+
preRead = s.Read
bits, err := json.Marshal(s.CPUStats)
if err != nil {
@@ -189,10 +212,8 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
logrus.Errorf("Unable to unmarshal previous stats: %q", err)
}
- // Only sleep when we're streaming.
- if query.Stream {
- time.Sleep(DefaultStatsPeriod)
- }
+ time.Sleep(DefaultStatsPeriod)
+ goto streamLabel
}
}