123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- /*
- Copyright 2016 The Kubernetes Authors.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package metricsutil
- import (
- "fmt"
- "io"
- metrics_api "k8s.io/heapster/metrics/apis/metrics/v1alpha1"
- "k8s.io/kubernetes/pkg/api"
- "k8s.io/kubernetes/pkg/api/resource"
- "k8s.io/kubernetes/pkg/kubectl"
- )
- var (
- MeasuredResources = []api.ResourceName{
- api.ResourceCPU,
- api.ResourceMemory,
- }
- NodeColumns = []string{"NAME", "CPU(cores)", "CPU%", "MEMORY(bytes)", "MEMORY%"}
- PodColumns = []string{"NAME", "CPU(cores)", "MEMORY(bytes)"}
- NamespaceColumn = "NAMESPACE"
- PodColumn = "POD"
- )
- type ResourceMetricsInfo struct {
- Name string
- Metrics api.ResourceList
- Available api.ResourceList
- }
- type TopCmdPrinter struct {
- out io.Writer
- }
- func NewTopCmdPrinter(out io.Writer) *TopCmdPrinter {
- return &TopCmdPrinter{out: out}
- }
- func (printer *TopCmdPrinter) PrintNodeMetrics(metrics []metrics_api.NodeMetrics, availableResources map[string]api.ResourceList) error {
- if len(metrics) == 0 {
- return nil
- }
- w := kubectl.GetNewTabWriter(printer.out)
- defer w.Flush()
- printColumnNames(w, NodeColumns)
- var usage api.ResourceList
- for _, m := range metrics {
- err := api.Scheme.Convert(&m.Usage, &usage, nil)
- if err != nil {
- return err
- }
- printMetricsLine(w, &ResourceMetricsInfo{
- Name: m.Name,
- Metrics: usage,
- Available: availableResources[m.Name],
- })
- }
- return nil
- }
- func (printer *TopCmdPrinter) PrintPodMetrics(metrics []metrics_api.PodMetrics, printContainers bool, withNamespace bool) error {
- if len(metrics) == 0 {
- return nil
- }
- w := kubectl.GetNewTabWriter(printer.out)
- defer w.Flush()
- if withNamespace {
- printValue(w, NamespaceColumn)
- }
- if printContainers {
- printValue(w, PodColumn)
- }
- printColumnNames(w, PodColumns)
- for _, m := range metrics {
- err := printSinglePodMetrics(w, &m, printContainers, withNamespace)
- if err != nil {
- return err
- }
- }
- return nil
- }
- func printColumnNames(out io.Writer, names []string) {
- for _, name := range names {
- printValue(out, name)
- }
- fmt.Fprint(out, "\n")
- }
- func printSinglePodMetrics(out io.Writer, m *metrics_api.PodMetrics, printContainersOnly bool, withNamespace bool) error {
- containers := make(map[string]api.ResourceList)
- podMetrics := make(api.ResourceList)
- for _, res := range MeasuredResources {
- podMetrics[res], _ = resource.ParseQuantity("0")
- }
- var usage api.ResourceList
- for _, c := range m.Containers {
- err := api.Scheme.Convert(&c.Usage, &usage, nil)
- if err != nil {
- return err
- }
- containers[c.Name] = usage
- if !printContainersOnly {
- for _, res := range MeasuredResources {
- quantity := podMetrics[res]
- quantity.Add(usage[res])
- podMetrics[res] = quantity
- }
- }
- }
- if printContainersOnly {
- for contName := range containers {
- if withNamespace {
- printValue(out, m.Namespace)
- }
- printValue(out, m.Name)
- printMetricsLine(out, &ResourceMetricsInfo{
- Name: contName,
- Metrics: containers[contName],
- Available: api.ResourceList{},
- })
- }
- } else {
- if withNamespace {
- printValue(out, m.Namespace)
- }
- printMetricsLine(out, &ResourceMetricsInfo{
- Name: m.Name,
- Metrics: podMetrics,
- Available: api.ResourceList{},
- })
- }
- return nil
- }
- func printMetricsLine(out io.Writer, metrics *ResourceMetricsInfo) {
- printValue(out, metrics.Name)
- printAllResourceUsages(out, metrics)
- fmt.Fprint(out, "\n")
- }
- func printValue(out io.Writer, value interface{}) {
- fmt.Fprintf(out, "%v\t", value)
- }
- func printAllResourceUsages(out io.Writer, metrics *ResourceMetricsInfo) {
- for _, res := range MeasuredResources {
- quantity := metrics.Metrics[res]
- printSingleResourceUsage(out, res, quantity)
- fmt.Fprint(out, "\t")
- if available, found := metrics.Available[res]; found {
- fraction := float64(quantity.MilliValue()) / float64(available.MilliValue()) * 100
- fmt.Fprintf(out, "%d%%\t", int64(fraction))
- }
- }
- }
- func printSingleResourceUsage(out io.Writer, resourceType api.ResourceName, quantity resource.Quantity) {
- switch resourceType {
- case api.ResourceCPU:
- fmt.Fprintf(out, "%vm", quantity.MilliValue())
- case api.ResourceMemory:
- fmt.Fprintf(out, "%vMi", quantity.Value()/(1024*1024))
- default:
- fmt.Fprintf(out, "%v", quantity.Value())
- }
- }
|