llama

package module
v0.0.0-...-c81f3ba Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 29, 2019 License: Apache-2.0 Imports: 25 Imported by: 0

README

LLAMA

LLAMA (Loss and LAtency MAtrix) is a library for testing and measuring network loss and latency between distributed endpoints.

It does this by sending UDP datagrams/probes from collectors to reflectors and measuring how long it takes for them to return, if they return at all. UDP is used to provide ECMP hashing over multiple paths (a win over ICMP) without the need for setup/teardown and per-packet granularity (a win over TCP).

Why Is This Useful

Black box testing is critical to the successful monitoring and operation of a network. While collection of metrics from network devices can provide greater detail regarding known issues, they don't always provide a complete picture and can provide an overwhelming number of metrics. Black box testing with LLAMA doesn't care how the network is structured, only if it's working. This data can be used for building KPIs, observing big-picture issues, and guiding investigations into issues with unknown causes by quantifying which flows are/aren't working.

At Dropbox, we've found this useful on multiple occasions for gauging the impact of network issues on internal traffic, identifying the scope of impact, and locating issues for which we had no other metrics (internal hardware failures, circuit degradations, etc).

Even if you operate entirely in the cloud LLAMA can help identify reachability and network health issues between and within regions/zones.

Architecture

  • Reflector - Lightweight daemon for receiving probes and sending them back to their source.
  • Collector - Sends probes to reflectors on potentially multiple ports, records results, and presents summarized data via REST API.
  • Scraper - Pulls results from REST API on collectors and writes to database (currently InfluxDB).

Quick Start

If you're looking to get started quickly with a basic setup that doesn't involve special integrations or customization, this should get you going. This assumes you have a running InfluxDB instance on locahost listening on port 5086 with a llama database already created.

In your Go development environment, in separate windows:

  • go run github.com/dropbox/llama/cmd/reflector
  • go run github.com/dropbox/llama/cmd/collector
  • go run github.com/dropbox/llama/cmd/scraper

If you want to run each of these on a separate machine/instance, after distributing the binaries created with go build, customizing the flags as needed:

  • reflector -port <port> to start the reflector listening on a non-default port.
  • collector -llama.dst-port <port> -llama.config <config> where the port matches what the reflector is listening on, and the config is a YAML configuration based on one of the examples under configs/.
  • scraper -llama.collector-hosts <hosts> -llama.collector-port <port> -llama.influxdb-host <hostname> -llama.influxdb-name <db-name> -llama.influxdb-pass <pass> -llama.influxdb-port <port> -llama.influxdb-user <user> -llama.interval <seconds>
    • collector-hosts being a comma-separated list of IP addresses or hostnames where collectors can be reached
    • collector-port identifying the port on which the collector's API is configured to listen
    • influxdb-* detailing where the InfluxDB instance can be reached, credentials, and database
    • interval being how often, in seconds, the scraper should pull data from collectors and write to the database. Should align with the summarization interval in the collector config.

Ongoing Development

LLAMA was primarily built during a Dropbox Hack Week and is still considered unstable, as the API, config format, and overall design is not considered final. It works and we've been using the original internal version for quite a while, but we want to make various changes and improvements before considering a v1.0.0 release.

Contributing

At this time, we're not ready for external contributors. Once we have a v1.0.0 release, we'll happily reconsider this and update accordingly. When that happens, substantial contributors will need to agree to the Dropbox Contributor License Agreement.

Acknowledgements/References

Documentation

Overview

Llama client to pull metrics from Llama collectors

LLAMA Collector sends UDP probes to a set of target reflectors and provides statistics about their latency and reachability via an API.

Mock Llama client used in `client_test.go`

Functionality for sending and receiving UDP probes on a socket.

portgroup defines PortGroup, which is used to multiplex UDPAddr structs to multiple ports via parallel channels.

LLAMA Scraper pulls stats from Collectors and then writes them to the indicated database.

