package resource
import (
"bufio"
"context"
"errors"
"io"
"os"
"regexp"
semconv "go.opentelemetry.io/otel/semconv/v1.37.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"
func (cgroupContainerIDDetector ) Detect (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
)
func getContainerIDFromCGroup() (string , error ) {
if _ , err := osStat (cgroupPath ); errors .Is (err , os .ErrNotExist ) {
return "" , nil
}
file , err := osOpen (cgroupPath )
if err != nil {
return "" , err
}
defer file .Close ()
return getContainerIDFromReader (file ), nil
}
func getContainerIDFromReader(reader io .Reader ) string {
scanner := bufio .NewScanner (reader )
for scanner .Scan () {
line := scanner .Text ()
if id := getContainerIDFromLine (line ); id != "" {
return id
}
}
return ""
}
func getContainerIDFromLine(line string ) string {
matches := cgroupContainerIDRe .FindStringSubmatch (line )
if len (matches ) <= 1 {
return ""
}
return matches [1 ]
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .