123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- // Copyright The OpenTelemetry 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 resource // import "go.opentelemetry.io/otel/sdk/resource"
- import (
- "bufio"
- "context"
- "errors"
- "io"
- "os"
- "regexp"
- semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
- )
- type containerIDProvider func() (string, error)
- var (
- containerID containerIDProvider = getContainerIDFromCGroup
- cgroupContainerIDRe = regexp.MustCompile(`^.*/(?:.*-)?([0-9a-f]+)(?:\.|\s*$)`)
- )
- type cgroupContainerIDDetector struct{}
- const cgroupPath = "/proc/self/cgroup"
- // Detect returns a *Resource that describes the id of the container.
- // If no container id found, an empty resource will be returned.
- func (cgroupContainerIDDetector) Detect(ctx context.Context) (*Resource, error) {
- containerID, err := containerID()
- if err != nil {
- return nil, err
- }
- if containerID == "" {
- return Empty(), nil
- }
- return NewWithAttributes(semconv.SchemaURL, semconv.ContainerID(containerID)), nil
- }
- var (
- defaultOSStat = os.Stat
- osStat = defaultOSStat
- defaultOSOpen = func(name string) (io.ReadCloser, error) {
- return os.Open(name)
- }
- osOpen = defaultOSOpen
- )
- // getContainerIDFromCGroup returns the id of the container from the cgroup file.
- // If no container id found, an empty string will be returned.
- func getContainerIDFromCGroup() (string, error) {
- if _, err := osStat(cgroupPath); errors.Is(err, os.ErrNotExist) {
- // File does not exist, skip
- return "", nil
- }
- file, err := osOpen(cgroupPath)
- if err != nil {
- return "", err
- }
- defer file.Close()
- return getContainerIDFromReader(file), nil
- }
- // getContainerIDFromReader returns the id of the container from reader.
- func getContainerIDFromReader(reader io.Reader) string {
- scanner := bufio.NewScanner(reader)
- for scanner.Scan() {
- line := scanner.Text()
- if id := getContainerIDFromLine(line); id != "" {
- return id
- }
- }
- return ""
- }
- // getContainerIDFromLine returns the id of the container from one string line.
- func getContainerIDFromLine(line string) string {
- matches := cgroupContainerIDRe.FindStringSubmatch(line)
- if len(matches) <= 1 {
- return ""
- }
- return matches[1]
- }
|