Tags is a helper description for a structure that stores a map of attributes and values for a given key.

Example: Tags["1.2.3.4"]["dst_hostname"] = "localhost" Tags["1.2.3.4"]["dst_cluster"] = "mycluster"

Index

Constants

View Source
const (
	// Listens on any addr to an automatically assigned port number
	DefaultAddrStr        = "0.0.0.0:0"
	DefaultTos            = byte(0)
	DefaultRcvBuff        = 2097600 // 2MiB
	DefaultReadTimeout    = 200 * time.Millisecond
	DefaultCacheTimeout   = 2 * time.Second
	DefaultCacheCleanRate = 5 * time.Second
	ExpireNow             = time.Nanosecond
)
View Source
const DEFAULT_CHANNEL_SIZE int64 = 100 // Default size used for buffered channels.
View Source
const DefaultTimeout = time.Second * 5

Set default timeout for writes to 5 seconds This may be worth adding as a parameter in the future

Variables

This section is empty.

Functions

func CalcCounts

func CalcCounts(results []*Result, summary *Summary)

CalcCounts will calculate the Sent and Lost counts on the provided summary, based on the provided results.

func CalcLoss

func CalcLoss(summary *Summary)

CalcLoss will calculate the Loss percentage (out of 1) based on the Sent and Lost vaules of the provided summary.

func CalcRTT

func CalcRTT(results []*Result, summary *Summary)

CalcRT will calculate the RTT values for the provided summary, based on the provided results.

func EnableTimestamps

func EnableTimestamps(conn *net.UDPConn)

EnableTimestamps enables kernel receive timestamping of packets on the provided conn.

The timestamp values can later be extracted in the oob data from Receive.

func FileCloseHandler

func FileCloseHandler(f *os.File)

FileCloseHandler will close an open File and handle the resulting error.

func GetTos

func GetTos(conn *net.UDPConn) byte

GetTos will get the IP_TOS value for the unix socket for the provided conn.

func HandleError

func HandleError(err error)

func HandleFatalError

func HandleFatalError(err error)

HandleError receives an error, then logs and exits if not nil. TODO(dmar): Create additional simple handlers for non-fatal issues

func HandleMinorError

func HandleMinorError(err error)

func IDToBytes

func IDToBytes(id string) [10]byte

IDTo10Bytes converts a string to a 10 byte array.

func LocalUDPAddr

func LocalUDPAddr(conn *net.UDPConn) (*net.UDPAddr, string, error)

LocalUDPAddr returns the UDPAddr and net for the provided UDPConn.

For UDPConn instances, net is generaly 'udp'.

func NewClient

func NewClient(hostname string, port string) *client

NewClient creates a new collector client with hostname and port TODO(dmar): This is likely overkill and should be simplified.

func NewID

func NewID() string

NewID returns 10 bytes of a new UUID4 as a string.

This should be unique enough for short-lived cases, but as it's only a partial UUID4.

func NowUint64

func NowUint64() uint64

NowUint64 returns the current time in nanoseconds as a uint64.

func NsToMs

func NsToMs(ns float64) float64

NsToMs takes ns (nanoseconds) and converts it to milliseconds.

func PackUdpData

func PackUdpData(data *UdpData) ([]byte, error)

TODO(dmar): These should be functions attached to `UdpData` PackUdpData takes a UdpData instances and converts it to a byte array.

func RTT

func RTT(probe *Probe, result *Result) error

RTT calculates the round trip time for a probe and updates the Result.

func Receive

func Receive(data []byte, oob []byte, conn *net.UDPConn) (
	[]byte, []byte, *net.UDPAddr)

Receive accepts UDP packets on the provided conn and returns the data and and control message slices, as well as the UDPAddr it was received from.

func Reflect

func Reflect(conn *net.UDPConn, rl *rate.Limiter)

Reflect will listen on the provided UDPConn and will send back any UdpData compliant packets that it receives, in compliance with the RateLimiter.

