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