You've already forked opentelemetry-go
mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-11-23 22:34:47 +02:00
OS and Process resource detectors (#1788)
* WIP: OS and Process resource detectors * Completed documentation headers * Added empty test files for OS and Process resource functions * Split long line * Added resource.WithOS function test * Added resource.WithProcess* functions tests * Renamed osDetector and WithOS function to better reflect they only add the os.type attribute * Updated changelog * WIP: possible use of wrappers for getting attribute values * Refined implementation of wrapper functions providing os/runtime/user information * Added PR number to new changelog entries Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com> * Fix wrong function name in documentation header Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com> * Fixed wording in WithProcessOwner documentation header Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com> * Updated osTypeDetector * Replaced ToUpper with ToLower to match the current convention. * Used runtimeOS provider to get the OS name. * Adapted WithOSType test to mock runtime providers Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
This commit is contained in:
10
CHANGELOG.md
10
CHANGELOG.md
@@ -38,6 +38,16 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||||||
- The Jaeger exporter now reports dropped attributes for a Span event in the exported log. (#1771)
|
- The Jaeger exporter now reports dropped attributes for a Span event in the exported log. (#1771)
|
||||||
- Adds `k8s.node.name` and `k8s.node.uid` attribute keys to the `semconv` package. (#1789)
|
- Adds `k8s.node.name` and `k8s.node.uid` attribute keys to the `semconv` package. (#1789)
|
||||||
- Adds `otlpgrpc.WithTimeout` option for configuring timeout to the otlp/gRPC exporter. (#1821)
|
- Adds `otlpgrpc.WithTimeout` option for configuring timeout to the otlp/gRPC exporter. (#1821)
|
||||||
|
- Added `WithOSType` resource configuration option to set OS (Operating System) type resource attribute (`os.type`). (#1788)
|
||||||
|
- Added `WithProcess*` resource configuration options to set Process resource attributes. (#1788)
|
||||||
|
- `process.pid`
|
||||||
|
- `process.executable.name`
|
||||||
|
- `process.executable.path`
|
||||||
|
- `process.command_args`
|
||||||
|
- `process.owner`
|
||||||
|
- `process.runtime.name`
|
||||||
|
- `process.runtime.version`
|
||||||
|
- `process.runtime.description`
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|||||||
31
sdk/resource/export_test.go
Normal file
31
sdk/resource/export_test.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
// Copyright The OpenTelemetry Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package resource // import "go.opentelemetry.io/otel/sdk/resource"
|
||||||
|
|
||||||
|
var (
|
||||||
|
SetDefaultOSProviders = setDefaultOSProviders
|
||||||
|
SetOSProviders = setOSProviders
|
||||||
|
SetDefaultRuntimeProviders = setDefaultRuntimeProviders
|
||||||
|
SetRuntimeProviders = setRuntimeProviders
|
||||||
|
SetDefaultUserProviders = setDefaultUserProviders
|
||||||
|
SetUserProviders = setUserProviders
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
CommandArgs = commandArgs
|
||||||
|
RuntimeName = runtimeName
|
||||||
|
RuntimeOS = runtimeOS
|
||||||
|
RuntimeArch = runtimeArch
|
||||||
|
)
|
||||||
39
sdk/resource/os.go
Normal file
39
sdk/resource/os.go
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// Copyright The OpenTelemetry Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package resource // import "go.opentelemetry.io/otel/sdk/resource"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"go.opentelemetry.io/otel/semconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type osTypeDetector struct{}
|
||||||
|
|
||||||
|
// Detect returns a *Resource that describes the operating system type the
|
||||||
|
// service is running on.
|
||||||
|
func (osTypeDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||||
|
osType := runtimeOS()
|
||||||
|
|
||||||
|
return NewWithAttributes(
|
||||||
|
semconv.OSTypeKey.String(strings.ToLower(osType)),
|
||||||
|
), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithOSType adds an attribute with the operating system type to the configured Resource.
|
||||||
|
func WithOSType() Option {
|
||||||
|
return WithDetectors(osTypeDetector{})
|
||||||
|
}
|
||||||
51
sdk/resource/os_test.go
Normal file
51
sdk/resource/os_test.go
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
// Copyright The OpenTelemetry Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package resource_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"go.opentelemetry.io/otel/sdk/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
func mockRuntimeProviders() {
|
||||||
|
resource.SetRuntimeProviders(
|
||||||
|
fakeRuntimeNameProvider,
|
||||||
|
fakeRuntimeVersionProvider,
|
||||||
|
func() string { return "LINUX" },
|
||||||
|
fakeRuntimeArchProvider,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithOSType(t *testing.T) {
|
||||||
|
mockRuntimeProviders()
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
res, err := resource.New(ctx,
|
||||||
|
resource.WithoutBuiltin(),
|
||||||
|
resource.WithOSType(),
|
||||||
|
)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.EqualValues(t, map[string]string{
|
||||||
|
"os.type": "linux",
|
||||||
|
}, toMap(res))
|
||||||
|
|
||||||
|
restoreProcessAttributesProviders()
|
||||||
|
}
|
||||||
237
sdk/resource/process.go
Normal file
237
sdk/resource/process.go
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
// Copyright The OpenTelemetry Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package resource // import "go.opentelemetry.io/otel/sdk/resource"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/user"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"go.opentelemetry.io/otel/semconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type pidProvider func() int
|
||||||
|
type executablePathProvider func() (string, error)
|
||||||
|
type commandArgsProvider func() []string
|
||||||
|
type ownerProvider func() (*user.User, error)
|
||||||
|
type runtimeNameProvider func() string
|
||||||
|
type runtimeVersionProvider func() string
|
||||||
|
type runtimeOSProvider func() string
|
||||||
|
type runtimeArchProvider func() string
|
||||||
|
|
||||||
|
var (
|
||||||
|
defaultPidProvider pidProvider = os.Getpid
|
||||||
|
defaultExecutablePathProvider executablePathProvider = os.Executable
|
||||||
|
defaultCommandArgsProvider commandArgsProvider = func() []string { return os.Args }
|
||||||
|
defaultOwnerProvider ownerProvider = user.Current
|
||||||
|
defaultRuntimeNameProvider runtimeNameProvider = func() string { return runtime.Compiler }
|
||||||
|
defaultRuntimeVersionProvider runtimeVersionProvider = runtime.Version
|
||||||
|
defaultRuntimeOSProvider runtimeOSProvider = func() string { return runtime.GOOS }
|
||||||
|
defaultRuntimeArchProvider runtimeArchProvider = func() string { return runtime.GOARCH }
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
pid = defaultPidProvider
|
||||||
|
executablePath = defaultExecutablePathProvider
|
||||||
|
commandArgs = defaultCommandArgsProvider
|
||||||
|
owner = defaultOwnerProvider
|
||||||
|
runtimeName = defaultRuntimeNameProvider
|
||||||
|
runtimeVersion = defaultRuntimeVersionProvider
|
||||||
|
runtimeOS = defaultRuntimeOSProvider
|
||||||
|
runtimeArch = defaultRuntimeArchProvider
|
||||||
|
)
|
||||||
|
|
||||||
|
func setDefaultOSProviders() {
|
||||||
|
setOSProviders(
|
||||||
|
defaultPidProvider,
|
||||||
|
defaultExecutablePathProvider,
|
||||||
|
defaultCommandArgsProvider,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setOSProviders(
|
||||||
|
pidProvider pidProvider,
|
||||||
|
executablePathProvider executablePathProvider,
|
||||||
|
commandArgsProvider commandArgsProvider,
|
||||||
|
) {
|
||||||
|
pid = pidProvider
|
||||||
|
executablePath = executablePathProvider
|
||||||
|
commandArgs = commandArgsProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
func setDefaultRuntimeProviders() {
|
||||||
|
setRuntimeProviders(
|
||||||
|
defaultRuntimeNameProvider,
|
||||||
|
defaultRuntimeVersionProvider,
|
||||||
|
defaultRuntimeOSProvider,
|
||||||
|
defaultRuntimeArchProvider,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setRuntimeProviders(
|
||||||
|
runtimeNameProvider runtimeNameProvider,
|
||||||
|
runtimeVersionProvider runtimeVersionProvider,
|
||||||
|
runtimeOSProvider runtimeOSProvider,
|
||||||
|
runtimeArchProvider runtimeArchProvider,
|
||||||
|
) {
|
||||||
|
runtimeName = runtimeNameProvider
|
||||||
|
runtimeVersion = runtimeVersionProvider
|
||||||
|
runtimeOS = runtimeOSProvider
|
||||||
|
runtimeArch = runtimeArchProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
func setDefaultUserProviders() {
|
||||||
|
setUserProviders(defaultOwnerProvider)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setUserProviders(ownerProvider ownerProvider) {
|
||||||
|
owner = ownerProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
type processPIDDetector struct{}
|
||||||
|
type processExecutableNameDetector struct{}
|
||||||
|
type processExecutablePathDetector struct{}
|
||||||
|
type processCommandArgsDetector struct{}
|
||||||
|
type processOwnerDetector struct{}
|
||||||
|
type processRuntimeNameDetector struct{}
|
||||||
|
type processRuntimeVersionDetector struct{}
|
||||||
|
type processRuntimeDescriptionDetector struct{}
|
||||||
|
|
||||||
|
// Detect returns a *Resource that describes the process identifier (PID) of the
|
||||||
|
// executing process.
|
||||||
|
func (processPIDDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||||
|
return NewWithAttributes(semconv.ProcessPIDKey.Int(pid())), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect returns a *Resource that describes the name of the process executable.
|
||||||
|
func (processExecutableNameDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||||
|
executableName := filepath.Base(commandArgs()[0])
|
||||||
|
|
||||||
|
return NewWithAttributes(semconv.ProcessExecutableNameKey.String(executableName)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect returns a *Resource that describes the full path of the process executable.
|
||||||
|
func (processExecutablePathDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||||
|
executablePath, err := executablePath()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewWithAttributes(semconv.ProcessExecutablePathKey.String(executablePath)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect returns a *Resource that describes all the command arguments as received
|
||||||
|
// by the process.
|
||||||
|
func (processCommandArgsDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||||
|
return NewWithAttributes(semconv.ProcessCommandArgsKey.Array(commandArgs())), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect returns a *Resource that describes the username of the user that owns the
|
||||||
|
// process.
|
||||||
|
func (processOwnerDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||||
|
owner, err := owner()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewWithAttributes(semconv.ProcessOwnerKey.String(owner.Username)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect returns a *Resource that describes the name of the compiler used to compile
|
||||||
|
// this process image.
|
||||||
|
func (processRuntimeNameDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||||
|
return NewWithAttributes(semconv.ProcessRuntimeNameKey.String(runtimeName())), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect returns a *Resource that describes the version of the runtime of this process.
|
||||||
|
func (processRuntimeVersionDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||||
|
return NewWithAttributes(semconv.ProcessRuntimeVersionKey.String(runtimeVersion())), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect returns a *Resource that describes the runtime of this process.
|
||||||
|
func (processRuntimeDescriptionDetector) Detect(ctx context.Context) (*Resource, error) {
|
||||||
|
runtimeDescription := fmt.Sprintf(
|
||||||
|
"go version %s %s/%s", runtimeVersion(), runtimeOS(), runtimeArch())
|
||||||
|
|
||||||
|
return NewWithAttributes(
|
||||||
|
semconv.ProcessRuntimeDescriptionKey.String(runtimeDescription),
|
||||||
|
), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithProcessPID adds an attribute with the process identifier (PID) to the
|
||||||
|
// configured Resource.
|
||||||
|
func WithProcessPID() Option {
|
||||||
|
return WithDetectors(processPIDDetector{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithProcessExecutableName adds an attribute with the name of the process
|
||||||
|
// executable to the configured Resource.
|
||||||
|
func WithProcessExecutableName() Option {
|
||||||
|
return WithDetectors(processExecutableNameDetector{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithProcessExecutablePath adds an attribute with the full path to the process
|
||||||
|
// executable to the configured Resource.
|
||||||
|
func WithProcessExecutablePath() Option {
|
||||||
|
return WithDetectors(processExecutablePathDetector{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithProcessCommandArgs adds an attribute with all the command arguments (including
|
||||||
|
// the command/executable itself) as received by the process the configured Resource.
|
||||||
|
func WithProcessCommandArgs() Option {
|
||||||
|
return WithDetectors(processCommandArgsDetector{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithProcessOwner adds an attribute with the username of the user that owns the process
|
||||||
|
// to the configured Resource.
|
||||||
|
func WithProcessOwner() Option {
|
||||||
|
return WithDetectors(processOwnerDetector{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithProcessRuntimeName adds an attribute with the name of the runtime of this
|
||||||
|
// process to the configured Resource.
|
||||||
|
func WithProcessRuntimeName() Option {
|
||||||
|
return WithDetectors(processRuntimeNameDetector{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithProcessRuntimeVersion adds an attribute with the version of the runtime of
|
||||||
|
// this process to the configured Resource.
|
||||||
|
func WithProcessRuntimeVersion() Option {
|
||||||
|
return WithDetectors(processRuntimeVersionDetector{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithProcessRuntimeDescription adds an attribute with an additional description
|
||||||
|
// about the runtime of the process to the configured Resource.
|
||||||
|
func WithProcessRuntimeDescription() Option {
|
||||||
|
return WithDetectors(processRuntimeDescriptionDetector{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithProcess adds all the Process attributes to the configured Resource.
|
||||||
|
// See individual WithProcess* functions to configure specific attributes.
|
||||||
|
func WithProcess() Option {
|
||||||
|
return WithDetectors(
|
||||||
|
processPIDDetector{},
|
||||||
|
processExecutableNameDetector{},
|
||||||
|
processExecutablePathDetector{},
|
||||||
|
processCommandArgsDetector{},
|
||||||
|
processOwnerDetector{},
|
||||||
|
processRuntimeNameDetector{},
|
||||||
|
processRuntimeVersionDetector{},
|
||||||
|
processRuntimeDescriptionDetector{},
|
||||||
|
)
|
||||||
|
}
|
||||||
302
sdk/resource/process_test.go
Normal file
302
sdk/resource/process_test.go
Normal file
@@ -0,0 +1,302 @@
|
|||||||
|
// Copyright The OpenTelemetry Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package resource_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/user"
|
||||||
|
"runtime"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"go.opentelemetry.io/otel/sdk/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
fakePID = 123
|
||||||
|
fakeExecutablePath = "/fake/path/mock"
|
||||||
|
fakeCommandArgs = []string{"mock", "-t", "30"}
|
||||||
|
fakeOwner = "gopher"
|
||||||
|
fakeRuntimeName = "gcmock"
|
||||||
|
fakeRuntimeVersion = "go1.2.3"
|
||||||
|
fakeRuntimeOS = "linux"
|
||||||
|
fakeRuntimeArch = "amd64"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
fakeExecutableName = "mock"
|
||||||
|
fakeRuntimeDescription = "go version go1.2.3 linux/amd64"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
fakePidProvider = func() int { return fakePID }
|
||||||
|
fakeExecutablePathProvider = func() (string, error) { return fakeExecutablePath, nil }
|
||||||
|
fakeCommandArgsProvider = func() []string { return fakeCommandArgs }
|
||||||
|
fakeOwnerProvider = func() (*user.User, error) { return &user.User{Username: fakeOwner}, nil }
|
||||||
|
fakeRuntimeNameProvider = func() string { return fakeRuntimeName }
|
||||||
|
fakeRuntimeVersionProvider = func() string { return fakeRuntimeVersion }
|
||||||
|
fakeRuntimeOSProvider = func() string { return fakeRuntimeOS }
|
||||||
|
fakeRuntimeArchProvider = func() string { return fakeRuntimeArch }
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
fakeExecutablePathProviderWithError = func() (string, error) {
|
||||||
|
return "", fmt.Errorf("Unable to get process executable")
|
||||||
|
}
|
||||||
|
fakeOwnerProviderWithError = func() (*user.User, error) {
|
||||||
|
return nil, fmt.Errorf("Unable to get process user")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func mockProcessAttributesProviders() {
|
||||||
|
resource.SetOSProviders(
|
||||||
|
fakePidProvider,
|
||||||
|
fakeExecutablePathProvider,
|
||||||
|
fakeCommandArgsProvider,
|
||||||
|
)
|
||||||
|
resource.SetRuntimeProviders(
|
||||||
|
fakeRuntimeNameProvider,
|
||||||
|
fakeRuntimeVersionProvider,
|
||||||
|
fakeRuntimeOSProvider,
|
||||||
|
fakeRuntimeArchProvider,
|
||||||
|
)
|
||||||
|
resource.SetUserProviders(
|
||||||
|
fakeOwnerProvider,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func mockProcessAttributesProvidersWithErrors() {
|
||||||
|
resource.SetOSProviders(
|
||||||
|
fakePidProvider,
|
||||||
|
fakeExecutablePathProviderWithError,
|
||||||
|
fakeCommandArgsProvider,
|
||||||
|
)
|
||||||
|
resource.SetRuntimeProviders(
|
||||||
|
fakeRuntimeNameProvider,
|
||||||
|
fakeRuntimeVersionProvider,
|
||||||
|
fakeRuntimeOSProvider,
|
||||||
|
fakeRuntimeArchProvider,
|
||||||
|
)
|
||||||
|
resource.SetUserProviders(
|
||||||
|
fakeOwnerProviderWithError,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func restoreProcessAttributesProviders() {
|
||||||
|
resource.SetDefaultOSProviders()
|
||||||
|
resource.SetDefaultRuntimeProviders()
|
||||||
|
resource.SetDefaultUserProviders()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithProcessFuncs(t *testing.T) {
|
||||||
|
mockProcessAttributesProviders()
|
||||||
|
|
||||||
|
t.Run("WithPID", testWithProcessPID)
|
||||||
|
t.Run("WithExecutableName", testWithProcessExecutableName)
|
||||||
|
t.Run("WithExecutablePath", testWithProcessExecutablePath)
|
||||||
|
t.Run("WithCommandArgs", testWithProcessCommandArgs)
|
||||||
|
t.Run("WithOwner", testWithProcessOwner)
|
||||||
|
t.Run("WithRuntimeName", testWithProcessRuntimeName)
|
||||||
|
t.Run("WithRuntimeVersion", testWithProcessRuntimeVersion)
|
||||||
|
t.Run("WithRuntimeDescription", testWithProcessRuntimeDescription)
|
||||||
|
t.Run("WithProcess", testWithProcess)
|
||||||
|
|
||||||
|
restoreProcessAttributesProviders()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithProcessFuncsErrors(t *testing.T) {
|
||||||
|
mockProcessAttributesProvidersWithErrors()
|
||||||
|
|
||||||
|
t.Run("WithPID", testWithProcessExecutablePathError)
|
||||||
|
t.Run("WithExecutableName", testWithProcessOwnerError)
|
||||||
|
|
||||||
|
restoreProcessAttributesProviders()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCommandArgs(t *testing.T) {
|
||||||
|
require.EqualValues(t, os.Args, resource.CommandArgs())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRuntimeName(t *testing.T) {
|
||||||
|
require.EqualValues(t, runtime.Compiler, resource.RuntimeName())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRuntimeOS(t *testing.T) {
|
||||||
|
require.EqualValues(t, runtime.GOOS, resource.RuntimeOS())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRuntimeArch(t *testing.T) {
|
||||||
|
require.EqualValues(t, runtime.GOARCH, resource.RuntimeArch())
|
||||||
|
}
|
||||||
|
|
||||||
|
func testWithProcessPID(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
res, err := resource.New(ctx,
|
||||||
|
resource.WithoutBuiltin(),
|
||||||
|
resource.WithProcessPID(),
|
||||||
|
)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.EqualValues(t, map[string]string{
|
||||||
|
"process.pid": fmt.Sprint(fakePID),
|
||||||
|
}, toMap(res))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testWithProcessExecutableName(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
res, err := resource.New(ctx,
|
||||||
|
resource.WithoutBuiltin(),
|
||||||
|
resource.WithProcessExecutableName(),
|
||||||
|
)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.EqualValues(t, map[string]string{
|
||||||
|
"process.executable.name": fakeExecutableName,
|
||||||
|
}, toMap(res))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testWithProcessExecutablePath(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
res, err := resource.New(ctx,
|
||||||
|
resource.WithoutBuiltin(),
|
||||||
|
resource.WithProcessExecutablePath(),
|
||||||
|
)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.EqualValues(t, map[string]string{
|
||||||
|
"process.executable.path": fakeExecutablePath,
|
||||||
|
}, toMap(res))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testWithProcessCommandArgs(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
res, err := resource.New(ctx,
|
||||||
|
resource.WithoutBuiltin(),
|
||||||
|
resource.WithProcessCommandArgs(),
|
||||||
|
)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.EqualValues(t, map[string]string{
|
||||||
|
"process.command_args": fmt.Sprint(fakeCommandArgs),
|
||||||
|
}, toMap(res))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testWithProcessOwner(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
res, err := resource.New(ctx,
|
||||||
|
resource.WithoutBuiltin(),
|
||||||
|
resource.WithProcessOwner(),
|
||||||
|
)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.EqualValues(t, map[string]string{
|
||||||
|
"process.owner": fakeOwner,
|
||||||
|
}, toMap(res))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testWithProcessRuntimeName(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
res, err := resource.New(ctx,
|
||||||
|
resource.WithoutBuiltin(),
|
||||||
|
resource.WithProcessRuntimeName(),
|
||||||
|
)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.EqualValues(t, map[string]string{
|
||||||
|
"process.runtime.name": fakeRuntimeName,
|
||||||
|
}, toMap(res))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testWithProcessRuntimeVersion(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
res, err := resource.New(ctx,
|
||||||
|
resource.WithoutBuiltin(),
|
||||||
|
resource.WithProcessRuntimeVersion(),
|
||||||
|
)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.EqualValues(t, map[string]string{
|
||||||
|
"process.runtime.version": fakeRuntimeVersion,
|
||||||
|
}, toMap(res))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testWithProcessRuntimeDescription(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
res, err := resource.New(ctx,
|
||||||
|
resource.WithoutBuiltin(),
|
||||||
|
resource.WithProcessRuntimeDescription(),
|
||||||
|
)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.EqualValues(t, map[string]string{
|
||||||
|
"process.runtime.description": fakeRuntimeDescription,
|
||||||
|
}, toMap(res))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testWithProcess(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
res, err := resource.New(ctx,
|
||||||
|
resource.WithoutBuiltin(),
|
||||||
|
resource.WithProcess(),
|
||||||
|
)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.EqualValues(t, map[string]string{
|
||||||
|
"process.pid": fmt.Sprint(fakePID),
|
||||||
|
"process.executable.name": fakeExecutableName,
|
||||||
|
"process.executable.path": fakeExecutablePath,
|
||||||
|
"process.command_args": fmt.Sprint(fakeCommandArgs),
|
||||||
|
"process.owner": fakeOwner,
|
||||||
|
"process.runtime.name": fakeRuntimeName,
|
||||||
|
"process.runtime.version": fakeRuntimeVersion,
|
||||||
|
"process.runtime.description": fakeRuntimeDescription,
|
||||||
|
}, toMap(res))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testWithProcessExecutablePathError(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
res, err := resource.New(ctx,
|
||||||
|
resource.WithoutBuiltin(),
|
||||||
|
resource.WithProcessExecutablePath(),
|
||||||
|
)
|
||||||
|
|
||||||
|
require.Error(t, err)
|
||||||
|
require.EqualValues(t, map[string]string{}, toMap(res))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testWithProcessOwnerError(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
res, err := resource.New(ctx,
|
||||||
|
resource.WithoutBuiltin(),
|
||||||
|
resource.WithProcessOwner(),
|
||||||
|
)
|
||||||
|
|
||||||
|
require.Error(t, err)
|
||||||
|
require.EqualValues(t, map[string]string{}, toMap(res))
|
||||||
|
}
|
||||||
@@ -116,8 +116,24 @@ const (
|
|||||||
// `proc/[pid]/cmdline`. On Windows, can be set to the result of
|
// `proc/[pid]/cmdline`. On Windows, can be set to the result of
|
||||||
// `GetCommandLineW`.
|
// `GetCommandLineW`.
|
||||||
ProcessCommandLineKey = attribute.Key("process.command_line")
|
ProcessCommandLineKey = attribute.Key("process.command_line")
|
||||||
|
// All the command arguments (including the command/executable itself)
|
||||||
|
// as received by the process. On Linux-based systems (and some other
|
||||||
|
// Unixoid systems supporting procfs), can be set according to the list
|
||||||
|
// of null-delimited strings extracted from `proc/[pid]/cmdline`. For
|
||||||
|
// libc-based executables, this would be the full argv vector passed to
|
||||||
|
// `main`.
|
||||||
|
ProcessCommandArgsKey = attribute.Key("process.command_args")
|
||||||
// The username of the user that owns the process.
|
// The username of the user that owns the process.
|
||||||
ProcessOwnerKey = attribute.Key("process.owner")
|
ProcessOwnerKey = attribute.Key("process.owner")
|
||||||
|
// The name of the runtime of this process. For compiled native
|
||||||
|
// binaries, this SHOULD be the name of the compiler.
|
||||||
|
ProcessRuntimeNameKey = attribute.Key("process.runtime.name")
|
||||||
|
// The version of the runtime of this process, as returned by the
|
||||||
|
// runtime without modification.
|
||||||
|
ProcessRuntimeVersionKey = attribute.Key("process.runtime.version")
|
||||||
|
// An additional description about the runtime of the process, for
|
||||||
|
// example a specific vendor customization of the runtime environment.
|
||||||
|
ProcessRuntimeDescriptionKey = attribute.Key("process.runtime.description")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Semantic conventions for Kubernetes resource attribute keys.
|
// Semantic conventions for Kubernetes resource attribute keys.
|
||||||
@@ -183,6 +199,14 @@ const (
|
|||||||
K8SCronJobNameKey = attribute.Key("k8s.cronjob.name")
|
K8SCronJobNameKey = attribute.Key("k8s.cronjob.name")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Semantic conventions for OS resource attribute keys.
|
||||||
|
const (
|
||||||
|
// The operating system type.
|
||||||
|
OSTypeKey = attribute.Key("os.type")
|
||||||
|
// Human readable (not intended to be parsed) OS version information.
|
||||||
|
OSDescriptionKey = attribute.Key("os.description")
|
||||||
|
)
|
||||||
|
|
||||||
// Semantic conventions for host resource attribute keys.
|
// Semantic conventions for host resource attribute keys.
|
||||||
const (
|
const (
|
||||||
// A uniquely identifying name for the host: 'hostname', FQDN, or user specified name
|
// A uniquely identifying name for the host: 'hostname', FQDN, or user specified name
|
||||||
|
|||||||
Reference in New Issue
Block a user