func Send

func Send(data []byte, conn *net.UDPConn, addr *net.UDPAddr)

Send will send the provided data using the conn to the addr, via UDP.

func SetRecvBufferSize

func SetRecvBufferSize(conn *net.UDPConn, size int)

SetRecvBufferSize sets the size of the receive buffer for the conn to the provided size in bytes. TODO(dmar): Validate and replace this with a simple call to conn.SetReadBuffer

func SetTos

func SetTos(conn *net.UDPConn, tos byte)

SetTos will set the IP_TOS value for the unix socket for the provided conn.

TODO(dmar): May want to have these return the err, or actually handle. Could dedup there a bit. Maybe.

Types

type API

type API struct {
	// contains filtered or unexported fields
}

API represnts the HTTP server answering queries for collected data.

func NewAPI

func NewAPI(s *Summarizer, t TagSet, addr string) *API

New returns an initialized API struct.

func (*API) InfluxHandler

func (api *API) InfluxHandler(rw http.ResponseWriter, request *http.Request)

InfluxHandler handles requests for InfluxDB formatted summaries.

func (*API) MergeUpdateTagSet

func (api *API) MergeUpdateTagSet(t TagSet)

MergeUpdateTagSet combines a provided TagSet with the existing one

func (*API) Run

func (api *API) Run()

Run calls RunForever in a separate goroutine for non-blocking behavior.

func (*API) RunForever

func (api *API) RunForever()

RunForever sets up the handlers above and then listens for requests until stopped or a fatal error occurs.

Calling this will block until stopped/crashed.

func (*API) StatusHandler

func (api *API) StatusHandler(rw http.ResponseWriter, request *http.Request)

StatusHandler acts as a back healthcheck and simply returns 200 OK.

func (*API) Stop

func (api *API) Stop()

Stop will close down the server and cause Run to exit.

type APIConfig

type APIConfig struct {
	Bind string `yaml:"bind"`
}

APIConfig describes the parameters for the JSON HTTP API.

type Client

type Client interface {
	GetPoints() (Points, error)
	Hostname() string
	Port() string
}

Client is a n interface for pulling stats from LLAMA collectors

type Collector

type Collector struct {
	// contains filtered or unexported fields
}

Collector reads a YAML configuration, performs UDP probe tests against targets, and provides summaries of the results via a JSON HTTP API.

func (*Collector) LoadConfig

func (c *Collector) LoadConfig()

LoadConfig loads the collector's configuration from CLI flag if provided, otherwise the default.

func (*Collector) Reload

func (c *Collector) Reload()

Reload causes the config to be reread, and test runners recreated

func (*Collector) Run

func (c *Collector) Run()

Run starts all of the components of the collector and begins testing.

func (*Collector) Setup

func (c *Collector) Setup()

Setup is a generally wrapper around all of the other Setup* functions.

func (*Collector) SetupAPI

func (c *Collector) SetupAPI()

SetupAPI creates and performs initial setup of the API based on the config.

func (*Collector) SetupSummarizer

func (c *Collector) SetupSummarizer()

SetupSummarizer creates the Summarizer and ResultHandlers that will summarize and save the test results, based on the config.

func (*Collector) SetupTagSet

func (c *Collector) SetupTagSet()

SetupTagSet loads the tags for targets, based on the config, that will be applied to summarized results.

func (*Collector) SetupTestRunner

func (c *Collector) SetupTestRunner(test TestConfig)

SetupTestRunner takes parameters from the loaded config, and creates the specified TestConfig.

func (*Collector) SetupTestRunners

func (c *Collector) SetupTestRunners()

SetupTestRunners creates all the `tests` that are defined in the config.

func (*Collector) Stop

func (c *Collector) Stop()

Stop will signal all collector components to stop.

type CollectorConfig

