| OLD | NEW |
| 1 // Prober is an HTTP prober that periodically sends out HTTP requests to specifi
ed | 1 // Prober is an HTTP prober that periodically sends out HTTP requests to specifi
ed |
| 2 // endpoints and reports if the returned results match the expectations. The res
ults | 2 // endpoints and reports if the returned results match the expectations. The res
ults |
| 3 // of the probe, including latency, are recored in InfluxDB using the Carbon pro
tocol. | 3 // of the probe, including latency, are recored in InfluxDB using the Carbon pro
tocol. |
| 4 // See probers.json as an example of the config file format. | 4 // See probers.json as an example of the config file format. |
| 5 package main | 5 package main |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "encoding/json" | 8 "encoding/json" |
| 9 "flag" | 9 "flag" |
| 10 "fmt" | 10 "fmt" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 var ( | 27 var ( |
| 28 graphiteServer = flag.String("graphite_server", "localhost:2003", "Where
is Graphite metrics ingestion server running.") | 28 graphiteServer = flag.String("graphite_server", "localhost:2003", "Where
is Graphite metrics ingestion server running.") |
| 29 config = flag.String("config", "probers.json,buildbots.json", "C
omma separated names of prober config files.") | 29 config = flag.String("config", "probers.json,buildbots.json", "C
omma separated names of prober config files.") |
| 30 prefix = flag.String("prefix", "prober", "Prefix to add to all p
rober values sent to Graphite.") | 30 prefix = flag.String("prefix", "prober", "Prefix to add to all p
rober values sent to Graphite.") |
| 31 useMetadata = flag.Bool("use_metadata", true, "Load sensitive values
from metadata not from flags.") | 31 useMetadata = flag.Bool("use_metadata", true, "Load sensitive values
from metadata not from flags.") |
| 32 apikey = flag.String("apikey", "", "The API Key used to make iss
ue tracker requests. Only for local testing.") | 32 apikey = flag.String("apikey", "", "The API Key used to make iss
ue tracker requests. Only for local testing.") |
| 33 runEvery = flag.Duration("run_every", 1*time.Minute, "How often to
run the probes.") | 33 runEvery = flag.Duration("run_every", 1*time.Minute, "How often to
run the probes.") |
| 34 | 34 |
| 35 // bodyTesters is a mapping of names to functions that test response bod
ies. | 35 // bodyTesters is a mapping of names to functions that test response bod
ies. |
| 36 bodyTesters = map[string]BodyTester{ | 36 bodyTesters = map[string]BodyTester{ |
| 37 » » "buildbotJSON": testBuildbotJSON, | 37 » » "buildbotJSON": testBuildbotJSON, |
| 38 » » "skfiddleJSONGood": skfiddleJSONGood, | 38 » » "ctfeChromiumPerfParametersJSON": ctfeChromiumPerfParametersJSON
, |
| 39 » » "skfiddleJSONBad": skfiddleJSONBad, | 39 » » "ctfeGetTasksJSON": ctfeGetTasksJSON, |
| 40 » » "validJSON": validJSON, | 40 » » "ctfeGetTasksNonEmptyJSON": ctfeGetTasksNonEmptyJSON, |
| 41 » » "ctfeRevDataJSON": ctfeRevDataJSON, |
| 42 » » "skfiddleJSONGood": skfiddleJSONGood, |
| 43 » » "skfiddleJSONBad": skfiddleJSONBad, |
| 44 » » "validJSON": validJSON, |
| 41 } | 45 } |
| 42 ) | 46 ) |
| 43 | 47 |
| 44 const ( | 48 const ( |
| 45 TIMEOUT = time.Duration(5 * time.Second) | 49 TIMEOUT = time.Duration(5 * time.Second) |
| 46 ISSUE_TRACKER_PERIOD = 15 * time.Minute | 50 ISSUE_TRACKER_PERIOD = 15 * time.Minute |
| 47 ) | 51 ) |
| 48 | 52 |
| 49 // BodyTester tests the response body from a probe and returns true if it passes
all tests. | 53 // BodyTester tests the response body from a probe and returns true if it passes
all tests. |
| 50 type BodyTester func(io.Reader) bool | 54 type BodyTester func(io.Reader) bool |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 } | 168 } |
| 165 glog.Infof("%#v", s) | 169 glog.Infof("%#v", s) |
| 166 return len(s.CompileErrors) == 0 | 170 return len(s.CompileErrors) == 0 |
| 167 } | 171 } |
| 168 | 172 |
| 169 // skfiddleJSONBad tests that the compile completed w/error. | 173 // skfiddleJSONBad tests that the compile completed w/error. |
| 170 func skfiddleJSONBad(r io.Reader) bool { | 174 func skfiddleJSONBad(r io.Reader) bool { |
| 171 return !skfiddleJSONGood(r) | 175 return !skfiddleJSONGood(r) |
| 172 } | 176 } |
| 173 | 177 |
| 178 // decodeJSONObject reads a JSON object from r and returns the resulting object.
Returns nil if the |
| 179 // JSON is invalid or can't be decoded to a map[string]interface{}. |
| 180 func decodeJSONObject(r io.Reader) map[string]interface{} { |
| 181 var obj map[string]interface{} |
| 182 if json.NewDecoder(r).Decode(&obj) != nil { |
| 183 return nil |
| 184 } |
| 185 return obj |
| 186 } |
| 187 |
| 188 // hasKeys tests that the given decoded JSON object has at least the provided ke
ys. If obj is nil, |
| 189 // returns false. |
| 190 func hasKeys(obj map[string]interface{}, keys []string) bool { |
| 191 if obj == nil { |
| 192 return false |
| 193 } |
| 194 for _, key := range keys { |
| 195 if _, ok := obj[key]; !ok { |
| 196 return false |
| 197 } |
| 198 } |
| 199 return true |
| 200 } |
| 201 |
| 202 // ctfeChromiumPerfParametersJSON tests that the response contains valid JSON wi
th the keys |
| 203 // expected by ct/templates/chromium_perf.html. |
| 204 func ctfeChromiumPerfParametersJSON(r io.Reader) bool { |
| 205 return hasKeys(decodeJSONObject(r), []string{"benchmarks", "platforms"}) |
| 206 } |
| 207 |
| 208 // ctfeGetTasksJSONObject tests that obj has the attributes expected by |
| 209 // ct/res/imp/pending-tasks-sk.html and ct/res/imp/*-runs-sk.html. Returns false
if obj is nil. |
| 210 func ctfeGetTasksJSONObject(obj map[string]interface{}) bool { |
| 211 if !hasKeys(obj, []string{"data", "permissions", "pagination"}) { |
| 212 return false |
| 213 } |
| 214 data, dataOk := obj["data"].([]interface{}) |
| 215 permissions, permissionsOk := obj["permissions"].([]interface{}) |
| 216 if !dataOk || !permissionsOk || len(data) != len(permissions) { |
| 217 return false |
| 218 } |
| 219 // TODO(benjaminwagner): Other checks required? |
| 220 return true |
| 221 } |
| 222 |
| 223 // ctfeGetTasksJSON tests that the response contains valid JSON and satisfies |
| 224 // ctfeGetTasksJSONObject. |
| 225 func ctfeGetTasksJSON(r io.Reader) bool { |
| 226 return ctfeGetTasksJSONObject(decodeJSONObject(r)) |
| 227 } |
| 228 |
| 229 // ctfeGetTasksNonEmptyJSON tests the same as ctfeGetTasksJSON and also checks t
hat there is at |
| 230 // least one task present. |
| 231 func ctfeGetTasksNonEmptyJSON(r io.Reader) bool { |
| 232 obj := decodeJSONObject(r) |
| 233 if !ctfeGetTasksJSONObject(obj) { |
| 234 return false |
| 235 } |
| 236 data := obj["data"].([]interface{}) |
| 237 if len(data) < 1 { |
| 238 return false |
| 239 } |
| 240 return true |
| 241 } |
| 242 |
| 243 // ctfeRevDataJSON tests that the response contains valid JSON with the keys exp
ected by |
| 244 // ct/res/imp/chromium-builds-sk.html. |
| 245 func ctfeRevDataJSON(r io.Reader) bool { |
| 246 return hasKeys(decodeJSONObject(r), []string{"commit", "author", "commit
ter"}) |
| 247 } |
| 248 |
| 174 // monitorIssueTracker reads the counts for all the types of issues in the skia | 249 // monitorIssueTracker reads the counts for all the types of issues in the skia |
| 175 // issue tracker (code.google.com/p/skia) and stuffs the counts into Graphite. | 250 // issue tracker (code.google.com/p/skia) and stuffs the counts into Graphite. |
| 176 func monitorIssueTracker() { | 251 func monitorIssueTracker() { |
| 177 c := &http.Client{ | 252 c := &http.Client{ |
| 178 Transport: &http.Transport{ | 253 Transport: &http.Transport{ |
| 179 Dial: dialTimeout, | 254 Dial: dialTimeout, |
| 180 }, | 255 }, |
| 181 } | 256 } |
| 182 | 257 |
| 183 if *useMetadata { | 258 if *useMetadata { |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 Transport: &http.Transport{ | 389 Transport: &http.Transport{ |
| 315 Dial: dialTimeout, | 390 Dial: dialTimeout, |
| 316 }, | 391 }, |
| 317 } | 392 } |
| 318 probeOneRound(cfg, c) | 393 probeOneRound(cfg, c) |
| 319 for _ = range time.Tick(*runEvery) { | 394 for _ = range time.Tick(*runEvery) { |
| 320 probeOneRound(cfg, c) | 395 probeOneRound(cfg, c) |
| 321 liveness.Update() | 396 liveness.Update() |
| 322 } | 397 } |
| 323 } | 398 } |
| OLD | NEW |