@ -117,6 +117,7 @@ type target struct {
Deadline time . Duration
Deadline time . Duration
// Any base labels that are added to this target and its metrics.
// Any base labels that are added to this target and its metrics.
baseLabels model . LabelSet
baseLabels model . LabelSet
client http . Client
}
}
// Furnish a reasonably configured target for querying.
// Furnish a reasonably configured target for querying.
@ -125,6 +126,7 @@ func NewTarget(address string, deadline time.Duration, baseLabels model.LabelSet
address : address ,
address : address ,
Deadline : deadline ,
Deadline : deadline ,
baseLabels : baseLabels ,
baseLabels : baseLabels ,
client : NewDeadlineClient ( deadline ) ,
}
}
scheduler := & healthScheduler {
scheduler := & healthScheduler {
@ -162,75 +164,53 @@ func (t *target) recordScrapeHealth(results chan format.Result, timestamp time.T
func ( t * target ) Scrape ( earliest time . Time , results chan format . Result ) ( err error ) {
func ( t * target ) Scrape ( earliest time . Time , results chan format . Result ) ( err error ) {
now := time . Now ( )
now := time . Now ( )
futureState := t . state
if err = t . scrape ( now , results ) ; err != nil {
t . recordScrapeHealth ( results , now , false )
futureState = UNREACHABLE
} else {
t . recordScrapeHealth ( results , now , true )
futureState = ALIVE
}
defer func ( ) {
t . scheduler . Reschedule ( earliest , futureState )
futureState := t . state
t . state = futureState
switch err {
case nil :
t . recordScrapeHealth ( results , now , true )
futureState = ALIVE
default :
t . recordScrapeHealth ( results , now , false )
futureState = UNREACHABLE
}
t . scheduler . Reschedule ( earliest , futureState )
t . state = futureState
} ( )
done := make ( chan bool )
go func ( start time . Time ) {
defer func ( ) {
ms := float64 ( time . Since ( start ) ) / float64 ( time . Millisecond )
labels := map [ string ] string { address : t . Address ( ) , outcome : success }
if err != nil {
labels [ outcome ] = failure
}
targetOperationLatencies . Add ( labels , ms )
targetOperations . Increment ( labels )
} ( )
defer func ( ) {
return
done <- true
}
} ( )
var resp * http . Response // Don't shadow "err" from the enclosing function.
func ( t * target ) scrape ( timestamp time . Time , results chan format . Result ) ( err error ) {
resp , err = http . Get ( t . Address ( ) )
defer func ( start time . Time ) {
ms := float64 ( time . Since ( start ) ) / float64 ( time . Millisecond )
labels := map [ string ] string { address : t . Address ( ) , outcome : success }
if err != nil {
if err != nil {
return
labels [ outcome ] = failure
}
}
defer resp . Body . Close ( )
targetOperationLatencies . Add ( labels , ms )
targetOperations . Increment ( labels )
processor , err := format . DefaultRegistry . ProcessorForRequestHeader ( resp . Header )
} ( time . Now ( ) )
if err != nil {
return
}
// XXX: This is a wart; we need to handle this more gracefully down the
resp , err := t . client . Get ( t . Address ( ) )
// road, especially once we have service discovery support.
if err != nil {
baseLabels := model . LabelSet { model . InstanceLabel : model . LabelValue ( t . Address ( ) ) }
return
for baseLabel , baseValue := range t . baseLabels {
}
baseLabels [ baseLabel ] = baseValue
defer resp . Body . Close ( )
}
err = processor . Process ( resp . Body , now , baseLabels , results )
processor , err := format . DefaultRegistry . ProcessorForRequestHeader ( resp . Header )
if err != nil {
if err != nil {
return
return
}
}
} ( time . Now ( ) )
select {
// XXX: This is a wart; we need to handle this more gracefully down the
case <- done :
// road, especially once we have service discovery support.
break
baseLabels := model . LabelSet { model . InstanceLabel : model . LabelValue ( t . Address ( ) ) }
case <- time . After ( t . Deadline ) :
for baseLabel , baseValue := range t . baseLabels {
err = fmt . Errorf ( "Target %s exceeded %s deadline." , t , t . Deadline )
baseLabels [ baseLabel ] = baseValue
}
}
return
return processor . Process ( resp . Body , timestamp , baseLabels , results )
}
}
func ( t target ) State ( ) TargetState {
func ( t target ) State ( ) TargetState {