type CollectorConfig struct {
	Summarization SummarizationConfig `yaml:"summarization"`
	API           APIConfig           `yaml:"api"`
	Ports         PortsConfig         `yaml:"ports"`
	PortGroups    PortGroupsConfig    `yaml:"port_groups"`
	RateLimits    RateLimitsConfig    `yaml:"rate_limits"`
	Tests         TestsConfig         `yaml:"tests"`
	Targets       TargetsConfig       `yaml:"targets"`
}

CollectorConfig wraps all of the above structs/maps/slices and defines the overall configuration for a collector.

func NewCollectorConfig

func NewCollectorConfig(data []byte) (*CollectorConfig, error)

NewCollectorConfig provides a parsed CollectorConfig based on the provided data.

`data` is expected to be a byte slice version of a YAML CollectorConfig.

func NewDefaultCollectorConfig

func NewDefaultCollectorConfig() (*CollectorConfig, error)

NewDefaultCollectorConfig provides a sensible default collector config.

type DataPoint

type DataPoint struct {
	Fields      map[string]IDBFloat64 `json:"fields"`
	Tags        Tags                  `json:"tags"`
	Time        time.Time             `json:"time"`
	Measurement string                `json:"measurement"`
}

DataPoint represents a single "point" of data for InfluxDB.

func NewDataPoint

func NewDataPoint() *DataPoint

NewDataPoint provides an empty and usable DataPoint.

func NewDataPointFromSummary

func NewDataPointFromSummary(s *Summary, t Tags) *DataPoint

NewDataPointFromSummary provides a new DataPoint populated with values in s and t.

func NewDataPointsFromSummaries

func NewDataPointsFromSummaries(summaries []*Summary, t TagSet) []*DataPoint

NewFromSummaries allows bulk operations against New by providing a slice of summaries and map of Tags (t).

func (*DataPoint) FromPD

func (dp *DataPoint) FromPD(pd *PathDist)

FromPD updates the values of dp to reflect what is available in pd.

func (*DataPoint) FromSummary

func (dp *DataPoint) FromSummary(s *Summary)

FromSummary updates the values of dp to reflect what is available in s.

func (*DataPoint) SetFieldFloat64

func (dp *DataPoint) SetFieldFloat64(k string, v float64)

SetFieldFloat64 sets the value of "field" k to the value v.

func (*DataPoint) SetFieldInt

func (dp *DataPoint) SetFieldInt(k string, v int)

SetFieldINt sets the value of "field" k to the value v.

func (*DataPoint) SetMeasurement

func (dp *DataPoint) SetMeasurement(s string)

SetMeasurements set the measurement of the dp to the value of s.

func (*DataPoint) SetTime

func (dp *DataPoint) SetTime(t time.Time)

SetTime updates the Time of the dp.

func (*DataPoint) UpdateTags

func (dp *DataPoint) UpdateTags(t Tags)

UpdateTags populates the tags of the dp based on the provided Tags map.

type Getter

type Getter = func(url string) (resp *http.Response, err error)

type IDBFloat64

type IDBFloat64 float64

IDBFloat64 is to allow custom JSON marshalling in the API, so it actually formats like a float consistently

func (IDBFloat64) MarshalJSON

func (n IDBFloat64) MarshalJSON() ([]byte, error)

TODO(dmar): This should be handled in the scraper by always writing numbers

as floats. But for now, ensure that float64 values without
decimal precision are still written in decimal format.
Otherwise, it turns into an int along the way and makes
InfluxDB angry. Another alternative, GRPC and Protobufs instead
of a JSON HTTP API.

type InfluxDbWriter

type InfluxDbWriter struct {
	// contains filtered or unexported fields
}

InfluxDbWriter is used for writing datapoints to an InfluxDB instance

func NewInfluxDbWriter

func NewInfluxDbWriter(host string, port string, user string, pass string, db string) (*InfluxDbWriter, error)

NewInfluxDbWriter provides a client for writing LLAMA datapoints to InfluxDB

