Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add host.id to resource auto-detection #3812

Merged
merged 12 commits into from
Mar 21, 2023
Prev Previous commit
Next Next commit
combine platform specific readers and tests
This allows us to run tests for the BSD, Darwin, and Linux readers
on all platforms.
  • Loading branch information
mwear committed Mar 8, 2023
commit 0f16d392b1ad49d0e6614fc179c41edd6481b61a
73 changes: 71 additions & 2 deletions sdk/resource/host_id.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ package resource // import "go.opentelemetry.io/otel/sdk/resource"

import (
"context"
"errors"
"os"
"os/exec"
"strings"

semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
)
Expand All @@ -42,7 +44,6 @@ type hostIDReader interface {

type fileReader func(string) (string, error)

// nolint:unused // commandExecutor is used on darwin and BSD, but excluded on linux where the lint job runs
type commandExecutor func(string, ...string) (string, error)

func readFile(filename string) (string, error) {
Expand All @@ -54,7 +55,7 @@ func readFile(filename string) (string, error) {
return string(b), nil
}

// nolint:unused // execCommand is used on darwin and BSD, but excluded on linux where the lint job runs
// nolint: unused // This is used by the hostReaderBSD, gated by build tags.
func execCommand(name string, arg ...string) (string, error) {
cmd := exec.Command(name, arg...)
b, err := cmd.Output()
Expand All @@ -65,6 +66,74 @@ func execCommand(name string, arg ...string) (string, error) {
return string(b), nil
}

// hostIDReaderBSD implements hostIDReader.
type hostIDReaderBSD struct {
execCommand commandExecutor
readFile fileReader
}

// read attempts to read the machine-id from /etc/hostid. If not found it will
// execute `kenv -q smbios.system.uuid`. If neither location yields an id an
// error will be returned.
func (r *hostIDReaderBSD) read() (string, error) {
if result, err := r.readFile("/etc/hostid"); err == nil {
return strings.TrimSpace(result), nil
}

if result, err := r.execCommand("kenv", "-q", "smbios.system.uuid"); err == nil {
return strings.TrimSpace(result), nil
}

return "", errors.New("host id not found in: /etc/hostid or kenv")
}

// hostIDReaderDarwin implements hostIDReader.
type hostIDReaderDarwin struct {
execCommand commandExecutor
}

// read executes `ioreg -rd1 -c "IOPlatformExpertDevice"` and parses host id
// from the IOPlatformUUID line. If the command fails or the uuid cannot be
// parsed an error will be returned.
func (r *hostIDReaderDarwin) read() (string, error) {
result, err := r.execCommand("ioreg", "-rd1", "-c", "IOPlatformExpertDevice")
if err != nil {
return "", err
}

lines := strings.Split(result, "\n")
for _, line := range lines {
if strings.Contains(line, "IOPlatformUUID") {
parts := strings.Split(line, " = ")
if len(parts) == 2 {
return strings.Trim(parts[1], "\""), nil
}
break
}
}

return "", errors.New("could not parse IOPlatformUUID")
}

type hostIDReaderLinux struct {
readFile fileReader
}

// read attempts to read the machine-id from /etc/machine-id followed by
// /var/lib/dbus/machine-id. If neither location yields an ID an error will
// be returned.
func (r *hostIDReaderLinux) read() (string, error) {
if result, err := r.readFile("/etc/machine-id"); err == nil {
return strings.TrimSpace(result), nil
}

if result, err := r.readFile("/var/lib/dbus/machine-id"); err == nil {
return strings.TrimSpace(result), nil
}

return "", errors.New("host id not found in: /etc/machine-id or /var/lib/dbus/machine-id")
}

type hostIDDetector struct{}

// Detect returns a *Resource containing the platform specific host id.
Expand Down
21 changes: 0 additions & 21 deletions sdk/resource/host_id_bsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,6 @@ import (
"strings"
)

// hostIDReaderBSD implements hostIDReader
type hostIDReaderBSD struct {
execCommand commandExecutor
readFile fileReader
}

// read attempts to read the machine-id from /etc/hostid. If not found it will
// execute `kenv -q smbios.system.uuid`. If neither location yields an id an
// error will be returned.
func (r *hostIDReaderBSD) read() (string, error) {
if result, err := r.readFile("/etc/hostid"); err == nil {
return strings.TrimSpace(result), nil
}

if result, err := r.execCommand("kenv", "-q", "smbios.system.uuid"); err == nil {
return strings.TrimSpace(result), nil
}

return "", errors.New("host id not found in: /etc/hostid or kenv")
}

var platformHostIDReader hostIDReader = &hostIDReaderBSD{
execCommand: execCommand,
readFile: readFile,
Expand Down
69 changes: 0 additions & 69 deletions sdk/resource/host_id_bsd_test.go

This file was deleted.

33 changes: 0 additions & 33 deletions sdk/resource/host_id_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,39 +14,6 @@

package resource // import "go.opentelemetry.io/otel/sdk/resource"

import (
"errors"
"strings"
)

// hostIDReaderDarwin implements hostIDReader
type hostIDReaderDarwin struct {
execCommand commandExecutor
}

// read executes `ioreg -rd1 -c "IOPlatformExpertDevice"` and parses host id
// from the IOPlatformUUID line. If the command fails or the uuid cannot be
// parsed an error will be returned.
func (r *hostIDReaderDarwin) read() (string, error) {
result, err := r.execCommand("ioreg", "-rd1", "-c", "IOPlatformExpertDevice")
if err != nil {
return "", err
}

lines := strings.Split(result, "\n")
for _, line := range lines {
if strings.Contains(line, "IOPlatformUUID") {
parts := strings.Split(line, " = ")
if len(parts) == 2 {
return strings.Trim(parts[1], "\""), nil
}
break
}
}

return "", errors.New("could not parse IOPlatformUUID")
}

var platformHostIDReader hostIDReader = &hostIDReaderDarwin{
execCommand: execCommand,
}
89 changes: 0 additions & 89 deletions sdk/resource/host_id_darwin_test.go

This file was deleted.

37 changes: 37 additions & 0 deletions sdk/resource/host_id_export_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// 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 (
"errors"

"go.opentelemetry.io/otel/sdk/resource"
)

func mockHostIDProvider() {
resource.SetHostIDProvider(
func() (string, error) { return "f2c668b579780554f70f72a063dc0864", nil },
)
}

func mockHostIDProviderWithError() {
resource.SetHostIDProvider(
func() (string, error) { return "", errors.New("not found") },
)
}

func restoreHostIDProvider() {
resource.SetDefaultHostIDProvider()
}
24 changes: 0 additions & 24 deletions sdk/resource/host_id_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,6 @@

package resource // import "go.opentelemetry.io/otel/sdk/resource"

import (
"errors"
"strings"
)

type hostIDReaderLinux struct {
readFile fileReader
}

// read attempts to read the machine-id from /etc/machine-id followed by
// /var/lib/dbus/machine-id. If neither location yields an ID an error will
// be returned.
func (r *hostIDReaderLinux) read() (string, error) {
if result, err := r.readFile("/etc/machine-id"); err == nil {
return strings.TrimSpace(result), nil
}

if result, err := r.readFile("/var/lib/dbus/machine-id"); err == nil {
return strings.TrimSpace(result), nil
}

return "", errors.New("host id not found in: /etc/machine-id or /var/lib/dbus/machine-id")
}

var platformHostIDReader hostIDReader = &hostIDReaderLinux{
readFile: readFile,
}
Loading