gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

container.go (2693B)


      1 // Copyright The OpenTelemetry 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 resource // import "go.opentelemetry.io/otel/sdk/resource"
     16 
     17 import (
     18 	"bufio"
     19 	"context"
     20 	"errors"
     21 	"io"
     22 	"os"
     23 	"regexp"
     24 
     25 	semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
     26 )
     27 
     28 type containerIDProvider func() (string, error)
     29 
     30 var (
     31 	containerID         containerIDProvider = getContainerIDFromCGroup
     32 	cgroupContainerIDRe                     = regexp.MustCompile(`^.*/(?:.*-)?([0-9a-f]+)(?:\.|\s*$)`)
     33 )
     34 
     35 type cgroupContainerIDDetector struct{}
     36 
     37 const cgroupPath = "/proc/self/cgroup"
     38 
     39 // Detect returns a *Resource that describes the id of the container.
     40 // If no container id found, an empty resource will be returned.
     41 func (cgroupContainerIDDetector) Detect(ctx context.Context) (*Resource, error) {
     42 	containerID, err := containerID()
     43 	if err != nil {
     44 		return nil, err
     45 	}
     46 
     47 	if containerID == "" {
     48 		return Empty(), nil
     49 	}
     50 	return NewWithAttributes(semconv.SchemaURL, semconv.ContainerID(containerID)), nil
     51 }
     52 
     53 var (
     54 	defaultOSStat = os.Stat
     55 	osStat        = defaultOSStat
     56 
     57 	defaultOSOpen = func(name string) (io.ReadCloser, error) {
     58 		return os.Open(name)
     59 	}
     60 	osOpen = defaultOSOpen
     61 )
     62 
     63 // getContainerIDFromCGroup returns the id of the container from the cgroup file.
     64 // If no container id found, an empty string will be returned.
     65 func getContainerIDFromCGroup() (string, error) {
     66 	if _, err := osStat(cgroupPath); errors.Is(err, os.ErrNotExist) {
     67 		// File does not exist, skip
     68 		return "", nil
     69 	}
     70 
     71 	file, err := osOpen(cgroupPath)
     72 	if err != nil {
     73 		return "", err
     74 	}
     75 	defer file.Close()
     76 
     77 	return getContainerIDFromReader(file), nil
     78 }
     79 
     80 // getContainerIDFromReader returns the id of the container from reader.
     81 func getContainerIDFromReader(reader io.Reader) string {
     82 	scanner := bufio.NewScanner(reader)
     83 	for scanner.Scan() {
     84 		line := scanner.Text()
     85 
     86 		if id := getContainerIDFromLine(line); id != "" {
     87 			return id
     88 		}
     89 	}
     90 	return ""
     91 }
     92 
     93 // getContainerIDFromLine returns the id of the container from one string line.
     94 func getContainerIDFromLine(line string) string {
     95 	matches := cgroupContainerIDRe.FindStringSubmatch(line)
     96 	if len(matches) <= 1 {
     97 		return ""
     98 	}
     99 	return matches[1]
    100 }