From c6410076b0a5ed2831868b1b0bf99571cd38c4ab Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Fri, 18 Sep 2020 13:33:32 +0200 Subject: stats endpoint: write OK header once Signed-off-by: Valentin Rothberg --- pkg/api/handlers/compat/containers_stats.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'pkg') diff --git a/pkg/api/handlers/compat/containers_stats.go b/pkg/api/handlers/compat/containers_stats.go index 3d7d49ad3..d7970741d 100644 --- a/pkg/api/handlers/compat/containers_stats.go +++ b/pkg/api/handlers/compat/containers_stats.go @@ -75,6 +75,17 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) { } } + // 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) + for ok := true; ok; ok = query.Stream { // Container stats stats, err := ctnr.GetContainerStats(stats) @@ -175,7 +186,10 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) { Networks: net, } - utils.WriteJSON(w, http.StatusOK, s) + if err := coder.Encode(s); err != nil { + utils.InternalServerError(w, err) + return + } if flusher, ok := w.(http.Flusher); ok { flusher.Flush() } -- cgit v1.2.3-54-g00ecf From ae0e4dfd75326c05bfe285c154d2e530a6adc657 Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Fri, 18 Sep 2020 13:56:31 +0200 Subject: stats: detect closed client connection Detect closed client connections and stop streaming. Fixes: #7521 Signed-off-by: Valentin Rothberg --- pkg/api/handlers/compat/containers_stats.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'pkg') diff --git a/pkg/api/handlers/compat/containers_stats.go b/pkg/api/handlers/compat/containers_stats.go index d7970741d..d3f9b7c41 100644 --- a/pkg/api/handlers/compat/containers_stats.go +++ b/pkg/api/handlers/compat/containers_stats.go @@ -86,7 +86,12 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) { coder := json.NewEncoder(w) coder.SetEscapeHTML(true) - for ok := true; ok; ok = query.Stream { +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 { @@ -194,6 +199,10 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) { flusher.Flush() } + if !query.Stream { + return + } + preRead = s.Read bits, err := json.Marshal(s.CPUStats) if err != nil { @@ -203,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 } } -- cgit v1.2.3-54-g00ecf From 3fdb83a2eed3bd1aa21d1896f6e981476e64e97c Mon Sep 17 00:00:00 2001 From: Valentin Rothberg Date: Mon, 21 Sep 2020 09:45:19 +0200 Subject: stats: log errors instead of sending 500 As 200 is already out the door, we cannot send 500s anymore. Signed-off-by: Valentin Rothberg --- pkg/api/handlers/compat/containers_stats.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'pkg') diff --git a/pkg/api/handlers/compat/containers_stats.go b/pkg/api/handlers/compat/containers_stats.go index d3f9b7c41..16bd0518a 100644 --- a/pkg/api/handlers/compat/containers_stats.go +++ b/pkg/api/handlers/compat/containers_stats.go @@ -95,28 +95,28 @@ streamLabel: // A label to flatten the scope // 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 } @@ -192,7 +192,7 @@ streamLabel: // A label to flatten the scope } if err := coder.Encode(s); err != nil { - utils.InternalServerError(w, err) + logrus.Errorf("Unable to encode stats: %v", err) return } if flusher, ok := w.(http.Flusher); ok { -- cgit v1.2.3-54-g00ecf