...

Source file src/go.opentelemetry.io/otel/sdk/resource/host_id.go

Documentation: go.opentelemetry.io/otel/sdk/resource

     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  	"errors"
    20  	"strings"
    21  
    22  	semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
    23  )
    24  
    25  type hostIDProvider func() (string, error)
    26  
    27  var defaultHostIDProvider hostIDProvider = platformHostIDReader.read
    28  
    29  var hostID = defaultHostIDProvider
    30  
    31  type hostIDReader interface {
    32  	read() (string, error)
    33  }
    34  
    35  type fileReader func(string) (string, error)
    36  
    37  type commandExecutor func(string, ...string) (string, error)
    38  
    39  // hostIDReaderBSD implements hostIDReader.
    40  type hostIDReaderBSD struct {
    41  	execCommand commandExecutor
    42  	readFile    fileReader
    43  }
    44  
    45  // read attempts to read the machine-id from /etc/hostid. If not found it will
    46  // execute `kenv -q smbios.system.uuid`. If neither location yields an id an
    47  // error will be returned.
    48  func (r *hostIDReaderBSD) read() (string, error) {
    49  	if result, err := r.readFile("/etc/hostid"); err == nil {
    50  		return strings.TrimSpace(result), nil
    51  	}
    52  
    53  	if result, err := r.execCommand("kenv", "-q", "smbios.system.uuid"); err == nil {
    54  		return strings.TrimSpace(result), nil
    55  	}
    56  
    57  	return "", errors.New("host id not found in: /etc/hostid or kenv")
    58  }
    59  
    60  // hostIDReaderDarwin implements hostIDReader.
    61  type hostIDReaderDarwin struct {
    62  	execCommand commandExecutor
    63  }
    64  
    65  // read executes `ioreg -rd1 -c "IOPlatformExpertDevice"` and parses host id
    66  // from the IOPlatformUUID line. If the command fails or the uuid cannot be
    67  // parsed an error will be returned.
    68  func (r *hostIDReaderDarwin) read() (string, error) {
    69  	result, err := r.execCommand("ioreg", "-rd1", "-c", "IOPlatformExpertDevice")
    70  	if err != nil {
    71  		return "", err
    72  	}
    73  
    74  	lines := strings.Split(result, "\n")
    75  	for _, line := range lines {
    76  		if strings.Contains(line, "IOPlatformUUID") {
    77  			parts := strings.Split(line, " = ")
    78  			if len(parts) == 2 {
    79  				return strings.Trim(parts[1], "\""), nil
    80  			}
    81  			break
    82  		}
    83  	}
    84  
    85  	return "", errors.New("could not parse IOPlatformUUID")
    86  }
    87  
    88  type hostIDReaderLinux struct {
    89  	readFile fileReader
    90  }
    91  
    92  // read attempts to read the machine-id from /etc/machine-id followed by
    93  // /var/lib/dbus/machine-id. If neither location yields an ID an error will
    94  // be returned.
    95  func (r *hostIDReaderLinux) read() (string, error) {
    96  	if result, err := r.readFile("/etc/machine-id"); err == nil {
    97  		return strings.TrimSpace(result), nil
    98  	}
    99  
   100  	if result, err := r.readFile("/var/lib/dbus/machine-id"); err == nil {
   101  		return strings.TrimSpace(result), nil
   102  	}
   103  
   104  	return "", errors.New("host id not found in: /etc/machine-id or /var/lib/dbus/machine-id")
   105  }
   106  
   107  type hostIDDetector struct{}
   108  
   109  // Detect returns a *Resource containing the platform specific host id.
   110  func (hostIDDetector) Detect(ctx context.Context) (*Resource, error) {
   111  	hostID, err := hostID()
   112  	if err != nil {
   113  		return nil, err
   114  	}
   115  
   116  	return NewWithAttributes(
   117  		semconv.SchemaURL,
   118  		semconv.HostID(hostID),
   119  	), nil
   120  }
   121  

View as plain text