blob: 6712ce80d5c48350db59037f9767c12da07e3e2b [file] [log] [blame]
Abhay Kumara2ae5992025-11-10 14:02:24 +00001// Copyright The OpenTelemetry Authors
2// SPDX-License-Identifier: Apache-2.0
3
4package resource // import "go.opentelemetry.io/otel/sdk/resource"
5
6import (
7 "context"
8 "fmt"
9 "os"
10 "os/user"
11 "path/filepath"
12 "runtime"
13
14 semconv "go.opentelemetry.io/otel/semconv/v1.34.0"
15)
16
17type (
18 pidProvider func() int
19 executablePathProvider func() (string, error)
20 commandArgsProvider func() []string
21 ownerProvider func() (*user.User, error)
22 runtimeNameProvider func() string
23 runtimeVersionProvider func() string
24 runtimeOSProvider func() string
25 runtimeArchProvider func() string
26)
27
28var (
29 defaultPidProvider pidProvider = os.Getpid
30 defaultExecutablePathProvider executablePathProvider = os.Executable
31 defaultCommandArgsProvider commandArgsProvider = func() []string { return os.Args }
32 defaultOwnerProvider ownerProvider = user.Current
33 defaultRuntimeNameProvider runtimeNameProvider = func() string {
34 if runtime.Compiler == "gc" {
35 return "go"
36 }
37 return runtime.Compiler
38 }
39 defaultRuntimeVersionProvider runtimeVersionProvider = runtime.Version
40 defaultRuntimeOSProvider runtimeOSProvider = func() string { return runtime.GOOS }
41 defaultRuntimeArchProvider runtimeArchProvider = func() string { return runtime.GOARCH }
42)
43
44var (
45 pid = defaultPidProvider
46 executablePath = defaultExecutablePathProvider
47 commandArgs = defaultCommandArgsProvider
48 owner = defaultOwnerProvider
49 runtimeName = defaultRuntimeNameProvider
50 runtimeVersion = defaultRuntimeVersionProvider
51 runtimeOS = defaultRuntimeOSProvider
52 runtimeArch = defaultRuntimeArchProvider
53)
54
55func setDefaultOSProviders() {
56 setOSProviders(
57 defaultPidProvider,
58 defaultExecutablePathProvider,
59 defaultCommandArgsProvider,
60 )
61}
62
63func setOSProviders(
64 pidProvider pidProvider,
65 executablePathProvider executablePathProvider,
66 commandArgsProvider commandArgsProvider,
67) {
68 pid = pidProvider
69 executablePath = executablePathProvider
70 commandArgs = commandArgsProvider
71}
72
73func setDefaultRuntimeProviders() {
74 setRuntimeProviders(
75 defaultRuntimeNameProvider,
76 defaultRuntimeVersionProvider,
77 defaultRuntimeOSProvider,
78 defaultRuntimeArchProvider,
79 )
80}
81
82func setRuntimeProviders(
83 runtimeNameProvider runtimeNameProvider,
84 runtimeVersionProvider runtimeVersionProvider,
85 runtimeOSProvider runtimeOSProvider,
86 runtimeArchProvider runtimeArchProvider,
87) {
88 runtimeName = runtimeNameProvider
89 runtimeVersion = runtimeVersionProvider
90 runtimeOS = runtimeOSProvider
91 runtimeArch = runtimeArchProvider
92}
93
94func setDefaultUserProviders() {
95 setUserProviders(defaultOwnerProvider)
96}
97
98func setUserProviders(ownerProvider ownerProvider) {
99 owner = ownerProvider
100}
101
102type (
103 processPIDDetector struct{}
104 processExecutableNameDetector struct{}
105 processExecutablePathDetector struct{}
106 processCommandArgsDetector struct{}
107 processOwnerDetector struct{}
108 processRuntimeNameDetector struct{}
109 processRuntimeVersionDetector struct{}
110 processRuntimeDescriptionDetector struct{}
111)
112
113// Detect returns a *Resource that describes the process identifier (PID) of the
114// executing process.
115func (processPIDDetector) Detect(ctx context.Context) (*Resource, error) {
116 return NewWithAttributes(semconv.SchemaURL, semconv.ProcessPID(pid())), nil
117}
118
119// Detect returns a *Resource that describes the name of the process executable.
120func (processExecutableNameDetector) Detect(ctx context.Context) (*Resource, error) {
121 executableName := filepath.Base(commandArgs()[0])
122
123 return NewWithAttributes(semconv.SchemaURL, semconv.ProcessExecutableName(executableName)), nil
124}
125
126// Detect returns a *Resource that describes the full path of the process executable.
127func (processExecutablePathDetector) Detect(ctx context.Context) (*Resource, error) {
128 executablePath, err := executablePath()
129 if err != nil {
130 return nil, err
131 }
132
133 return NewWithAttributes(semconv.SchemaURL, semconv.ProcessExecutablePath(executablePath)), nil
134}
135
136// Detect returns a *Resource that describes all the command arguments as received
137// by the process.
138func (processCommandArgsDetector) Detect(ctx context.Context) (*Resource, error) {
139 return NewWithAttributes(semconv.SchemaURL, semconv.ProcessCommandArgs(commandArgs()...)), nil
140}
141
142// Detect returns a *Resource that describes the username of the user that owns the
143// process.
144func (processOwnerDetector) Detect(ctx context.Context) (*Resource, error) {
145 owner, err := owner()
146 if err != nil {
147 return nil, err
148 }
149
150 return NewWithAttributes(semconv.SchemaURL, semconv.ProcessOwner(owner.Username)), nil
151}
152
153// Detect returns a *Resource that describes the name of the compiler used to compile
154// this process image.
155func (processRuntimeNameDetector) Detect(ctx context.Context) (*Resource, error) {
156 return NewWithAttributes(semconv.SchemaURL, semconv.ProcessRuntimeName(runtimeName())), nil
157}
158
159// Detect returns a *Resource that describes the version of the runtime of this process.
160func (processRuntimeVersionDetector) Detect(ctx context.Context) (*Resource, error) {
161 return NewWithAttributes(semconv.SchemaURL, semconv.ProcessRuntimeVersion(runtimeVersion())), nil
162}
163
164// Detect returns a *Resource that describes the runtime of this process.
165func (processRuntimeDescriptionDetector) Detect(ctx context.Context) (*Resource, error) {
166 runtimeDescription := fmt.Sprintf(
167 "go version %s %s/%s", runtimeVersion(), runtimeOS(), runtimeArch())
168
169 return NewWithAttributes(
170 semconv.SchemaURL,
171 semconv.ProcessRuntimeDescription(runtimeDescription),
172 ), nil
173}