Skip to content

Commit

Permalink
Merge pull request #58 from honeycombio/travis.redis-ip
Browse files Browse the repository at this point in the history
[redis] allow IP and other host identifiers
  • Loading branch information
tredman authored Apr 22, 2020
2 parents 9c3578f + c1b247a commit ba8a5b7
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 19 deletions.
21 changes: 21 additions & 0 deletions config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,27 @@ Peers = [
# Not eligible for live reload.
RedisHost = "localhost:6379"

# IdentifierInterfaceName is optional. By default, when using RedisHost, samproxy will use
# the local hostname to identify itself to other peers in Redis. If your environment
# requires that you use IPs as identifiers (for example, if peers can't resolve eachother
# by name), you can specify the network interface that samproxy is listening on here.
# Samproxy will use the first unicast address that it finds on the specified network
# interface as its identifier.
# Not eligible for live reload.
# IdentifierInterfaceName = "eth0"

# UseIPV6Identifier is optional. If using IdentifierInterfaceName, samproxy will default to the first
# IPv4 unicast address it finds for the specified interface. If UseIPV6Identifier is used, will use
# the first IPV6 unicast address found.
# UseIPV6Identifier = false

# RedisIdentifier is optional. By default, when using RedisHost, samproxy will use
# the local hostname to identify itself to other peers in Redis. If your environment
# requires that you use IPs as identifiers (for example, if peers can't resolve eachother
# by name), you can specify the exact identifier (IP address, etc) to use here.
# Not eligible for live reload. Overrides IdentifierInterfaceName, if both are set.
# RedisIdentifier = "192.168.1.1"

# HoneycombAPI is the URL for the upstream Honeycomb API.
# Eligible for live reload.
HoneycombAPI = "https://api.honeycomb.io"
Expand Down
49 changes: 32 additions & 17 deletions config/fileconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,26 @@ type FileConfig struct {
}

type confContents struct {
ListenAddr string
PeerListenAddr string
APIKeys []string
Peers []string
RedisHost string
HoneycombAPI string
CollectCacheCapacity int
Logger string
LoggingLevel string
Collector string
Sampler string
Metrics string
SendDelay int
SpanSeenDelay int
TraceTimeout int
UpstreamBufferSize int
PeerBufferSize int
ListenAddr string
PeerListenAddr string
APIKeys []string
Peers []string
RedisHost string
RedisIdentifier string
IdentifierInterfaceName string
UseIPV6Identifier bool
HoneycombAPI string
CollectCacheCapacity int
Logger string
LoggingLevel string
Collector string
Sampler string
Metrics string
SendDelay int
SpanSeenDelay int
TraceTimeout int
UpstreamBufferSize int
PeerBufferSize int
}

// Used to marshall in the sampler type in SamplerConfig definitions
Expand Down Expand Up @@ -99,6 +102,18 @@ func (f *FileConfig) GetRedisHost() (string, error) {
return f.conf.RedisHost, nil
}

func (f *FileConfig) GetIdentifierInterfaceName() (string, error) {
return f.conf.IdentifierInterfaceName, nil
}

func (f *FileConfig) GetUseIPV6Identifier() (bool, error) {
return f.conf.UseIPV6Identifier, nil
}

func (f *FileConfig) GetRedisIdentifier() (string, error) {
return f.conf.RedisIdentifier, nil
}

func (f *FileConfig) GetHoneycombAPI() (string, error) {
return f.conf.HoneycombAPI, nil
}
Expand Down
55 changes: 53 additions & 2 deletions config/redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package config
import (
"context"
"fmt"
"net"
"os"
"sort"
"strings"
Expand All @@ -24,6 +25,14 @@ type RedisPeerFileConfig struct {
// store and check for peers
RedisAddress string

// If set, register the host in redis using the (first) IP address from the interface
// specified here. If not set, registers the host using its hostname.
IdentifierInterfaceName string

UseIPV6Identifier bool

RedisIdentifier string

// peers is my local cache of the peer list. It gets updated by a background
// ticker
peers []string
Expand Down Expand Up @@ -80,6 +89,9 @@ func (rc *RedisPeerFileConfig) Start() error {
}

rc.RedisAddress, _ = rc.GetRedisHost()
rc.IdentifierInterfaceName, _ = rc.GetIdentifierInterfaceName()
rc.UseIPV6Identifier, _ = rc.GetUseIPV6Identifier()
rc.RedisIdentifier, _ = rc.GetRedisIdentifier()

if rc.RedisAddress == "" {
rc.RedisAddress = "localhost:6379"
Expand Down Expand Up @@ -108,8 +120,47 @@ func (rc *RedisPeerFileConfig) Start() error {
// compute the public version of my peer listen address
listenAddr, _ := rc.FileConfig.GetPeerListenAddr()
port := strings.Split(listenAddr, ":")[1]
myhostname, _ := os.Hostname()
publicListenAddr := fmt.Sprintf("http://%s:%s", myhostname, port)

myIdentifier, _ := os.Hostname()
if rc.IdentifierInterfaceName != "" {
ifc, err := net.InterfaceByName(rc.IdentifierInterfaceName)
if err != nil {
logrus.WithError(err).WithField("interface", rc.IdentifierInterfaceName).
Error("IdentifierInterfaceName set but couldn't find interface by that name")
return
}
addrs, err := ifc.Addrs()
if err != nil {
logrus.WithError(err).WithField("interface", rc.IdentifierInterfaceName).
Error("IdentifierInterfaceName set but couldn't list addresses")
return
}
var ipStr string
for _, addr := range addrs {
// ParseIP doesn't know what to do with the suffix
ip := net.ParseIP(strings.Split(addr.String(), "/")[0])
if rc.UseIPV6Identifier && ip.To16() != nil {
ipStr = fmt.Sprintf("[%s]", ip.String())
break
}
if !rc.UseIPV6Identifier && ip.To4() != nil {
ipStr = ip.String()
break
}
}
if ipStr == "" {
logrus.WithField("interface", ifc.Name).Error("could not find a valid IP to use from interface")
return
}
myIdentifier = ipStr
logrus.WithField("identifier", myIdentifier).WithField("interface", ifc.Name).Info("using identifier from interface")
}
if rc.RedisIdentifier != "" {
myIdentifier = rc.RedisIdentifier
logrus.WithField("identifier", myIdentifier).Info("using specific identifier from config")
}

publicListenAddr := fmt.Sprintf("http://%s:%s", myIdentifier, port)
rc.publicAddr = publicListenAddr

// register myself once
Expand Down

0 comments on commit ba8a5b7

Please sign in to comment.