diff --git a/README.md b/README.md index 86d7737..28cd884 100644 --- a/README.md +++ b/README.md @@ -14,10 +14,18 @@ import "go.ajitem.com/zapdriver" This package provides three building blocks to support the full array of structured logging capabilities of Stackdriver: -* [Special purpose logging fields](#special-purpose-logging-fields) -* [Pre-configured Stackdriver-optimized encoder](#pre-configured-stackdriver-optimized-encoder) -* [Custom Stackdriver Zap core](#custom-stackdriver-zap-core) -* [Using Error Reporting](#using-error-reporting) +- [:zap: Zapdriver](#zap-zapdriver) + - [Usage](#usage) + - [Special purpose logging fields](#special-purpose-logging-fields) + - [HTTP](#http) + - [Label](#label) + - [SourceLocation](#sourcelocation) + - [Operation](#operation) + - [TraceContext](#tracecontext) + - [Pre-configured Stackdriver-optimized encoder](#pre-configured-stackdriver-optimized-encoder) + - [Custom Stackdriver Zap core](#custom-stackdriver-zap-core) + - [Using Error Reporting](#using-error-reporting) + - [Reporting errors manually](#reporting-errors-manually) The above components can be used separately, but to start, you can create a new Zap logger with all of the above included: @@ -93,7 +101,7 @@ one or the other will be omitted if `nil` is passed in. Note that there are some fields that are not populated by either the request or response object, and need to be set manually: -* `ServerIP string` + * `Latency string` * `CacheLookup bool` * `CacheHit bool` diff --git a/http.go b/http.go index 441e585..b5d294f 100644 --- a/http.go +++ b/http.go @@ -117,24 +117,49 @@ func NewHTTP(req *http.Request, res *http.Response) *HTTPPayload { RemoteIP: req.RemoteAddr, Referer: req.Referer(), Protocol: req.Proto, + ServerIP: req.Host, } if req.URL != nil { sdreq.RequestURL = req.URL.String() } + // Count the requestSize: both headers and body + var requestSize int64 + + for hKey, hValue := range req.Header { + requestSize += int64(len([]byte(hKey))) + for _, v := range hValue { + requestSize += int64(len([]byte(v))) + } + } + buf := &bytes.Buffer{} if req.Body != nil { n, _ := io.Copy(buf, req.Body) // nolint: gas - sdreq.RequestSize = strconv.FormatInt(n, 10) + requestSize += n + } + + sdreq.RequestSize = strconv.FormatInt(requestSize, 10) + + // Count the response size, both headers and body + var responseSize int64 + + for hKey, hValue := range res.Header { + responseSize += int64(len([]byte(hKey))) + for _, v := range hValue { + responseSize += int64(len([]byte(v))) + } } if res.Body != nil { buf.Reset() n, _ := io.Copy(buf, res.Body) // nolint: gas - sdreq.ResponseSize = strconv.FormatInt(n, 10) + responseSize += n } + sdreq.ResponseSize = strconv.FormatInt(responseSize, 10) + return sdreq } @@ -142,8 +167,8 @@ func NewHTTP(req *http.Request, res *http.Response) *HTTPPayload { func (req HTTPPayload) MarshalLogObject(enc zapcore.ObjectEncoder) error { enc.AddString("requestMethod", req.RequestMethod) enc.AddString("requestUrl", req.RequestURL) - enc.AddString("requestSize", req.RequestSize) enc.AddInt("status", req.Status) + enc.AddString("requestSize", req.RequestSize) enc.AddString("responseSize", req.ResponseSize) enc.AddString("userAgent", req.UserAgent) enc.AddString("remoteIp", req.RemoteIP) @@ -153,8 +178,11 @@ func (req HTTPPayload) MarshalLogObject(enc zapcore.ObjectEncoder) error { enc.AddBool("cacheLookup", req.CacheLookup) enc.AddBool("cacheHit", req.CacheHit) enc.AddBool("cacheValidatedWithOriginServer", req.CacheValidatedWithOriginServer) - enc.AddString("cacheFillBytes", req.CacheFillBytes) enc.AddString("protocol", req.Protocol) + if req.CacheFillBytes != "" { + enc.AddString("cacheFillBytes", req.CacheFillBytes) + } + return nil } diff --git a/http_test.go b/http_test.go index 42aa1cb..ebc6938 100644 --- a/http_test.go +++ b/http_test.go @@ -35,61 +35,61 @@ func TestNewHTTP(t *testing.T) { "empty": { nil, nil, - &zapdriver.HTTPPayload{}, + &zapdriver.HTTPPayload{RequestSize: "0", ResponseSize: "0"}, }, "RequestMethod": { &http.Request{Method: "GET"}, nil, - &zapdriver.HTTPPayload{RequestMethod: "GET"}, + &zapdriver.HTTPPayload{RequestMethod: "GET", RequestSize: "0", ResponseSize: "0"}, }, "Status": { nil, &http.Response{StatusCode: 404}, - &zapdriver.HTTPPayload{Status: 404}, + &zapdriver.HTTPPayload{Status: 404, RequestSize: "0", ResponseSize: "0"}, }, "UserAgent": { &http.Request{Header: http.Header{"User-Agent": []string{"hello world"}}}, nil, - &zapdriver.HTTPPayload{UserAgent: "hello world"}, + &zapdriver.HTTPPayload{UserAgent: "hello world", RequestSize: "21", ResponseSize: "0"}, }, "RemoteIP": { &http.Request{RemoteAddr: "127.0.0.1"}, nil, - &zapdriver.HTTPPayload{RemoteIP: "127.0.0.1"}, + &zapdriver.HTTPPayload{RemoteIP: "127.0.0.1", RequestSize: "0", ResponseSize: "0"}, }, "Referrer": { &http.Request{Header: http.Header{"Referer": []string{"hello universe"}}}, nil, - &zapdriver.HTTPPayload{Referer: "hello universe"}, + &zapdriver.HTTPPayload{Referer: "hello universe", RequestSize: "21", ResponseSize: "0"}, }, "Protocol": { &http.Request{Proto: "HTTP/1.1"}, nil, - &zapdriver.HTTPPayload{Protocol: "HTTP/1.1"}, + &zapdriver.HTTPPayload{Protocol: "HTTP/1.1", RequestSize: "0", ResponseSize: "0"}, }, "RequestURL": { &http.Request{URL: &url.URL{Host: "example.com", Scheme: "https"}}, nil, - &zapdriver.HTTPPayload{RequestURL: "https://example.com"}, + &zapdriver.HTTPPayload{RequestURL: "https://example.com", RequestSize: "0", ResponseSize: "0"}, }, "RequestSize": { &http.Request{Body: ioutil.NopCloser(strings.NewReader("12345"))}, nil, - &zapdriver.HTTPPayload{RequestSize: "5"}, + &zapdriver.HTTPPayload{RequestSize: "5", ResponseSize: "0"}, }, "ResponseSize": { nil, &http.Response{Body: ioutil.NopCloser(strings.NewReader("12345"))}, - &zapdriver.HTTPPayload{ResponseSize: "5"}, + &zapdriver.HTTPPayload{ResponseSize: "5", RequestSize: "0"}, }, "simple request": { @@ -101,19 +101,21 @@ func TestNewHTTP(t *testing.T) { RemoteIP: "192.0.2.1:1234", Protocol: "HTTP/1.1", RequestURL: "/", + ResponseSize: "0", + ServerIP: "example.com", }, }, "simple response": { nil, &http.Response{Body: ioutil.NopCloser(strings.NewReader("12345")), StatusCode: 404}, - &zapdriver.HTTPPayload{ResponseSize: "5", Status: 404}, + &zapdriver.HTTPPayload{RequestSize: "0", ResponseSize: "5", Status: 404}, }, "request & response": { &http.Request{Method: "POST", Proto: "HTTP/1.1"}, &http.Response{StatusCode: 200}, - &zapdriver.HTTPPayload{RequestMethod: "POST", Protocol: "HTTP/1.1", Status: 200}, + &zapdriver.HTTPPayload{RequestMethod: "POST", Protocol: "HTTP/1.1", Status: 200, RequestSize: "0", ResponseSize: "0"}, }, }