func perfLogSaver() { f, err := os.OpenFile(perflogFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil { log.Error("Unable to open stats file: %v", err) return } defer f.Close() enc := json.NewEncoder(f) for entry := range perflogChan { err = enc.Encode(entry) if err != nil { log.Error("PerfLog error: %v", err) } } }
func runWebUI(addr string, perfData []perflog.PerfLogEntry) { m := staticbin.Classic(gopnikwebstatic.Asset) m.Map(log.New(os.Stderr, "", log.LstdFlags)) m.Use(rendergold.Renderer(rendergold.Options{Asset: Asset})) m.Get("/", func(r rendergold.Render) { totalStats := getStats(perfData, nil) var zoomsStats []zoomStats zrng := getZooms(perfData) for z := zrng.MinZoom; z <= zrng.MaxZoom; z++ { zoomsStats = append(zoomsStats, zoomStats{ Zoom: z, Stats: getStats(perfData, &z), }) } r.HTML( http.StatusOK, "index", map[string]interface{}{ "Page": "Results", "TotalStats": totalStats, "ZoomsStats": zoomsStats, }, ) }) m.Get("/heatmap", func(r rendergold.Render) { r.HTML( http.StatusOK, "heatmap", map[string]interface{}{ "Page": "Heat", }, ) }) m.Get("/heattiles_zooms", func(res http.ResponseWriter) { var zooms struct { Min uint64 Max uint64 } if len(perfData) > 0 { zooms.Min = perfData[0].Coord.Zoom zooms.Max = perfData[0].Coord.Zoom for i := 1; i < len(perfData); i++ { zoom := perfData[i].Coord.Zoom if zoom < zooms.Min { zooms.Min = zoom } if zoom > zooms.Max { zooms.Max = zoom } } } enc := json.NewEncoder(res) if err := enc.Encode(zooms); err != nil { http.Error(res, err.Error(), 500) return } }) m.Get("/heattiles/:zoom_orig/:zoom/:x/:y.png", func(params martini.Params, res http.ResponseWriter) { var coord gopnik.TileCoord coord.Size = 1 _, err := fmt.Sscan(params["zoom"], &coord.Zoom) if err != nil { http.Error(res, err.Error(), 400) return } _, err = fmt.Sscan(params["x"], &coord.X) if err != nil { http.Error(res, err.Error(), 400) return } _, err = fmt.Sscan(params["y"], &coord.Y) if err != nil { http.Error(res, err.Error(), 400) return } var zoomOrig uint64 _, err = fmt.Sscan(params["zoom_orig"], &zoomOrig) if err != nil { http.Error(res, err.Error(), 400) return } tile, err := genPerfTile(perfData, coord, zoomOrig) if err != nil { http.Error(res, err.Error(), 500) return } res.Header().Set("Content-Type", "image/png") res.Write(tile) }) log.Printf("Starting WebUI on %v", addr) log.Fatal(http.ListenAndServe(addr, m)) }
func main() { cfg := gopnikprerenderlib.PrerenderGlobalConfig{ Prerender: gopnikprerenderlib.PrerenderConfig{ UIAddr: ":8088", DebugAddr: ":8098", }, CommonConfig: app.CommonConfig{ MetaSize: 8, TileSize: 256, }, } app.App.Configure("Prerender", &cfg) zooms, err := parseZoom(*zoom) if err != nil { log.Fatalf("Invalid zoom: %v", err) } var tags []string if *tagsF != "" { tags = strings.Split(*tagsF, ",") } var coords []gopnik.TileCoord if *doAppend { f, err := os.Open(*planFile) if err != nil { if !strings.Contains(err.Error(), "no such file or directory") { log.Fatalf("Failed to open plan file: %v", err) } } else { dec := json.NewDecoder(f) err = dec.Decode(&coords) if err != nil { log.Fatalf("Failed to parse plan file: %v", err) } } } if *allWorld { for _, zoom := range zooms { bbox := [4]float64{-85 /*latMin*/, 85 /*latMax*/, -180 /*lonMin*/, 180 /*lonMax*/} zoomCoords, err := genCoords(bbox, zoom) if err != nil { log.Fatal(err) } // append tags for i := 0; i < len(zoomCoords); i++ { zoomCoords[i].Tags = tags } coords = append(coords, zoomCoords...) } } else { if *csvFile != "" { csvCoords, err := readCSVFile(*csvFile, zooms) if err != nil { log.Fatal(err) } // append tags for i := 0; i < len(csvCoords); i++ { csvCoords[i].Tags = tags } coords = append(coords, csvCoords...) } for _, zoom := range zooms { flagCoords, err := latLon(zoom) if err != nil { log.Fatal(err) } // append tags for i := 0; i < len(flagCoords); i++ { flagCoords[i].Tags = tags } coords = append(coords, flagCoords...) } } if *subtractPerflog != "" { sinceT, err := parseTime(*subtractPerflogSince) if err != nil { log.Fatalf("Invalid since param: %v", err) } untilT, err := parseTime(*subtractPerflogUntil) if err != nil { log.Fatalf("Invalid unitl param: %v", err) } perfData, err := perflog.LoadPerf(*subtractPerflog, sinceT, untilT) if err != nil { log.Fatalf("Failed to load performance log: %v", err) } coords = subtractPerflogItems(coords, perfData) } if *shuffle { rand.Seed(time.Now().UnixNano()) shuffleCoords(coords) } fout, err := os.OpenFile(*planFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666) if err != nil { log.Fatalf("Failed to open plan file: %v", err) } enc := json.NewEncoder(fout) err = enc.Encode(coords) if err != nil { log.Fatalf("Failed to encode plan file: %v", err) } }