github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/pkg/api/handlers/libpod/containers_stats.go (about) 1 package libpod 2 3 import ( 4 "encoding/json" 5 "net/http" 6 "time" 7 8 "github.com/containers/podman/v2/libpod" 9 "github.com/containers/podman/v2/pkg/api/handlers/utils" 10 "github.com/containers/podman/v2/pkg/domain/entities" 11 "github.com/containers/podman/v2/pkg/domain/infra/abi" 12 "github.com/gorilla/schema" 13 "github.com/pkg/errors" 14 "github.com/sirupsen/logrus" 15 ) 16 17 const DefaultStatsPeriod = 5 * time.Second 18 19 func StatsContainer(w http.ResponseWriter, r *http.Request) { 20 runtime := r.Context().Value("runtime").(*libpod.Runtime) 21 decoder := r.Context().Value("decoder").(*schema.Decoder) 22 23 query := struct { 24 Containers []string `schema:"containers"` 25 Stream bool `schema:"stream"` 26 }{ 27 Stream: true, 28 } 29 if err := decoder.Decode(&query, r.URL.Query()); err != nil { 30 utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) 31 return 32 } 33 34 // Reduce code duplication and use the local/abi implementation of 35 // container stats. 36 containerEngine := abi.ContainerEngine{Libpod: runtime} 37 38 statsOptions := entities.ContainerStatsOptions{ 39 Stream: query.Stream, 40 } 41 42 // Stats will stop if the connection is closed. 43 statsChan, err := containerEngine.ContainerStats(r.Context(), query.Containers, statsOptions) 44 if err != nil { 45 utils.InternalServerError(w, err) 46 return 47 } 48 49 // Write header and content type. 50 w.WriteHeader(http.StatusOK) 51 w.Header().Add("Content-Type", "application/json") 52 if flusher, ok := w.(http.Flusher); ok { 53 flusher.Flush() 54 } 55 56 // Setup JSON encoder for streaming. 57 coder := json.NewEncoder(w) 58 coder.SetEscapeHTML(true) 59 60 for stats := range statsChan { 61 if err := coder.Encode(stats); err != nil { 62 // Note: even when streaming, the stats goroutine will 63 // be notified (and stop) as the connection will be 64 // closed. 65 logrus.Errorf("Unable to encode stats: %v", err) 66 return 67 } 68 if flusher, ok := w.(http.Flusher); ok { 69 flusher.Flush() 70 } 71 } 72 }