Skip to content

Commit

Permalink
gkelog: Make ordering of headers and query params deterministic
Browse files Browse the repository at this point in the history
Fixes gkelog TestRequest
  • Loading branch information
justinruggles committed Dec 19, 2018
1 parent d369dc3 commit 9d211b9
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 30 deletions.
79 changes: 50 additions & 29 deletions emitter/gkelog/emitter.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net/http"
"os"
"path"
"sort"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -160,6 +161,22 @@ func jsonTrace(ctx context.Context, w *bytes.Buffer) {
}
}

func sortedMapKeys(m map[string][]string) []string {
out := make([]string, 0, len(m))
for k := range m {
out = append(out, k)
}
sort.Strings(out)
return out
}

var skipHeaders = map[string]bool{
"Referer": true,
"Referrer": true,
"User-Agent": true,
"X-Cloud-Trace-Context": true,
}

func jsonHTTPRequest(ctx context.Context, w *bytes.Buffer) {
var (
request *http.Request
Expand Down Expand Up @@ -234,53 +251,57 @@ func jsonHTTPRequest(ctx context.Context, w *bytes.Buffer) {
return
}

var headers []string
first := true
for k, v := range request.Header {
switch http.CanonicalHeaderKey(k) {
case "Referer", "Referrer", "User-Agent", "X-Cloud-Trace-Context":
default:
if len(v) > 0 {
if !first {
headerKeys := sortedMapKeys(request.Header)
if len(headerKeys) > 0 {
jsonKey(w, "httpHeaders")
w.WriteByte('{')
i := 0
for _, h := range headerKeys {
if skipHeaders[h] {
continue
}
if i > 0 {
w.WriteString(", ")
}
jsonKey(w, h)
v := request.Header[h]
if len(v) > 1 {
w.WriteByte('[')
}
for j, v0 := range v {
if j > 0 {
w.WriteString(", ")
} else {
first = false
}
headers = append(headers, http.CanonicalHeaderKey(k), v[0])
jsonString(w, v0)
}
}
}
if len(headers) > 0 {
jsonKey(w, "httpHeaders")
w.WriteByte('{')
for i := 0; i < len(headers); i += 2 {
jsonKey(w, headers[i])
jsonString(w, headers[i+1])
if len(v) > 1 {
w.WriteByte(']')
}
i++
}
w.WriteByte('}')
w.WriteString(", ")
}

query := request.URL.Query()
if len(query) > 0 {
queryKeys := sortedMapKeys(query)
if len(queryKeys) > 0 {
jsonKey(w, "httpQuery")
w.WriteByte('{')
first = true
for k, v := range query {
if !first {
for i, q := range queryKeys {
if i > 0 {
w.WriteString(", ")
} else {
first = false
}
jsonKey(w, k)
jsonKey(w, q)
v := query[q]
if len(v) > 1 {
w.WriteByte('[')
}
for i, v0 := range v {
jsonString(w, v0)
if i < len(v)-1 {
for j, v0 := range v {
if j > 0 {
w.WriteString(", ")
}
jsonString(w, v0)
}
if len(v) > 1 {
w.WriteByte(']')
Expand Down
3 changes: 2 additions & 1 deletion emitter/gkelog/emitter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,12 @@ func TestRequest(t *testing.T) {
req.Header.Set("Referer", "https://vimeo.com")
req.Header.Set("X-Cloud-Trace-Context", "a2fbf27a2ed90077e0d4af0e40a241f9/12690385211238481741")
req.Header.Set("Content-Type", "text/plain")
req.Header.Set("Dnt", "1")
ctx = WithRequest(ctx, req)

l.Print(ctx, "test")

want := `{"time":"0001-01-01T00:00:00Z", "httpRequest":{"requestMethod":"GET", "requestUrl":"/test/endpoint?q=1&c=pink", "userAgent":"curl/7.54.0", "referer":"https://vimeo.com"}, "httpHeaders":{"Content-Type":"text/plain"}, "httpQuery":{"q":"1", "c":"pink"}, "logging.googleapis.com/trace":"a2fbf27a2ed90077e0d4af0e40a241f9", "logging.googleapis.com/spanId":"b01d4e1cf2bd7f4d", "message":"test"}` + "\n"
want := `{"time":"0001-01-01T00:00:00Z", "httpRequest":{"requestMethod":"GET", "requestUrl":"/test/endpoint?q=1&c=pink", "userAgent":"curl/7.54.0", "referer":"https://vimeo.com"}, "httpHeaders":{"Content-Type":"text/plain", "Dnt":"1"}, "httpQuery":{"c":"pink", "q":"1"}, "logging.googleapis.com/trace":"a2fbf27a2ed90077e0d4af0e40a241f9", "logging.googleapis.com/spanId":"b01d4e1cf2bd7f4d", "message":"test"}` + "\n"
got := b.String()
if got != want {
t.Errorf("got:\n%s\nwant:\n%s", got, want)
Expand Down

0 comments on commit 9d211b9

Please sign in to comment.