Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
- `transformprocessor`: Add new `limit` function to allow limiting the number of items in a map, such as the number of attributes in `attributes` or `resource.attributes` (#9552)
- `processor/attributes`: Support attributes set by server authenticator (#9420)
- `datadogexporter`: Experimental support for Exponential Histograms with delta aggregation temporality (#8350)
- `resourcedetectionprocessor`: Add "cname" and "lookup" hostname sources

### 🧰 Bug fixes 🧰

Expand Down
26 changes: 25 additions & 1 deletion processor/resourcedetectionprocessor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ processors:

### System metadata

Note: use the Docker detector (see below) if running the Collector as a Docker container.

Queries the host machine to retrieve the following resource attributes:

* host.name
Expand All @@ -47,8 +49,30 @@ processors:
* all valid options for `hostname_sources`:
* "dns"
* "os"
* "cname"
* "lookup"

Note: use the Docker detector (see below) if running the Collector as a Docker container.
#### Hostname Sources

##### dns

The "dns" hostname source uses multiple sources to get the fully qualified domain name. First, it looks up the
host name in the local machine's `hosts` file. If that fails, it looks up the CNAME. Lastly, if that fails,
it does a reverse DNS query. Note: this hostname source may produce unreliable results on Windows. To produce
a FQDN, Windows hosts might have better results using the "lookup" hostname source, which is mentioned below.

##### os

The "os" hostname source provides the hostname provided by the local machine's kernel.

##### cname

The "cname" hostname source provides the canonical name, as provided by net.LookupCNAME in the Go standard library.
Note: this hostname source may produce unreliable results on Windows.

##### lookup

The "lookup" hostname source does a reverse DNS lookup of the current host's IP address.

### Docker metadata

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
package system // import "github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/system"

import (
"fmt"
"net"
"os"
"runtime"

Expand All @@ -32,6 +34,10 @@ type systemMetadata interface {

// OSType returns the host operating system
OSType() (string, error)

LookupCNAME() (string, error)

ReverseLookupHost() (string, error)
}

type systemMetadataImpl struct{}
Expand All @@ -47,3 +53,53 @@ func (*systemMetadataImpl) FQDN() (string, error) {
func (*systemMetadataImpl) Hostname() (string, error) {
return os.Hostname()
}

func (m *systemMetadataImpl) LookupCNAME() (string, error) {
hostname, err := m.Hostname()
if err != nil {
return "", fmt.Errorf("LookupCNAME failed to get hostname: %w", err)
}
cname, err := net.LookupCNAME(hostname)
if err != nil {
return "", fmt.Errorf("LookupCNAME failed to get CNAME: %w", err)
}
return stripTrailingDot(cname), nil
}

func (m *systemMetadataImpl) ReverseLookupHost() (string, error) {
hostname, err := m.Hostname()
if err != nil {
return "", fmt.Errorf("ReverseLookupHost failed to get hostname: %w", err)
}
return hostnameToDomainName(hostname)
}

func hostnameToDomainName(hostname string) (string, error) {
ipAddresses, err := net.LookupHost(hostname)
if err != nil {
return "", fmt.Errorf("hostnameToDomainName failed to convert hostname to IP addresses: %w", err)
}
return reverseLookup(ipAddresses)
}

func reverseLookup(ipAddresses []string) (string, error) {
var err error
for _, ip := range ipAddresses {
var names []string
names, err = net.LookupAddr(ip)
if err != nil {
continue
}
return stripTrailingDot(names[0]), nil
}
return "", fmt.Errorf("reverseLookup failed to convert IP address to name: %w", err)
}

func stripTrailingDot(name string) string {
nameLen := len(name)
lastIdx := nameLen - 1
if nameLen > 0 && name[lastIdx] == '.' {
name = name[:lastIdx]
}
return name
}
27 changes: 23 additions & 4 deletions processor/resourcedetectionprocessor/internal/system/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ const (
)

var hostnameSourcesMap = map[string]func(*Detector) (string, error){
"dns": getFQDN,
"os": getHostname,
"os": getHostname,
"dns": getFQDN,
"cname": lookupCNAME,
"lookup": reverseLookupHost,
}

var _ internal.Detector = (*Detector)(nil)
Expand All @@ -52,6 +54,7 @@ func NewDetector(p component.ProcessorCreateSettings, dcfg internal.DetectorConf
if len(cfg.HostnameSources) == 0 {
cfg.HostnameSources = []string{"dns", "os"}
}

return &Detector{provider: &systemMetadataImpl{}, logger: p.Logger, hostnameSources: cfg.HostnameSources}, nil
}

Expand All @@ -78,7 +81,7 @@ func (d *Detector) Detect(_ context.Context) (resource pcommon.Resource, schemaU
d.logger.Debug(err.Error())
}

return res, "", errors.New("all hostname sources are failed to get hostname")
return res, "", errors.New("all hostname sources failed to get hostname")
}

// getHostname returns OS hostname
Expand All @@ -94,7 +97,23 @@ func getHostname(d *Detector) (string, error) {
func getFQDN(d *Detector) (string, error) {
hostname, err := d.provider.FQDN()
if err != nil {
return "", fmt.Errorf("failed getting FQDN: %w", err)
return "", fmt.Errorf("getFQDN failed getting FQDN: %w", err)
}
return hostname, nil
}

func lookupCNAME(d *Detector) (string, error) {
cname, err := d.provider.LookupCNAME()
if err != nil {
return "", fmt.Errorf("lookupCNAME failed to get CNAME: %w", err)
}
return cname, nil
}

func reverseLookupHost(d *Detector) (string, error) {
hostname, err := d.provider.ReverseLookupHost()
if err != nil {
return "", fmt.Errorf("reverseLookupHost failed to lookup host: %w", err)
}
return hostname, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ func (m *mockMetadata) OSType() (string, error) {
return args.String(0), args.Error(1)
}

func (m *mockMetadata) LookupCNAME() (string, error) {
args := m.MethodCalled("LookupCNAME")
return args.String(0), args.Error(1)
}

func (m *mockMetadata) ReverseLookupHost() (string, error) {
args := m.MethodCalled("ReverseLookupHost")
return args.String(0), args.Error(1)
}

func TestNewDetector(t *testing.T) {
tests := []struct {
name string
Expand Down