Skip to content

Instantly share code, notes, and snippets.

@dustin
Created December 14, 2012 18:18
Show Gist options
  • Select an option

  • Save dustin/4287420 to your computer and use it in GitHub Desktop.

Select an option

Save dustin/4287420 to your computer and use it in GitHub Desktop.
Based on phone home data, build an extrusion map.
package main
import (
"archive/zip"
"flag"
"log"
"os"
"text/template"
"time"
"code.google.com/p/dsallings-couch-go"
"github.com/dustin/go-humanize"
)
const kml_head = `<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<Style id="win">
<IconStyle><color>01ffffff</color><scale>1</scale></IconStyle>
<LineStyle>
<color>ffff0000</color>
<colorMode>normal</colorMode>
<width>2</width>
</LineStyle>
</Style>
<Style id="lnx">
<IconStyle><color>01ffffff</color><scale>1</scale></IconStyle>
<LineStyle>
<color>ff00ff00</color>
<colorMode>normal</colorMode>
<width>2</width>
</LineStyle>
</Style>
<Style id="mac">
<IconStyle><color>01ff00ff</color><scale>1</scale></IconStyle>
<LineStyle>
<color>ffff00ff</color>
<colorMode>normal</colorMode>
<width>2</width>
</LineStyle>
</Style>
<Style id="sol">
<IconStyle><color>01ffffff</color><scale>1</scale></IconStyle>
<LineStyle>
<color>ff00ffff</color>
<colorMode>normal</colorMode>
<width>2</width>
</LineStyle>
</Style>
<Style id="mixed">
<IconStyle><color>01ffffff</color><scale>1</scale></IconStyle>
<LineStyle>
<color>ff0000ff</color>
<colorMode>normal</colorMode>
<width>2</width>
</LineStyle>
</Style>
`
const kml_point_source = `<Placemark>
<visibility>1</visibility>
<name>{{.NumNodes}} node {{.LongOS}} cluster</name>
<description><![CDATA[First seen on {{.First}}.
Has {{.PrettySize}} RAM
over the whole cluster. Currently on version {{.Version}}.]]>
</description>
<styleUrl>#{{.OS}}</styleUrl>
<Point>
<extrude>1</extrude>
<altitudeMode>relativeToGround</altitudeMode>
<coordinates>{{.Longitude}},{{.Latitude}},{{.Altitude}}</coordinates>
</Point>
</Placemark>
`
var kml_point = template.New("point")
const kml_tail = `</Document></kml>`
func init() {
var err error
kml_point, err = kml_point.Parse(kml_point_source)
if err != nil {
log.Panicf("Error parsing template: %v", err)
}
}
type ResultRow struct {
Value struct {
RamMax int64
OS string
NumNodes int
First string
Version string
Longitude float64
Latitude float64
PrettySize string
Altitude int
LongOS string
}
}
type Results struct {
Rows []ResultRow
}
func maybefatal(msg string, err error) {
if err != nil {
log.Fatalf("%s: %v", msg, err)
}
}
func lengthen(o string) string {
switch o {
case "lnx":
o = "Linux"
case "mac":
o = "Mac"
case "win":
o = "Windows"
}
return o
}
func main() {
dburl := flag.String("couch", "http://localhost:5984/cbstats",
"Stats location.")
filename := flag.String("kmz", "data.kmz", "File to create.")
days := flag.Int("days", 30, "Number of days to include")
minNodes := flag.Int("nodes", 3,
"Minimum number of nodes a cluster must have")
flag.Parse()
d := time.Now().Add(time.Hour * -24 * time.Duration(*days))
startkey := d.Format("2006-01-02")
db, err := couch.Connect(*dburl)
if err != nil {
log.Fatalf("Error connecting to couchdb: %v", err)
}
query_results := Results{}
err = db.Query("_design/geo/_view/vitals",
map[string]interface{}{"startkey": startkey},
&query_results)
maybefatal("Error querying couchdb", err)
f, err := os.Create(*filename + ".tmp")
maybefatal("Error creating file", err)
defer f.Close()
z := zip.NewWriter(f)
defer z.Close()
dockml, err := z.Create("doc.kml")
maybefatal("Error creating kml zip thing", err)
dockml.Write([]byte(kml_head))
for _, r := range query_results.Rows {
v := r.Value
if v.NumNodes >= *minNodes {
v.LongOS = lengthen(v.OS)
v.PrettySize = humanize.Bytes(uint64(v.RamMax))
v.Altitude = v.NumNodes * 50000
kml_point.Execute(dockml, v)
}
}
dockml.Write([]byte(kml_tail))
os.Rename(*filename+".tmp", *filename)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment