Created
January 13, 2016 16:28
-
-
Save diyan/e34474fc635770918cb6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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