func (*InfluxDbWriter) Batch

Batch will group the points into a batch for writing to the database

func (*InfluxDbWriter) BatchWrite

func (w *InfluxDbWriter) BatchWrite(points Points) error

BatchWrite will group and write the indicates points to the associated InfluxDB host

func (*InfluxDbWriter) Close

func (w *InfluxDbWriter) Close() error

Close will close the InfluxDB client connection and release any associated resources

func (*InfluxDbWriter) Write

Write will commit the batched points to the database

type LegacyCollectorConfig

type LegacyCollectorConfig map[string]map[string]string

LegacyCollectorConfig is for backward compatibility with the existing LLAMA config and represents only a map of targets to tags.

func NewLegacyCollectorConfig

func NewLegacyCollectorConfig(data []byte) (*LegacyCollectorConfig, error)

NewLegacyCollectorConfig creates a new LegacyCollectorConfig struct based on the provided data, which is expected to be a YAML representation of the config.

func (*LegacyCollectorConfig) ToDefaultCollectorConfig

func (legacy *LegacyCollectorConfig) ToDefaultCollectorConfig(port int64) (*CollectorConfig, error)

ToDefaultCollectorConfig converts a LegacyCollectorConfig to CollectorConfig by merging with the defaults and applying the provided port on targets.

type MockClient

type MockClient struct {
	NextPoints Points
	NextErr    error
	// contains filtered or unexported fields
}

func NewMock

func NewMock(serverHost string) (*MockClient, error)

deadcode: NewMock is grandfathered in as legacy code

func (*MockClient) GetPoints

func (m *MockClient) GetPoints() (Points, error)

func (*MockClient) Hostname

func (m *MockClient) Hostname() string

func (*MockClient) Port

func (m *MockClient) Port() string

func (*MockClient) Run

func (m *MockClient) Run()

type PathDist

type PathDist struct {
	SrcIP   net.IP
	SrcPort int
	DstIP   net.IP
	DstPort int
	Proto   string // 'udp' generally
}

PathDist -> Path Distinguisher, uniquely IDs the components that determine path selection.

type Points

type Points []DataPoint

Points is a collection of DataPoints

type Port

type Port struct {
	// contains filtered or unexported fields
}

Port represents a socket and its associated caching, inputs, and outputs.

func NewDefault

func NewDefault(tosend chan *net.UDPAddr, stop chan bool,
	cbc chan *Probe) *Port

NewDefault creates a new Port using default settings.

func NewPort

func NewPort(conn *net.UDPConn, tosend chan *net.UDPAddr, stop chan bool,
	cbc chan *Probe, cTimeout time.Duration, cCleanRate time.Duration,
	readTimeout time.Duration) *Port

New creates and returns a new Port with associated inputs, outputs, and caching mechanisms.

func (*Port) Recv

func (p *Port) Recv()

Recv listens on the Port for returning probes and updates them in the cache.

Once probes are received, they are located in the cache, updated, and then set for immediate expiration. If a probe is received but has no entry in the cache, it most likely exceeded the timeout.

func (*Port) Send

func (p *Port) Send()

Send waits to get UDPAddr targets and sends probes to them using the associated Port.

After sending the probe, it is added to a cache with a unique ID, which is used for retrieving later. The cache will also utilize a timeout to expire probes that haven't returned in time.

func (*Port) Tos

func (p *Port) Tos() byte

ToS provides the currently active ToS byte value for the port's conn.

type PortConfig

type PortConfig struct {
	IP      string `yaml:"ip"`
	Port    int64  `yaml:"port"`
	Tos     int64  `yaml:"tos"`
	Timeout int64  `yaml:"timeout"`
}

PortConfig describes the configuration for a single Port.

type PortGroup

type PortGroup struct {
	// contains filtered or unexported fields
}

func NewPortGroup

func NewPortGroup(stop chan bool, cbc chan *Probe,
	tosend chan *net.UDPAddr) *PortGroup

