process.go (6081B)
1 // Copyright The OpenTelemetry Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package resource // import "go.opentelemetry.io/otel/sdk/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.17.0" 26 ) 27 28 type pidProvider func() int 29 type executablePathProvider func() (string, error) 30 type commandArgsProvider func() []string 31 type ownerProvider func() (*user.User, error) 32 type runtimeNameProvider func() string 33 type runtimeVersionProvider func() string 34 type runtimeOSProvider func() string 35 type runtimeArchProvider func() string 36 37 var ( 38 defaultPidProvider pidProvider = os.Getpid 39 defaultExecutablePathProvider executablePathProvider = os.Executable 40 defaultCommandArgsProvider commandArgsProvider = func() []string { return os.Args } 41 defaultOwnerProvider ownerProvider = user.Current 42 defaultRuntimeNameProvider runtimeNameProvider = func() string { 43 if runtime.Compiler == "gc" { 44 return "go" 45 } 46 return runtime.Compiler 47 } 48 defaultRuntimeVersionProvider runtimeVersionProvider = runtime.Version 49 defaultRuntimeOSProvider runtimeOSProvider = func() string { return runtime.GOOS } 50 defaultRuntimeArchProvider runtimeArchProvider = func() string { return runtime.GOARCH } 51 ) 52 53 var ( 54 pid = defaultPidProvider 55 executablePath = defaultExecutablePathProvider 56 commandArgs = defaultCommandArgsProvider 57 owner = defaultOwnerProvider 58 runtimeName = defaultRuntimeNameProvider 59 runtimeVersion = defaultRuntimeVersionProvider 60 runtimeOS = defaultRuntimeOSProvider 61 runtimeArch = defaultRuntimeArchProvider 62 ) 63 64 func setDefaultOSProviders() { 65 setOSProviders( 66 defaultPidProvider, 67 defaultExecutablePathProvider, 68 defaultCommandArgsProvider, 69 ) 70 } 71 72 func setOSProviders( 73 pidProvider pidProvider, 74 executablePathProvider executablePathProvider, 75 commandArgsProvider commandArgsProvider, 76 ) { 77 pid = pidProvider 78 executablePath = executablePathProvider 79 commandArgs = commandArgsProvider 80 } 81 82 func setDefaultRuntimeProviders() { 83 setRuntimeProviders( 84 defaultRuntimeNameProvider, 85 defaultRuntimeVersionProvider, 86 defaultRuntimeOSProvider, 87 defaultRuntimeArchProvider, 88 ) 89 } 90 91 func setRuntimeProviders( 92 runtimeNameProvider runtimeNameProvider, 93 runtimeVersionProvider runtimeVersionProvider, 94 runtimeOSProvider runtimeOSProvider, 95 runtimeArchProvider runtimeArchProvider, 96 ) { 97 runtimeName = runtimeNameProvider 98 runtimeVersion = runtimeVersionProvider 99 runtimeOS = runtimeOSProvider 100 runtimeArch = runtimeArchProvider 101 } 102 103 func setDefaultUserProviders() { 104 setUserProviders(defaultOwnerProvider) 105 } 106 107 func setUserProviders(ownerProvider ownerProvider) { 108 owner = ownerProvider 109 } 110 111 type processPIDDetector struct{} 112 type processExecutableNameDetector struct{} 113 type processExecutablePathDetector struct{} 114 type processCommandArgsDetector struct{} 115 type processOwnerDetector struct{} 116 type processRuntimeNameDetector struct{} 117 type processRuntimeVersionDetector struct{} 118 type processRuntimeDescriptionDetector struct{} 119 120 // Detect returns a *Resource that describes the process identifier (PID) of the 121 // executing process. 122 func (processPIDDetector) Detect(ctx context.Context) (*Resource, error) { 123 return NewWithAttributes(semconv.SchemaURL, semconv.ProcessPID(pid())), nil 124 } 125 126 // Detect returns a *Resource that describes the name of the process executable. 127 func (processExecutableNameDetector) Detect(ctx context.Context) (*Resource, error) { 128 executableName := filepath.Base(commandArgs()[0]) 129 130 return NewWithAttributes(semconv.SchemaURL, semconv.ProcessExecutableName(executableName)), nil 131 } 132 133 // Detect returns a *Resource that describes the full path of the process executable. 134 func (processExecutablePathDetector) Detect(ctx context.Context) (*Resource, error) { 135 executablePath, err := executablePath() 136 if err != nil { 137 return nil, err 138 } 139 140 return NewWithAttributes(semconv.SchemaURL, semconv.ProcessExecutablePath(executablePath)), nil 141 } 142 143 // Detect returns a *Resource that describes all the command arguments as received 144 // by the process. 145 func (processCommandArgsDetector) Detect(ctx context.Context) (*Resource, error) { 146 return NewWithAttributes(semconv.SchemaURL, semconv.ProcessCommandArgs(commandArgs()...)), nil 147 } 148 149 // Detect returns a *Resource that describes the username of the user that owns the 150 // process. 151 func (processOwnerDetector) Detect(ctx context.Context) (*Resource, error) { 152 owner, err := owner() 153 if err != nil { 154 return nil, err 155 } 156 157 return NewWithAttributes(semconv.SchemaURL, semconv.ProcessOwner(owner.Username)), nil 158 } 159 160 // Detect returns a *Resource that describes the name of the compiler used to compile 161 // this process image. 162 func (processRuntimeNameDetector) Detect(ctx context.Context) (*Resource, error) { 163 return NewWithAttributes(semconv.SchemaURL, semconv.ProcessRuntimeName(runtimeName())), nil 164 } 165 166 // Detect returns a *Resource that describes the version of the runtime of this process. 167 func (processRuntimeVersionDetector) Detect(ctx context.Context) (*Resource, error) { 168 return NewWithAttributes(semconv.SchemaURL, semconv.ProcessRuntimeVersion(runtimeVersion())), nil 169 } 170 171 // Detect returns a *Resource that describes the runtime of this process. 172 func (processRuntimeDescriptionDetector) Detect(ctx context.Context) (*Resource, error) { 173 runtimeDescription := fmt.Sprintf( 174 "go version %s %s/%s", runtimeVersion(), runtimeOS(), runtimeArch()) 175 176 return NewWithAttributes( 177 semconv.SchemaURL, 178 semconv.ProcessRuntimeDescription(runtimeDescription), 179 ), nil 180 }