github.com/observiq/carbon@v0.9.11-0.20200820160507-1b872e368a5e/operator/helper/host_identifier.go (about)

     1  package helper
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"os"
     7  
     8  	"github.com/observiq/carbon/entry"
     9  	"github.com/observiq/carbon/errors"
    10  )
    11  
    12  // NewHostIdentifierConfig returns a HostIdentifierConfig with default values
    13  func NewHostIdentifierConfig() HostIdentifierConfig {
    14  	return HostIdentifierConfig{
    15  		IncludeHostname: true,
    16  		IncludeIP:       true,
    17  		getHostname:     getHostname,
    18  		getIP:           getIP,
    19  	}
    20  }
    21  
    22  // HostIdentifierConfig is the configuration of a host identifier
    23  type HostIdentifierConfig struct {
    24  	IncludeHostname bool `json:"include_hostname,omitempty"     yaml:"include_hostname,omitempty"`
    25  	IncludeIP       bool `json:"include_ip,omitempty"     yaml:"include_ip,omitempty"`
    26  	getHostname     func() (string, error)
    27  	getIP           func() (string, error)
    28  }
    29  
    30  // Build will build a host labeler from the supplied configuration
    31  func (c HostIdentifierConfig) Build() (HostIdentifier, error) {
    32  	identifier := HostIdentifier{
    33  		includeHostname: c.IncludeHostname,
    34  		includeIP:       c.IncludeIP,
    35  	}
    36  
    37  	if c.getHostname == nil {
    38  		return identifier, fmt.Errorf("getHostname func is not set")
    39  	}
    40  
    41  	if c.getIP == nil {
    42  		return identifier, fmt.Errorf("getIP func is not set")
    43  	}
    44  
    45  	if c.IncludeHostname {
    46  		hostname, err := c.getHostname()
    47  		if err != nil {
    48  			return identifier, errors.Wrap(err, "get hostname")
    49  		}
    50  		identifier.hostname = hostname
    51  	}
    52  
    53  	if c.IncludeIP {
    54  		ip, err := c.getIP()
    55  		if err != nil {
    56  			return identifier, errors.Wrap(err, "get ip address")
    57  		}
    58  		identifier.ip = ip
    59  	}
    60  
    61  	return identifier, nil
    62  }
    63  
    64  // getHostname will return the hostname of the current host
    65  func getHostname() (string, error) {
    66  	return os.Hostname()
    67  }
    68  
    69  // getIP will return the IP address of the current host
    70  func getIP() (string, error) {
    71  	var ip string
    72  
    73  	interfaces, err := net.Interfaces()
    74  	if err != nil {
    75  		return "", errors.Wrap(err, "list interfaces")
    76  	}
    77  
    78  	for _, i := range interfaces {
    79  		// Skip loopback interfaces
    80  		if i.Flags&net.FlagLoopback != 0 {
    81  			continue
    82  		}
    83  
    84  		// Skip down interfaces
    85  		if i.Flags&net.FlagUp == 0 {
    86  			continue
    87  		}
    88  
    89  		addrs, err := i.Addrs()
    90  		if err != nil {
    91  			continue
    92  		}
    93  		if len(addrs) > 0 {
    94  			ip = addrs[0].String()
    95  		}
    96  	}
    97  
    98  	if len(ip) == 0 {
    99  		return "", errors.NewError(
   100  			"failed to find ip address",
   101  			"check that a non-loopback interface with an assigned IP address exists and is running",
   102  		)
   103  	}
   104  
   105  	return ip, nil
   106  }
   107  
   108  // HostIdentifier is a helper that adds host related metadata to an entry's resource
   109  type HostIdentifier struct {
   110  	hostname        string
   111  	ip              string
   112  	includeHostname bool
   113  	includeIP       bool
   114  }
   115  
   116  // Identify will add host related metadata to an entry's resource
   117  func (h *HostIdentifier) Identify(entry *entry.Entry) {
   118  	if h.includeHostname {
   119  		entry.AddResourceKey("hostname", h.hostname)
   120  	}
   121  
   122  	if h.includeIP {
   123  		entry.AddResourceKey("ip", h.ip)
   124  	}
   125  }