blob: a6ff26a4d2700e1902990023485d6e0b214608ac [file] [log] [blame]
Abhay Kumara2ae5992025-11-10 14:02:24 +00001// Copyright The OpenTelemetry Authors
2// SPDX-License-Identifier: Apache-2.0
3
4//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
5// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
6
7package resource // import "go.opentelemetry.io/otel/sdk/resource"
8
9import (
10 "fmt"
11 "os"
12
13 "golang.org/x/sys/unix"
14)
15
16type unameProvider func(buf *unix.Utsname) (err error)
17
18var defaultUnameProvider unameProvider = unix.Uname
19
20var currentUnameProvider = defaultUnameProvider
21
22func setDefaultUnameProvider() {
23 setUnameProvider(defaultUnameProvider)
24}
25
26func setUnameProvider(unameProvider unameProvider) {
27 currentUnameProvider = unameProvider
28}
29
30// platformOSDescription returns a human readable OS version information string.
31// The final string combines OS release information (where available) and the
32// result of the `uname` system call.
33func platformOSDescription() (string, error) {
34 uname, err := uname()
35 if err != nil {
36 return "", err
37 }
38
39 osRelease := osRelease()
40 if osRelease != "" {
41 return fmt.Sprintf("%s (%s)", osRelease, uname), nil
42 }
43
44 return uname, nil
45}
46
47// uname issues a uname(2) system call (or equivalent on systems which doesn't
48// have one) and formats the output in a single string, similar to the output
49// of the `uname` commandline program. The final string resembles the one
50// obtained with a call to `uname -snrvm`.
51func uname() (string, error) {
52 var utsName unix.Utsname
53
54 err := currentUnameProvider(&utsName)
55 if err != nil {
56 return "", err
57 }
58
59 return fmt.Sprintf("%s %s %s %s %s",
60 unix.ByteSliceToString(utsName.Sysname[:]),
61 unix.ByteSliceToString(utsName.Nodename[:]),
62 unix.ByteSliceToString(utsName.Release[:]),
63 unix.ByteSliceToString(utsName.Version[:]),
64 unix.ByteSliceToString(utsName.Machine[:]),
65 ), nil
66}
67
68// getFirstAvailableFile returns an *os.File of the first available
69// file from a list of candidate file paths.
70func getFirstAvailableFile(candidates []string) (*os.File, error) {
71 for _, c := range candidates {
72 file, err := os.Open(c)
73 if err == nil {
74 return file, nil
75 }
76 }
77
78 return nil, fmt.Errorf("no candidate file available: %v", candidates)
79}