New creates a new PortGroup utilizing a set of input, output, and signalling channels.

stop is used to signal stopping of the PortGroup and all ports. cbc is used as a callback for completed or timedout probes from all ports. tosend is used to receive UDPAddr targets for sending to probes, and is muxed across all Ports in the PortGroup.

func (*PortGroup) Add

func (pg *PortGroup) Add(p *Port, c chan *net.UDPAddr)

Add will add a Port and channel to the PortGroup.

This must NOT be used after running, as it is currently not threadsafe. TODO(dmar): In the future, if doing this is desired, add a mutex and

appropriate locking.

func (*PortGroup) AddNew

func (pg *PortGroup) AddNew(portStr string, tos byte, cTimeout time.Duration,
	cCleanRate time.Duration,
	readTimeout time.Duration) (
	*Port, chan *net.UDPAddr)

AddNew will create a new Port and add it to the PortGroup via Add.

func (*PortGroup) Del

func (pg *PortGroup) Del(p *Port)

Del removes a Port from the PortGroup.

This must NOT be done after running. TODO(dmar): If this is desirable, similar to Add, a mutex and locking

will be needed and adds overhead.

func (*PortGroup) Run

func (pg *PortGroup) Run()

Run will start sending/receiving on all Ports in the PortGroup, and then then loop muxing inbound UDPAddrs to all ports until stopped.

TODO(dmar): Add something here to prevent ports from being added after

it has started running. Otherwise, a mutex is needed to
to sync things, though that may be a fine option as long
as there aren't too many goroutines or ports.

TODO(dmar): Allow an arg for starting multiple goroutines? Otherwise

leave that to higher level stuff.

func (*PortGroup) Stop

func (pg *PortGroup) Stop()

Stop will signal all muxing to cease (if started) and stop all Ports.

type PortGroupConfig

type PortGroupConfig struct {
	Port  string `yaml:"port"` // Should correspond with a PortsConfig key
	Count int64  `yaml:"count"`
}

PortGroupConfig describes a set of identical Ports in a PortGroup.

type PortGroupsConfig

type PortGroupsConfig map[string][]PortGroupConfig

PortGroupsConfig is a mapping of port group "name" to PortGroupConfigs.

type PortsConfig

type PortsConfig map[string]PortConfig

PortsConfig is a mapping of port "name" to a PortConfig.

type Probe

type Probe struct {
	Pd    *PathDist
	CSent uint64
	CRcvd uint64
	Tos   byte
}

Probe represents a single UDP probe that was sent from, and (hopefully) received back, a Port.

func IfaceToProbe

func IfaceToProbe(iface interface{}) (*Probe, error)

IfaceToProbe attempts to convert an anonymous object to a Probe, and returns and error if the operation failed.

type RateLimitConfig

type RateLimitConfig struct {
	CPS float64 `yaml:"cps"` // Cycles per second
}

RateLimitConfig describes the configuration for a rate limiter.

type RateLimitsConfig

type RateLimitsConfig map[string]RateLimitConfig

RateLimitsConfig is a mapping of "name" to RateLimitConfig.

type Result

type Result struct {
	Pd   *PathDist // Characteristics that make this path unique
	RTT  uint64    // Round trip time in nanoseconds
	Done uint64    // When the test completed (was received by Port) in ns
	Lost bool      // If the Probe was lost and never actually completed
}

Result defines characteristics of a single completed Probe.

func Process

func Process(probe *Probe) *Result

Process takes in a probe, performs calculations on it, and returns a Result.

type ResultHandler

type ResultHandler struct {
	// contains filtered or unexported fields
}

ResultHandler is a post-processor for Probes and converts them to Results.

func NewResultHandler

func NewResultHandler(in chan *Probe, out chan *Result) *ResultHandler

New creates a new ResultHandler that utilizes the provided in and out channels.

func (*ResultHandler) Run

func (rh *ResultHandler) Run()

