Add http request scheme to logger
This commit is contained in:
parent
7c430e5c9d
commit
1c764052f7
5 changed files with 71 additions and 3 deletions
|
@ -195,6 +195,7 @@ accessLog:
|
||||||
| `RequestMethod` | The HTTP method. |
|
| `RequestMethod` | The HTTP method. |
|
||||||
| `RequestPath` | The HTTP request URI, not including the scheme, host or port. |
|
| `RequestPath` | The HTTP request URI, not including the scheme, host or port. |
|
||||||
| `RequestProtocol` | The version of HTTP requested. |
|
| `RequestProtocol` | The version of HTTP requested. |
|
||||||
|
| `RequestScheme` | The HTTP scheme requested `http` or `https`. |
|
||||||
| `RequestLine` | `RequestMethod` + `RequestPath` + `RequestProtocol` |
|
| `RequestLine` | `RequestMethod` + `RequestPath` + `RequestProtocol` |
|
||||||
| `RequestContentSize` | The number of bytes in the request entity (a.k.a. body) sent by the client. |
|
| `RequestContentSize` | The number of bytes in the request entity (a.k.a. body) sent by the client. |
|
||||||
| `OriginDuration` | The time taken by the origin server ('upstream') to return its response. |
|
| `OriginDuration` | The time taken by the origin server ('upstream') to return its response. |
|
||||||
|
|
|
@ -616,7 +616,7 @@ func (s *SimpleSuite) TestUDPServiceConfigErrors(c *check.C) {
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
defer cmd.Process.Kill()
|
defer cmd.Process.Kill()
|
||||||
|
|
||||||
err = try.GetRequest("http://127.0.0.1:8080/api/udp/services", 1000*time.Millisecond, try.BodyContains(`["the udp service \"service1@file\" does not have any type defined"]`))
|
err = try.GetRequest("http://127.0.0.1:8080/api/udp/services", 3000*time.Millisecond, try.BodyContains(`["the udp service \"service1@file\" does not have any type defined"]`))
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
err = try.GetRequest("http://127.0.0.1:8080/api/udp/services/service1@file", 1000*time.Millisecond, try.BodyContains(`"status":"disabled"`))
|
err = try.GetRequest("http://127.0.0.1:8080/api/udp/services/service1@file", 1000*time.Millisecond, try.BodyContains(`"status":"disabled"`))
|
||||||
|
|
|
@ -42,6 +42,8 @@ const (
|
||||||
RequestPath = "RequestPath"
|
RequestPath = "RequestPath"
|
||||||
// RequestProtocol is the map key used for the version of HTTP requested.
|
// RequestProtocol is the map key used for the version of HTTP requested.
|
||||||
RequestProtocol = "RequestProtocol"
|
RequestProtocol = "RequestProtocol"
|
||||||
|
// RequestScheme is the map key used for the HTTP request scheme.
|
||||||
|
RequestScheme = "RequestScheme"
|
||||||
// RequestContentSize is the map key used for the number of bytes in the request entity (a.k.a. body) sent by the client.
|
// RequestContentSize is the map key used for the number of bytes in the request entity (a.k.a. body) sent by the client.
|
||||||
RequestContentSize = "RequestContentSize"
|
RequestContentSize = "RequestContentSize"
|
||||||
// RequestRefererHeader is the Referer header in the request
|
// RequestRefererHeader is the Referer header in the request
|
||||||
|
@ -85,6 +87,7 @@ var defaultCoreKeys = [...]string{
|
||||||
RequestMethod,
|
RequestMethod,
|
||||||
RequestPath,
|
RequestPath,
|
||||||
RequestProtocol,
|
RequestProtocol,
|
||||||
|
RequestScheme,
|
||||||
RequestContentSize,
|
RequestContentSize,
|
||||||
OriginDuration,
|
OriginDuration,
|
||||||
OriginContentSize,
|
OriginContentSize,
|
||||||
|
|
|
@ -193,6 +193,11 @@ func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request, next http
|
||||||
core[RequestPath] = urlCopyString
|
core[RequestPath] = urlCopyString
|
||||||
core[RequestProtocol] = req.Proto
|
core[RequestProtocol] = req.Proto
|
||||||
|
|
||||||
|
core[RequestScheme] = "http"
|
||||||
|
if req.TLS != nil {
|
||||||
|
core[RequestScheme] = "https"
|
||||||
|
}
|
||||||
|
|
||||||
core[ClientAddr] = req.RemoteAddr
|
core[ClientAddr] = req.RemoteAddr
|
||||||
core[ClientHost], core[ClientPort] = silentSplitHostPort(req.RemoteAddr)
|
core[ClientHost], core[ClientPort] = silentSplitHostPort(req.RemoteAddr)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package accesslog
|
package accesslog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
@ -31,6 +32,7 @@ var (
|
||||||
testPath = "testpath"
|
testPath = "testpath"
|
||||||
testPort = 8181
|
testPort = 8181
|
||||||
testProto = "HTTP/0.0"
|
testProto = "HTTP/0.0"
|
||||||
|
testScheme = "http"
|
||||||
testMethod = http.MethodPost
|
testMethod = http.MethodPost
|
||||||
testReferer = "testReferer"
|
testReferer = "testReferer"
|
||||||
testUserAgent = "testUserAgent"
|
testUserAgent = "testUserAgent"
|
||||||
|
@ -183,6 +185,7 @@ func TestLoggerJSON(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc string
|
desc string
|
||||||
config *types.AccessLog
|
config *types.AccessLog
|
||||||
|
tls bool
|
||||||
expected map[string]func(t *testing.T, value interface{})
|
expected map[string]func(t *testing.T, value interface{})
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
|
@ -198,6 +201,47 @@ func TestLoggerJSON(t *testing.T) {
|
||||||
RequestMethod: assertString(testMethod),
|
RequestMethod: assertString(testMethod),
|
||||||
RequestPath: assertString(testPath),
|
RequestPath: assertString(testPath),
|
||||||
RequestProtocol: assertString(testProto),
|
RequestProtocol: assertString(testProto),
|
||||||
|
RequestScheme: assertString(testScheme),
|
||||||
|
RequestPort: assertString("-"),
|
||||||
|
DownstreamStatus: assertFloat64(float64(testStatus)),
|
||||||
|
DownstreamContentSize: assertFloat64(float64(len(testContent))),
|
||||||
|
OriginContentSize: assertFloat64(float64(len(testContent))),
|
||||||
|
OriginStatus: assertFloat64(float64(testStatus)),
|
||||||
|
RequestRefererHeader: assertString(testReferer),
|
||||||
|
RequestUserAgentHeader: assertString(testUserAgent),
|
||||||
|
RouterName: assertString(testRouterName),
|
||||||
|
ServiceURL: assertString(testServiceName),
|
||||||
|
ClientUsername: assertString(testUsername),
|
||||||
|
ClientHost: assertString(testHostname),
|
||||||
|
ClientPort: assertString(fmt.Sprintf("%d", testPort)),
|
||||||
|
ClientAddr: assertString(fmt.Sprintf("%s:%d", testHostname, testPort)),
|
||||||
|
"level": assertString("info"),
|
||||||
|
"msg": assertString(""),
|
||||||
|
"downstream_Content-Type": assertString("text/plain; charset=utf-8"),
|
||||||
|
RequestCount: assertFloat64NotZero(),
|
||||||
|
Duration: assertFloat64NotZero(),
|
||||||
|
Overhead: assertFloat64NotZero(),
|
||||||
|
RetryAttempts: assertFloat64(float64(testRetryAttempts)),
|
||||||
|
"time": assertNotEmpty(),
|
||||||
|
"StartLocal": assertNotEmpty(),
|
||||||
|
"StartUTC": assertNotEmpty(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "default config, with TLS request",
|
||||||
|
config: &types.AccessLog{
|
||||||
|
FilePath: "",
|
||||||
|
Format: JSONFormat,
|
||||||
|
},
|
||||||
|
tls: true,
|
||||||
|
expected: map[string]func(t *testing.T, value interface{}){
|
||||||
|
RequestContentSize: assertFloat64(0),
|
||||||
|
RequestHost: assertString(testHostname),
|
||||||
|
RequestAddr: assertString(testHostname),
|
||||||
|
RequestMethod: assertString(testMethod),
|
||||||
|
RequestPath: assertString(testPath),
|
||||||
|
RequestProtocol: assertString(testProto),
|
||||||
|
RequestScheme: assertString("https"),
|
||||||
RequestPort: assertString("-"),
|
RequestPort: assertString("-"),
|
||||||
DownstreamStatus: assertFloat64(float64(testStatus)),
|
DownstreamStatus: assertFloat64(float64(testStatus)),
|
||||||
DownstreamContentSize: assertFloat64(float64(len(testContent))),
|
DownstreamContentSize: assertFloat64(float64(len(testContent))),
|
||||||
|
@ -319,7 +363,11 @@ func TestLoggerJSON(t *testing.T) {
|
||||||
logFilePath := filepath.Join(tmpDir, logFileNameSuffix)
|
logFilePath := filepath.Join(tmpDir, logFileNameSuffix)
|
||||||
|
|
||||||
test.config.FilePath = logFilePath
|
test.config.FilePath = logFilePath
|
||||||
|
if test.tls {
|
||||||
|
doLoggingTLS(t, test.config)
|
||||||
|
} else {
|
||||||
doLogging(t, test.config)
|
doLogging(t, test.config)
|
||||||
|
}
|
||||||
|
|
||||||
logData, err := ioutil.ReadFile(logFilePath)
|
logData, err := ioutil.ReadFile(logFilePath)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -597,7 +645,7 @@ func createTempDir(t *testing.T, prefix string) string {
|
||||||
return tmpDir
|
return tmpDir
|
||||||
}
|
}
|
||||||
|
|
||||||
func doLogging(t *testing.T, config *types.AccessLog) {
|
func doLoggingTLSOpt(t *testing.T, config *types.AccessLog, enableTLS bool) {
|
||||||
logger, err := NewHandler(config)
|
logger, err := NewHandler(config)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer logger.Close()
|
defer logger.Close()
|
||||||
|
@ -621,10 +669,21 @@ func doLogging(t *testing.T, config *types.AccessLog) {
|
||||||
Path: testPath,
|
Path: testPath,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
if enableTLS {
|
||||||
|
req.TLS = &tls.ConnectionState{}
|
||||||
|
}
|
||||||
|
|
||||||
logger.ServeHTTP(httptest.NewRecorder(), req, http.HandlerFunc(logWriterTestHandlerFunc))
|
logger.ServeHTTP(httptest.NewRecorder(), req, http.HandlerFunc(logWriterTestHandlerFunc))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func doLoggingTLS(t *testing.T, config *types.AccessLog) {
|
||||||
|
doLoggingTLSOpt(t, config, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func doLogging(t *testing.T, config *types.AccessLog) {
|
||||||
|
doLoggingTLSOpt(t, config, false)
|
||||||
|
}
|
||||||
|
|
||||||
func logWriterTestHandlerFunc(rw http.ResponseWriter, r *http.Request) {
|
func logWriterTestHandlerFunc(rw http.ResponseWriter, r *http.Request) {
|
||||||
if _, err := rw.Write([]byte(testContent)); err != nil {
|
if _, err := rw.Write([]byte(testContent)); err != nil {
|
||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
|
|
Loading…
Reference in a new issue