Index: android_stats/go/android_stats/main.go |
diff --git a/android_stats/go/android_stats/main.go b/android_stats/go/android_stats/main.go |
new file mode 100644 |
index 0000000000000000000000000000000000000000..0777a717d5dc6da0ac25e2f84c72b37684d4dca7 |
--- /dev/null |
+++ b/android_stats/go/android_stats/main.go |
@@ -0,0 +1,98 @@ |
+/* |
+ Periodically report the status of all attached Android devices to InfluxDB. |
+*/ |
+ |
+package main |
+ |
+import ( |
+ "encoding/json" |
+ "flag" |
+ "reflect" |
+ "time" |
+ |
+ "github.com/rcrowley/go-metrics" |
+ "github.com/skia-dev/glog" |
+ "go.skia.org/infra/go/common" |
+ "go.skia.org/infra/go/exec" |
+) |
+ |
+var ( |
+ frequency = flag.String("frequency", "1m", "How often to send data.") |
+ graphiteServer = flag.String("graphite server", "localhost:2003", "Where is Graphite metrics ingestion server running.") |
jcgregorio
2015/12/02 16:41:05
Right now we don't have a way to push data into in
|
+ statsScript = flag.String("stats_script", "", "Script to run which generates stats.") |
+) |
+ |
+// parseAndReportStats drills down recursively until it hits a non-map value, |
+// then reports that value with the metric name as the path of keys to that |
+// value, eg. "Nexus_5X.002e3da61560d3d4.battery.level". |
+func parseAndReportStats(name string, stats map[string]interface{}) { |
+ for k, v := range stats { |
+ measurement := name + "." + k |
+ kind := reflect.ValueOf(v).Kind() |
+ if kind == reflect.Map { |
+ parseAndReportStats(measurement, v.(map[string]interface{})) |
+ } else { |
+ glog.Infof("%s = %v", measurement, v) |
+ metrics.GetOrRegisterGaugeFloat64(measurement, metrics.DefaultRegistry).Update(v.(float64)) |
+ } |
+ } |
+} |
+ |
+// generateStats runs the statistics generation script, parses its output, and |
+// reports the data into InfluxDB. |
+// |
+// The script produces data in this format: |
+// { |
+// "Nexus_5X": { |
+// "002e3da61560d3d4": { |
+// "battery": { |
+// "ac": 0, |
+// "health": 2, |
+// "level": 100, |
+// "max": 500000, |
+// "present": 1, |
+// "status": 5, |
+// "temp": 282, |
+// "usb": 1, |
+// "voltage": 4311, |
+// "wireless": 0 |
+// }, |
+// "temperature": 28.0 |
+// } |
+// } |
+// } |
+// |
+func generateStats() error { |
+ output, err := exec.RunSimple(*statsScript) |
+ if err != nil { |
+ return err |
+ } |
+ |
+ res := map[string]interface{}{} |
+ if err := json.Unmarshal([]byte(output), &res); err != nil { |
+ return err |
+ } |
+ |
+ parseAndReportStats("androidstats", res) |
+ |
+ return nil |
+} |
+ |
+func main() { |
+ defer common.LogPanic() |
+ common.InitWithMetrics("android_stats", graphiteServer) |
+ |
+ pollFreq, err := time.ParseDuration(*frequency) |
+ if err != nil { |
+ glog.Fatalf("Invalid value for frequency %q: %s", *frequency, err) |
+ } |
+ |
+ if err := generateStats(); err != nil { |
+ glog.Fatal(err) |
+ } |
+ for _ = range time.Tick(pollFreq) { |
+ if err := generateStats(); err != nil { |
+ glog.Error(err) |
+ } |
+ } |
+} |