Run will start the ResultHandler in a new goroutine, and cause it to forever receive Probes, process them and pass their results out.

func (*ResultHandler) Stop

func (rh *ResultHandler) Stop()

Stop will stop the rh.

type Scraper

type Scraper struct {
	// contains filtered or unexported fields
}

Scraper pulls stats from collectors and writes them to a backend

func NewScraper

func NewScraper(collectors []string, cPort string, dbHost string, dbPort string, dbUser string, dbPass string, dbName string) (*Scraper, error)

NewScraper creates and initializes a means of collecting stats and writing them to a database

func (*Scraper) Run

func (s *Scraper) Run()

Run performs collections for all assocated collectors

type SummarizationConfig

type SummarizationConfig struct {
	Interval int64 `yaml:"interval"`
	Handlers int64 `yaml:"handlers"`
}

SummarizationConfig describes the parameters for setting up a Summarizer and related ResultHandlers.

type Summarizer

type Summarizer struct {
	// NOTE(dmar): For posterity, use value references for mutexes, not pointers
	CMutex sync.RWMutex
	Cache  []*Summary
	// contains filtered or unexported fields
}

Summarizer stores results and summarizes them at intervals.

func NewSummarizer

func NewSummarizer(in chan *Result, interval time.Duration) *Summarizer

New returns a new Summarizer, based on the provided parameters.

func (*Summarizer) Run

func (s *Summarizer) Run()

Run causes the summarizer to infinitely wait for new results, store them, and then summarize at an interval.

When results are summarized, they are removed and won't be summarized again.

func (*Summarizer) Stop

func (s *Summarizer) Stop()

Stop will stop the summarizer from receiving results or summarizing them.

type Summary

type Summary struct {
	Pd     *PathDist
	RTTAvg float64
	RTTMin float64
	RTTMax float64
	Sent   int
	Lost   int
	Loss   float64
	TS     time.Time // No longer used, but keeping for posterity
}

Summary represents summaried results and statistics about them.

type TagSet

type TagSet map[string]Tags

type Tags

type Tags map[string]string

type TargetConfig

type TargetConfig struct {
	IP   string `yaml:"ip"`
	Port int64  `yaml:"port"`
	Tags Tags   `yaml:"tags"`
}

TargetConfig describes a single target for testing, including tags that are applied to the resulting summaries.

TODO(dmar): Restructure this to be more Dropbox specific, and reduce the

data being included in this config. Most of this can come from a base,
and then be populated by MDB queries.

func (*TargetConfig) AddrString

func (tc *TargetConfig) AddrString() string

AddrString converts the tc into a string formated "IP:port" combo.

func (*TargetConfig) ResolveUDPAddr

func (tc *TargetConfig) ResolveUDPAddr() (*net.UDPAddr, error)

ResolveUDPAddr converts the tc into a net.UDPAddr pointer.

type TargetSet

type TargetSet []TargetConfig

TargetSet is a slice of TargetConfig structs.

func (TargetSet) IntoTagSet

func (ts TargetSet) IntoTagSet(tagset TagSet)

IntoTagSet is similar to TagSet but updates the provided tagset instead of creating a new one.

func (TargetSet) ListResolvedTargets

func (ts TargetSet) ListResolvedTargets() ([]*net.UDPAddr, error)

ListResolvedTargets provides a slice of net.UDPAddr pointers for all of the targets in the ts, and will return with an error as soon as one is hit.

func (TargetSet) ListTargets

func (ts TargetSet) ListTargets() []string

ListTargets provides a slice of "IP:port" string representations for all of the targets in the ts.

func (TargetSet) TagSet

func (ts TargetSet) TagSet() TagSet

TagSet converts the ts into TagSet struct.

type TargetsConfig

type TargetsConfig map[string]TargetSet

TargetsConfig is a mapping of "name" to TargetSet slice.

func (TargetsConfig) IntoTagSet

