@ -23,35 +23,87 @@ import (
"time"
)
// The state of the given Target.
type TargetState int
const (
// The Target has not been seen; we know nothing about it, except that it is
// on our docket for examination.
UNKNOWN TargetState = iota
// The Target has been found and successfully queried.
ALIVE
// The Target was either historically found or not found and then determined
// to be unhealthy by either not responding or disappearing.
UNREACHABLE
)
// A healthReporter is a type that can provide insight into its health state.
//
// It mainly exists for testability reasons to decouple the scheduler behaviors
// from fully-fledged Target and other types.
type healthReporter interface {
// Report the last-known health state for this target.
State ( ) TargetState
}
// A Target represents an endpoint that should be interrogated for metrics.
//
// The protocol described by this type will likely change in future iterations,
// as it offers no good support for aggregated targets and fan out. Thusly,
// it is likely that the current Target and target uses will be
// wrapped with some resolver type.
//
// For the future, the Target protocol will abstract away the exact means that
// metrics are retrieved and deserialized from the given instance to which it
// refers.
type Target interface {
// Retrieve values from this target.
//
// earliest refers to the soonest available opportunity to reschedule the
// target for a future retrieval. It is up to the underlying scheduler type,
// alluded to in the scheduledFor function, to use this as it wants to. The
// current use case is to create a common batching time for scraping multiple
// Targets in the future through the TargetPool.
Scrape ( earliest time . Time , results chan Result ) error
// Fulfill the healthReporter interface.
State ( ) TargetState
// Report the soonest time at which this Target may be scheduled for
// retrieval. This value needn't convey that the operation occurs at this
// time, but it should occur no sooner than it.
//
// Right now, this is used as the sorting key in TargetPool.
scheduledFor ( ) time . Time
// The address to which the Target corresponds. Out of all of the available
// points in this interface, this one is the best candidate to change given
// the ways to express the endpoint.
Address ( ) string
// How frequently queries occur.
Interval ( ) time . Duration
}
type Target struct {
// target is a Target that refers to a singular HTTP or HTTPS endpoint.
type target struct {
// scheduler provides the scheduling strategy that is used to formulate what
// is returned in Target.scheduledFor.
scheduler scheduler
state TargetState
Address string
Deadline time . Duration
address string
// What is the deadline for the HTTP or HTTPS against this endpoint.
Deadline time . Duration
// Any base labels that are added to this target and its metrics.
BaseLabels model . LabelSet
// XXX: Move this to a field with the target manager initialization instead of here.
Interval time . Duration
i nterval time . Duration
}
func NewTarget ( address string , interval , deadline time . Duration , baseLabels model . LabelSet ) * Target {
target := & Target {
Address : address ,
// Furnish a reasonably configured target for querying.
func NewTarget ( address string , interval , deadline time . Duration , baseLabels model . LabelSet ) Target {
target := & target {
address : address ,
Deadline : deadline ,
Interval : interval ,
i nterval: interval ,
BaseLabels : baseLabels ,
}
@ -69,7 +121,7 @@ type Result struct {
Target Target
}
func ( t * T arget) Scrape ( earliest time . Time , results chan Result ) ( err error ) {
func ( t * t arget) Scrape ( earliest time . Time , results chan Result ) ( err error ) {
result := Result { }
defer func ( ) {
@ -92,7 +144,7 @@ func (t *Target) Scrape(earliest time.Time, results chan Result) (err error) {
request := func ( ) {
ti := time . Now ( )
resp , err := http . Get ( t . Address )
resp , err := http . Get ( t . Address ( ) )
if err != nil {
return
}
@ -110,7 +162,7 @@ func (t *Target) Scrape(earliest time.Time, results chan Result) (err error) {
return
}
baseLabels := map [ string ] string { "instance" : t . Address }
baseLabels := map [ string ] string { "instance" : t . Address ( ) }
for name , v := range intermediate {
asMap , ok := v . ( map [ string ] interface { } )
@ -199,10 +251,18 @@ func (t *Target) Scrape(earliest time.Time, results chan Result) (err error) {
return
}
func ( t T arget) State ( ) TargetState {
func ( t t arget) State ( ) TargetState {
return t . state
}
func ( t T arget) scheduledFor ( ) time . Time {
func ( t t arget) scheduledFor ( ) time . Time {
return t . scheduler . ScheduledFor ( )
}
func ( t target ) Address ( ) string {
return t . address
}
func ( t target ) Interval ( ) time . Duration {
return t . interval
}