Skip to content

Commit

Permalink
[system detector] Fallback to os.Hostname when FQDN is not available (
Browse files Browse the repository at this point in the history
#3099)

- Fall back to `os.Hostname` when FQDN is not available.

**Link to tracking Issue:** Fixes #3092
  • Loading branch information
mx-psi authored Apr 14, 2021
1 parent fbef6d4 commit a067bf9
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@
package system

import (
"os"
"runtime"
"strings"

"github.com/Showmax/go-fqdn"
)

type systemMetadata interface {
// Hostname returns the OS hostname
Hostname() (string, error)

// FQDN returns the fully qualified domain name
FQDN() (string, error)

Expand All @@ -47,3 +51,7 @@ func (*systemMetadataImpl) OSType() (string, error) {
func (*systemMetadataImpl) FQDN() (string, error) {
return fqdn.FqdnHostname()
}

func (*systemMetadataImpl) Hostname() (string, error) {
return os.Hostname()
}
17 changes: 12 additions & 5 deletions processor/resourcedetectionprocessor/internal/system/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/consumer/pdata"
"go.opentelemetry.io/collector/translator/conventions"
"go.uber.org/zap"

"github.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal"
)
Expand All @@ -35,11 +36,12 @@ var _ internal.Detector = (*Detector)(nil)
// Detector is a system metadata detector
type Detector struct {
provider systemMetadata
logger *zap.Logger
}

// NewDetector creates a new system metadata detector
func NewDetector(component.ProcessorCreateParams, internal.DetectorConfig) (internal.Detector, error) {
return &Detector{provider: &systemMetadataImpl{}}, nil
func NewDetector(p component.ProcessorCreateParams, _ internal.DetectorConfig) (internal.Detector, error) {
return &Detector{provider: &systemMetadataImpl{}, logger: p.Logger}, nil
}

// Detect detects system metadata and returns a resource with the available ones
Expand All @@ -52,12 +54,17 @@ func (d *Detector) Detect(_ context.Context) (pdata.Resource, error) {
return res, fmt.Errorf("failed getting OS type: %w", err)
}

fqdn, err := d.provider.FQDN()
hostname, err := d.provider.FQDN()
if err != nil {
return res, fmt.Errorf("failed getting FQDN: %w", err)
// Fallback to OS hostname
d.logger.Debug("FQDN query failed, falling back to OS hostname", zap.Error(err))
hostname, err = d.provider.Hostname()
if err != nil {
return res, fmt.Errorf("failed getting OS hostname: %w", err)
}
}

attrs.InsertString(conventions.AttributeHostName, fqdn)
attrs.InsertString(conventions.AttributeHostName, hostname)
attrs.InsertString(conventions.AttributeOSType, osType)

return res, nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ type mockMetadata struct {
mock.Mock
}

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

func (m *mockMetadata) FQDN() (string, error) {
args := m.MethodCalled("FQDN")
return args.String(0), args.Error(1)
Expand All @@ -54,7 +59,7 @@ func TestDetectFQDNAvailable(t *testing.T) {
md.On("FQDN").Return("fqdn", nil)
md.On("OSType").Return("DARWIN", nil)

detector := &Detector{provider: md}
detector := &Detector{provider: md, logger: zap.NewNop()}
res, err := detector.Detect(context.Background())
require.NoError(t, err)
md.AssertExpectations(t)
Expand All @@ -70,23 +75,45 @@ func TestDetectFQDNAvailable(t *testing.T) {

}

func TestFallbackHostname(t *testing.T) {
mdHostname := &mockMetadata{}
mdHostname.On("Hostname").Return("hostname", nil)
mdHostname.On("FQDN").Return("", errors.New("err"))
mdHostname.On("OSType").Return("DARWIN", nil)

detector := &Detector{provider: mdHostname, logger: zap.NewNop()}
res, err := detector.Detect(context.Background())
require.NoError(t, err)
mdHostname.AssertExpectations(t)
res.Attributes().Sort()

expected := internal.NewResource(map[string]interface{}{
conventions.AttributeHostName: "hostname",
conventions.AttributeOSType: "DARWIN",
})
expected.Attributes().Sort()

assert.Equal(t, expected, res)
}

func TestDetectError(t *testing.T) {
// FQDN fails
// FQDN and hostname fail
mdFQDN := &mockMetadata{}
mdFQDN.On("OSType").Return("WINDOWS", nil)
mdFQDN.On("FQDN").Return("", errors.New("err"))
mdFQDN.On("Hostname").Return("", errors.New("err"))

detector := &Detector{provider: mdFQDN}
detector := &Detector{provider: mdFQDN, logger: zap.NewNop()}
res, err := detector.Detect(context.Background())
assert.Error(t, err)
assert.True(t, internal.IsEmptyResource(res))

// Hostname fails
mdHostname := &mockMetadata{}
mdHostname.On("FQDN").Return("fqdn", nil)
mdHostname.On("OSType").Return("", errors.New("err"))
// OS type fails
mdOSType := &mockMetadata{}
mdOSType.On("FQDN").Return("fqdn", nil)
mdOSType.On("OSType").Return("", errors.New("err"))

detector = &Detector{provider: mdHostname}
detector = &Detector{provider: mdOSType, logger: zap.NewNop()}
res, err = detector.Detect(context.Background())
assert.Error(t, err)
assert.True(t, internal.IsEmptyResource(res))
Expand Down

0 comments on commit a067bf9

Please sign in to comment.