func (tc TargetsConfig) IntoTagSet(ts TagSet)

IntoTagSet is a wrapper about the same function for each contained TargetSet and merges them into an existing ts.

func (TargetsConfig) TagSet

func (tc TargetsConfig) TagSet() TagSet

TagSet is a wrapper, and merges the TagSet output for all TargetSet slices within the tc.

type TestConfig

type TestConfig struct {
	Targets   string `yaml:"targets"`    // Should correspond with a TargetsConfig key
	PortGroup string `yaml:"port_group"` // Should correspond with a PortGroupsConfig key
	RateLimit string `yaml:"rate_limit"` // Should correspond with a RateLimitsConfig key
}

TestConfig describes the elements of a test, for use by TestRunner, which correspond to their respective named elements in the config.

Ex. A `targets` value of "default" in the config would correspond to a TargetsConfig key of "default" which contains the definitions of targets.

type TestRunner

type TestRunner struct {
	// contains filtered or unexported fields
}

TestRunner repeatedly runs through a list of targets and passes them down to a PortGroup for processing.

func NewTestRunner

func NewTestRunner(cbc chan *Probe, rl *rate.Limiter) *TestRunner

New creates and returns a new TestRunner instance.

`cbc` is a channel for accepting completed Probes. `rl` is a rate limiter which is used to throttle the number of cycles that may be completed per second.

func (*TestRunner) Add

func (tr *TestRunner) Add(addrs ...*net.UDPAddr)

Add will add a variable number of addrs to the slice of targets for processing.

NOTE: This will block during cycles. So it should be avoided when possible.

It's better to just use `Set` to replace the whole thing. Either way,
this change will only go into effect between cycles.

func (*TestRunner) AddNewPort

func (tr *TestRunner) AddNewPort(portStr string, tos byte,
	cTimeout time.Duration,
	cCleanRate time.Duration,
	readTimeout time.Duration)

AddNewPort will add a new Port to the TestRunner's PortGroup.

See PortGroup.AddNew for more details on these arguments.

NOTE: This is basically just a passthrough for PortGroup.AddNew until

the pattern is better understood and this can be cleaned up.

func (*TestRunner) Del

func (tr *TestRunner) Del(addr *net.UDPAddr)

Del will remove all occurrences of a target addr from the slice of targets.

NOTE: This will block during cycles. It will also take longer as the

number of targets increases. So it should be avoided when possible.
It's better to just use `Set` to replace the whole thing. Either way,
this change will only go into effect between cycles.

func (*TestRunner) Run

func (tr *TestRunner) Run()

Run starts the TestRunner and begins cycling through targets.

func (*TestRunner) Set

func (tr *TestRunner) Set(targets []*net.UDPAddr)

Set will replace the current slice of targets with the provided one.

NOTE: This will block during cycles. It is generally advised to use `Set`

over `Add` and `Del` in making larger changes or operating on multiple
targets. It's just more atomic.

func (*TestRunner) Stop

func (tr *TestRunner) Stop()

Stop will stop the TestRunner after the current cycle and any underlying PortGroup and Port(s).

type TestsConfig

type TestsConfig []TestConfig

TestsConfig is a slice of TestConfig structs.

type UdpData

type UdpData struct {
	Signature [10]byte
	Tos       byte
	Sent      uint64
	Rcvd      uint64
	RTT       uint64
	Lost      uint8 // binary.Read doesn't handle bool correctly
}

func UnpackUdpData

func UnpackUdpData(data []byte) (*UdpData, error)

UnpackUdpData takes data and unpacks it into a UdpData struct, returning an error if the data was not compatible.

Directories

Path Synopsis
cmd
scraper
LLAMA Scraper pulls stats from Collectors and then writes them to the indicated database.
LLAMA Scraper pulls stats from Collectors and then writes them to the indicated database.
Code generated by protoc-gen-gogo.
Code generated by protoc-gen-gogo.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL