diff --git a/src/runtime/cmd/kata-monitor/main.go b/src/runtime/cmd/kata-monitor/main.go index 356316dcf2..86b5693d9b 100644 --- a/src/runtime/cmd/kata-monitor/main.go +++ b/src/runtime/cmd/kata-monitor/main.go @@ -175,6 +175,15 @@ func main() { } func indexPage(w http.ResponseWriter, r *http.Request) { + htmlResponse := kataMonitor.IfReturnHTMLResponse(w, r) + if htmlResponse { + indexPageHTML(w, r) + } else { + indexPageText(w, r) + } +} + +func indexPageText(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Available HTTP endpoints:\n")) spacing := 0 @@ -184,13 +193,35 @@ func indexPage(w http.ResponseWriter, r *http.Request) { } } spacing = spacing + 3 + formatter := fmt.Sprintf("%%-%ds: %%s\n", spacing) - formattedString := fmt.Sprintf("%%-%ds: %%s\n", spacing) for _, endpoint := range endpoints { - w.Write([]byte(fmt.Sprintf(formattedString, endpoint.path, endpoint.desc))) + w.Write([]byte(fmt.Sprintf(formatter, endpoint.path, endpoint.desc))) } } +func indexPageHTML(w http.ResponseWriter, r *http.Request) { + + w.Write([]byte("

Available HTTP endpoints:

\n")) + + var formattedString string + needLinkPaths := []string{"/metrics", "/sandboxes"} + + w.Write([]byte("")) +} + // initLog setup logger func initLog() { kataMonitorLog := logrus.WithFields(logrus.Fields{ diff --git a/src/runtime/pkg/kata-monitor/metrics.go b/src/runtime/pkg/kata-monitor/metrics.go index 7249906cea..e5d9477670 100644 --- a/src/runtime/pkg/kata-monitor/metrics.go +++ b/src/runtime/pkg/kata-monitor/metrics.go @@ -78,6 +78,21 @@ func (km *KataMonitor) ProcessMetricsRequest(w http.ResponseWriter, r *http.Requ scrapeDurationsHistogram.Observe(float64(time.Since(start).Nanoseconds() / int64(time.Millisecond))) }() + // this is likely the same as `kata-runtime metrics `. + sandboxID, err := getSandboxIDFromReq(r) + if err == nil && sandboxID != "" { + metrics, err := GetSandboxMetrics(sandboxID) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(err.Error())) + return + } + w.Write([]byte(metrics)) + return + } + + // if no sandbox provided, will get all sandbox's metrics. + // prepare writer for writing response. contentType := expfmt.Negotiate(r.Header) diff --git a/src/runtime/pkg/kata-monitor/monitor.go b/src/runtime/pkg/kata-monitor/monitor.go index ed3ea5c089..1e60a50b7b 100644 --- a/src/runtime/pkg/kata-monitor/monitor.go +++ b/src/runtime/pkg/kata-monitor/monitor.go @@ -27,6 +27,7 @@ const ( RuntimeCRIO = "cri-o" fsMonitorRetryDelaySeconds = 60 podCacheRefreshDelaySeconds = 5 + contentTypeHtml = "text/html" ) // SetLogger sets the logger for katamonitor package. @@ -194,7 +195,41 @@ func (km *KataMonitor) GetAgentURL(w http.ResponseWriter, r *http.Request) { // ListSandboxes list all sandboxes running in Kata func (km *KataMonitor) ListSandboxes(w http.ResponseWriter, r *http.Request) { sandboxes := km.sandboxCache.getSandboxList() + htmlResponse := IfReturnHTMLResponse(w, r) + if htmlResponse { + listSandboxesHtml(sandboxes, w) + } else { + listSandboxesText(sandboxes, w) + } +} + +func listSandboxesText(sandboxes []string, w http.ResponseWriter) { for _, s := range sandboxes { w.Write([]byte(fmt.Sprintf("%s\n", s))) } } +func listSandboxesHtml(sandboxes []string, w http.ResponseWriter) { + w.Write([]byte("

Sandbox list

\n")) + w.Write([]byte("\n")) +} + +// IfReturnHTMLResponse returns true if request accepts html response +// NOTE: IfReturnHTMLResponse will also set response header to `text/html` +func IfReturnHTMLResponse(w http.ResponseWriter, r *http.Request) bool { + accepts := r.Header["Accept"] + for _, accept := range accepts { + fields := strings.Split(accept, ",") + for _, field := range fields { + if field == contentTypeHtml { + w.Header().Set("Content-Type", contentTypeHtml) + return true + } + } + } + + return false +} diff --git a/src/runtime/pkg/kata-monitor/pprof.go b/src/runtime/pkg/kata-monitor/pprof.go index 5dac2da03c..a2ff76bc30 100644 --- a/src/runtime/pkg/kata-monitor/pprof.go +++ b/src/runtime/pkg/kata-monitor/pprof.go @@ -55,8 +55,10 @@ func (km *KataMonitor) proxyRequest(w http.ResponseWriter, r *http.Request) { } uri := fmt.Sprintf("http://shim%s", r.URL.String()) + monitorLog.Debugf("proxyRequest to: %s, uri: %s", socketAddress, uri) resp, err := client.Get(uri) if err != nil { + serveError(w, http.StatusInternalServerError, fmt.Sprintf("failed to request %s through %s", uri, socketAddress)) return }