gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/runsc/metricserver/containermetrics/containermetrics.go (about) 1 // Copyright 2023 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package containermetrics returns metrics and labels interesting to export 16 // about a container or sandbox. 17 package containermetrics 18 19 import ( 20 "crypto/sha256" 21 "encoding/binary" 22 "io" 23 "strconv" 24 25 "gvisor.dev/gvisor/pkg/prometheus" 26 "gvisor.dev/gvisor/runsc/container" 27 ) 28 29 // SandboxPrometheusLabels returns a set of Prometheus labels that identifies the sandbox running 30 // the given root container. 31 func SandboxPrometheusLabels(rootContainer *container.Container) (map[string]string, error) { 32 s := rootContainer.Sandbox 33 labels := make(map[string]string, 4) 34 labels[prometheus.SandboxIDLabel] = s.ID 35 36 // Compute iteration ID label in a stable manner. 37 // This uses sha256(ID + ":" + creation time). 38 h := sha256.New() 39 if _, err := io.WriteString(h, s.ID); err != nil { 40 return nil, err 41 } 42 if _, err := io.WriteString(h, ":"); err != nil { 43 return nil, err 44 } 45 if _, err := io.WriteString(h, rootContainer.CreatedAt.UTC().String()); err != nil { 46 return nil, err 47 } 48 labels[prometheus.IterationIDLabel] = strconv.FormatUint(binary.BigEndian.Uint64(h.Sum(nil)[:8]), 36) 49 50 if s.PodName != "" { 51 labels[prometheus.PodNameLabel] = s.PodName 52 } 53 if s.Namespace != "" { 54 labels[prometheus.NamespaceLabel] = s.Namespace 55 } 56 return labels, nil 57 } 58 59 // ComputeSpecMetadata returns the labels for the `spec_metadata` metric. 60 // It merges data from the Specs of multiple containers running within the 61 // same sandbox. 62 // This function must support being called with `allContainers` being nil. 63 // It must return the same set of label keys regardless of how many containers 64 // are in `allContainers`. 65 func ComputeSpecMetadata(allContainers []*container.Container) map[string]string { 66 const ( 67 unknownOCIVersion = "UNKNOWN" 68 inconsistentOCIVersion = "INCONSISTENT" 69 ) 70 71 hasUID0Container := false 72 ociVersion := unknownOCIVersion 73 for _, cont := range allContainers { 74 if cont.RunsAsUID0() { 75 hasUID0Container = true 76 } 77 if ociVersion == unknownOCIVersion { 78 ociVersion = cont.Spec.Version 79 } else if ociVersion != cont.Spec.Version { 80 ociVersion = inconsistentOCIVersion 81 } 82 } 83 return map[string]string{ 84 "hasuid0": strconv.FormatBool(hasUID0Container), 85 "ociversion": ociVersion, 86 } 87 }