Skip to content

Instantly share code, notes, and snippets.

@diyan
Created January 13, 2016 16:28
Show Gist options
  • Save diyan/e34474fc635770918cb6 to your computer and use it in GitHub Desktop.
Save diyan/e34474fc635770918cb6 to your computer and use it in GitHub Desktop.
package main
import (
"encoding/csv"
"log"
"strings"
"strconv"
"net/http"
"github.com/gosuri/uitable"
"fmt"
"github.com/cheggaaa/pb"
"sync"
)
type AccessRow struct {
Visitors int
Hits int
Percent float64
Bandwidth string
Protocol string
Method string
Requests string
StatusCode int
Readiness string
XCacheable string
ContentType string
}
var accessStats string = `Visitors Hits % Bandwidth Protocol Method Requests
4 85973 1.51% 0.0 B HTTP/1.1 HEAD /
705 32430 0.57% 891.64 KiB HTTP/1.1 GET /
49 25008 0.44% 2.89 GiB HTTP/1.1 GET /da
...
`
func main() {
r := csv.NewReader(strings.NewReader(accessStats))
r.Comma = '\t'
csvRows, err := r.ReadAll()
if err != nil {
log.Fatal(err)
}
accessRows := []*AccessRow{}
for i, csvRow := range csvRows {
if i == 0 {
continue
}
visitors, _ := strconv.Atoi(csvRow[0])
hits, _ := strconv.Atoi(csvRow[1])
percent, _ := strconv.ParseFloat(strings.TrimSuffix(csvRow[2], "%"), 64)
accessRow := &AccessRow{
Visitors: visitors, Hits: hits, Percent: percent,
Bandwidth: csvRow[3], Protocol: csvRow[4], Method: csvRow[5],
Requests: csvRow[6],
}
accessRows = append(accessRows, accessRow)
}
fillVarnishReadiness(accessRows)
table := uitable.New()
table.AddRow(
"Visitors", "Hits", "%", "Bandwidth", "Protocol", "Method", "Requests",
"StatusCode", "Readiness", "X-Cacheable", "Content-Type")
for _, row := range accessRows {
table.AddRow(
row.Visitors, row.Hits, row.Percent, row.Bandwidth, row.Protocol,
row.Method, row.Requests, row.StatusCode, row.Readiness,
row.XCacheable, row.ContentType,
)
}
fmt.Println(table)
}
func fillVarnishReadiness(accessRows []*AccessRow) {
var wg sync.WaitGroup
wg.Add(len(accessRows))
bar := pb.New(len(accessRows)).SetMaxWidth(80).Start()
for _, row := range accessRows {
go func(row *AccessRow) {
defer wg.Done()
defer bar.Increment()
var res *http.Response
var err error
if row.Method == "HEAD" {
res, err = http.Head("http://example.com" + row.Requests)
} else if row.Method == "GET" {
res, err = http.Get("http://example.com" + row.Requests)
} else {
row.Readiness = "UNKNOWN"
row.XCacheable = "UNKNOWN"
row.ContentType = "UNKNOWN"
return
}
if err != nil {
log.Print(err)
row.Readiness = "ERROR"
row.XCacheable = "ERROR"
return
}
row.StatusCode = res.StatusCode
row.Readiness = res.Header.Get("X-Cache")
if row.Readiness == "" {
row.Readiness = "ABSENT"
}
row.XCacheable = res.Header.Get("X-Cacheable")
row.ContentType = res.Header.Get("Content-Type")
if res.Header.Get("Content-Type") == "application/octet-stream" {
row.Readiness = "BINARY_NO_CACHE"
}
if res.Header.Get("Cache-Control") == "private, max-age=3600" {
row.Readiness = "BROWSER_CACHE_1H"
}
}(row)
}
wg.Wait()
bar.Finish()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment