mirror of
https://github.com/wahyd4/loginsrv.git
synced 2026-08-09 12:56:06 +10:00
360 lines
9.4 KiB
Go
360 lines
9.4 KiB
Go
package logging
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/tarent/logrus"
|
|
"net/http"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
type logReccord struct {
|
|
Type string `json:"type"`
|
|
Timestamp string `json:"@timestamp"`
|
|
CorrelationId string `json:"correlation_id"`
|
|
RemoteIp string `json:"remote_ip"`
|
|
Host string `json:"host"`
|
|
URL string `json:"url"`
|
|
Method string `json:"method"`
|
|
Proto string `json:"proto"`
|
|
Duration int `json:"duration"`
|
|
ResponseStatus int `json:"response_status"`
|
|
UserCorrelationId string `json:"user_correlation_id"`
|
|
Cookies map[string]string `json:"cookies"`
|
|
Error string `json:"error"`
|
|
Message string `json:"message"`
|
|
Level string `json:"level"`
|
|
UserAgent string `json:"User_Agent"`
|
|
}
|
|
|
|
func Test_Logger_Set(t *testing.T) {
|
|
a := assert.New(t)
|
|
|
|
// given: an error logger in text format
|
|
Set("error", true)
|
|
defer Set("info", false)
|
|
Logger.Formatter.(*logrus.TextFormatter).DisableColors = true
|
|
b := bytes.NewBuffer(nil)
|
|
Logger.Out = b
|
|
|
|
// when: I log something
|
|
Logger.Info("should be ignored ..")
|
|
Logger.WithField("foo", "bar").Error("oops")
|
|
|
|
// then: only the error text is contained
|
|
// and it is text formated
|
|
a.Regexp(`^time.* level\=error msg\=oops foo\=bar.*`, b.String())
|
|
}
|
|
|
|
func Test_Logger_Call(t *testing.T) {
|
|
a := assert.New(t)
|
|
|
|
// given a logger
|
|
b := bytes.NewBuffer(nil)
|
|
Logger.Out = b
|
|
AccessLogCookiesBlacklist = []string{"ignore", "user_id"}
|
|
UserCorrelationCookie = "user_id"
|
|
|
|
// and a request
|
|
r, _ := http.NewRequest("GET", "http://www.example.org/foo?q=bar", nil)
|
|
r.Header = http.Header{
|
|
CorrelationIdHeader: {"correlation-123"},
|
|
"Cookie": {"user_id=user-id-xyz; ignore=me; foo=bar;"},
|
|
}
|
|
|
|
resp := &http.Response{
|
|
StatusCode: 404,
|
|
Header: http.Header{"Content-Type": {"text/html"}},
|
|
}
|
|
|
|
// when: We log a request with access
|
|
start := time.Now().Add(-1 * time.Second)
|
|
Call(r, resp, start, nil)
|
|
|
|
// then: all fields match
|
|
data := &logReccord{}
|
|
err := json.Unmarshal(b.Bytes(), data)
|
|
a.NoError(err)
|
|
|
|
a.Equal("warning", data.Level)
|
|
a.Equal("correlation-123", data.CorrelationId)
|
|
a.Equal("user-id-xyz", data.UserCorrelationId)
|
|
a.InDelta(1000, data.Duration, 0.5)
|
|
a.Equal("", data.Error)
|
|
a.Equal("www.example.org", data.Host)
|
|
a.Equal("GET", data.Method)
|
|
a.Equal("404 GET-> http://www.example.org/foo?q=bar", data.Message)
|
|
a.Equal(404, data.ResponseStatus)
|
|
a.Equal("call", data.Type)
|
|
a.Equal("/foo?q=bar", data.URL)
|
|
|
|
// when we call with an error
|
|
b.Reset()
|
|
start = time.Now().Add(-1 * time.Second)
|
|
Call(r, nil, start, errors.New("oops"))
|
|
|
|
// then: all fields match
|
|
data = &logReccord{}
|
|
err = json.Unmarshal(b.Bytes(), data)
|
|
a.NoError(err)
|
|
|
|
a.Equal("error", data.Level)
|
|
a.Equal("oops", data.Error)
|
|
a.Equal("oops", data.Message)
|
|
a.Equal("correlation-123", data.CorrelationId)
|
|
a.Equal("user-id-xyz", data.UserCorrelationId)
|
|
a.InDelta(1000, data.Duration, 0.5)
|
|
a.Equal("www.example.org", data.Host)
|
|
a.Equal("GET", data.Method)
|
|
a.Equal("call", data.Type)
|
|
a.Equal("/foo?q=bar", data.URL)
|
|
}
|
|
|
|
func Test_Logger_Access(t *testing.T) {
|
|
a := assert.New(t)
|
|
|
|
// given a logger
|
|
b := bytes.NewBuffer(nil)
|
|
Logger.Out = b
|
|
AccessLogCookiesBlacklist = []string{"ignore", "user_id"}
|
|
UserCorrelationCookie = "user_id"
|
|
|
|
// Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.84 Safari/537.36
|
|
|
|
// and a request
|
|
r, _ := http.NewRequest("GET", "http://www.example.org/foo?q=bar", nil)
|
|
r.Header = http.Header{
|
|
CorrelationIdHeader: {"correlation-123"},
|
|
"Cookie": {"user_id=user-id-xyz; ignore=me; foo=bar;"},
|
|
"User-Agent": {"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.84 Safari/537.36"},
|
|
}
|
|
r.RemoteAddr = "127.0.0.1"
|
|
|
|
// when: We log a request with access
|
|
start := time.Now().Add(-1 * time.Second)
|
|
Access(r, start, 201)
|
|
|
|
// then: all fields match
|
|
data := &logReccord{}
|
|
err := json.Unmarshal(b.Bytes(), data)
|
|
a.NoError(err)
|
|
|
|
a.Equal("info", data.Level)
|
|
a.Equal(map[string]string{"foo": "bar"}, data.Cookies)
|
|
a.Equal("correlation-123", data.CorrelationId)
|
|
a.InDelta(1000, data.Duration, 0.5)
|
|
a.Equal("", data.Error)
|
|
a.Equal("www.example.org", data.Host)
|
|
a.Equal("GET", data.Method)
|
|
a.Equal("HTTP/1.1", data.Proto)
|
|
a.Equal("201 ->GET /foo?...", data.Message)
|
|
a.Equal("127.0.0.1", data.RemoteIp)
|
|
a.Equal(201, data.ResponseStatus)
|
|
a.Equal("access", data.Type)
|
|
a.Equal("/foo?q=bar", data.URL)
|
|
a.Equal("user-id-xyz", data.UserCorrelationId)
|
|
a.Equal("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.84 Safari/537.36", data.UserAgent)
|
|
}
|
|
|
|
func Test_Logger_Access_ErrorCases(t *testing.T) {
|
|
a := assert.New(t)
|
|
|
|
// given a logger
|
|
b := bytes.NewBuffer(nil)
|
|
Logger.Out = b
|
|
|
|
// and a request
|
|
r, _ := http.NewRequest("GET", "http://www.example.org/foo", nil)
|
|
|
|
// when a status 404 is logged
|
|
Access(r, time.Now(), 404)
|
|
// then: all fields match
|
|
data := logRecordFromBuffer(b)
|
|
a.Equal("warning", data.Level)
|
|
a.Equal("404 ->GET /foo", data.Message)
|
|
|
|
// when a status 500 is logged
|
|
b.Reset()
|
|
Access(r, time.Now(), 500)
|
|
// then: all fields match
|
|
data = logRecordFromBuffer(b)
|
|
a.Equal("error", data.Level)
|
|
|
|
// when an error is logged
|
|
b.Reset()
|
|
AccessError(r, time.Now(), errors.New("oops"))
|
|
// then: all fields match
|
|
data = logRecordFromBuffer(b)
|
|
a.Equal("error", data.Level)
|
|
a.Equal("oops", data.Error)
|
|
a.Equal("ERROR ->GET /foo", data.Message)
|
|
}
|
|
|
|
func Test_Logger_Application(t *testing.T) {
|
|
a := assert.New(t)
|
|
|
|
// given:
|
|
UserCorrelationCookie = "user_id"
|
|
header := http.Header{
|
|
CorrelationIdHeader: {"correlation-123"},
|
|
"Cookie": {"user_id=user-id-xyz;"},
|
|
}
|
|
|
|
// when:
|
|
entry := Application(header)
|
|
|
|
// then:
|
|
a.Equal("correlation-123", entry.Data["correlation_id"])
|
|
a.Equal("user-id-xyz", entry.Data["user_correlation_id"])
|
|
}
|
|
|
|
func Test_Logger_LifecycleStart(t *testing.T) {
|
|
a := assert.New(t)
|
|
|
|
// given a logger
|
|
b := bytes.NewBuffer(nil)
|
|
Logger.Out = b
|
|
|
|
// and
|
|
someArguments := struct {
|
|
Foo string
|
|
Number int
|
|
}{
|
|
Foo: "bar",
|
|
Number: 42,
|
|
}
|
|
|
|
// and an Environment Variable with the Build Number is set
|
|
os.Setenv("BUILD_NUMBER", "b666")
|
|
|
|
// when a LifecycleStart is logged
|
|
LifecycleStart("my-app", someArguments)
|
|
|
|
// then: it is logged
|
|
data := mapFromBuffer(b)
|
|
a.Equal("info", data["level"])
|
|
a.Equal("lifecycle", data["type"])
|
|
a.Equal("start", data["event"])
|
|
a.Equal("bar", data["Foo"])
|
|
a.Equal(42.0, data["Number"])
|
|
a.Equal("b666", data["build_number"])
|
|
}
|
|
|
|
func Test_Logger_LifecycleStop(t *testing.T) {
|
|
a := assert.New(t)
|
|
|
|
// given a logger
|
|
b := bytes.NewBuffer(nil)
|
|
Logger.Out = b
|
|
|
|
// and an Environment Variable with the Build Number is set
|
|
os.Setenv("BUILD_NUMBER", "b666")
|
|
|
|
// when a LifecycleStart is logged
|
|
LifecycleStop("my-app", os.Interrupt, nil)
|
|
|
|
// then: it is logged
|
|
data := mapFromBuffer(b)
|
|
a.Equal("info", data["level"])
|
|
a.Equal("stopping application: my-app (interrupt)", data["message"])
|
|
a.Equal("lifecycle", data["type"])
|
|
a.Equal("stop", data["event"])
|
|
a.Equal("interrupt", data["signal"])
|
|
a.Equal("b666", data["build_number"])
|
|
}
|
|
|
|
func Test_Logger_ServerClosed(t *testing.T) {
|
|
a := assert.New(t)
|
|
|
|
// given a logger
|
|
b := bytes.NewBuffer(nil)
|
|
Logger.Out = b
|
|
|
|
// and an Environment Variable with the Build Number is set
|
|
os.Setenv("BUILD_NUMBER", "b666")
|
|
|
|
// when a LifecycleStart is logged
|
|
ServerClosed("my-app")
|
|
|
|
// then: it is logged
|
|
data := mapFromBuffer(b)
|
|
a.Equal("info", data["level"])
|
|
a.Equal("http server was closed: my-app", data["message"])
|
|
a.Equal("application", data["type"])
|
|
a.Equal("stop", data["event"])
|
|
a.Equal("b666", data["build_number"])
|
|
}
|
|
|
|
func Test_Logger_Cacheinfo(t *testing.T) {
|
|
a := assert.New(t)
|
|
|
|
// given a logger
|
|
Set("debug", false)
|
|
defer Set("info", false)
|
|
b := bytes.NewBuffer(nil)
|
|
Logger.Out = b
|
|
|
|
// when a positive cachinfo is logged
|
|
Cacheinfo("/foo", true)
|
|
|
|
// then: it is logged
|
|
data := mapFromBuffer(b)
|
|
a.Equal("/foo", data["url"])
|
|
a.Equal("cacheinfo", data["type"])
|
|
a.Equal(true, data["hit"])
|
|
a.Equal("cache hit: /foo", data["message"])
|
|
|
|
b.Reset()
|
|
// logging a non hit
|
|
Cacheinfo("/foo", false)
|
|
data = mapFromBuffer(b)
|
|
a.Equal(false, data["hit"])
|
|
a.Equal("cache miss: /foo", data["message"])
|
|
}
|
|
|
|
func Test_Logger_GetRemoteIp1(t *testing.T) {
|
|
a := assert.New(t)
|
|
req, _ := http.NewRequest("GET", "test.com", nil)
|
|
req.Header["X-Cluster-Client-Ip"] = []string{"1234"}
|
|
ret := getRemoteIp(req)
|
|
a.Equal("1234", ret)
|
|
}
|
|
|
|
func Test_Logger_GetRemoteIp2(t *testing.T) {
|
|
a := assert.New(t)
|
|
req, _ := http.NewRequest("GET", "test.com", nil)
|
|
req.Header["X-Real-Ip"] = []string{"1234"}
|
|
ret := getRemoteIp(req)
|
|
a.Equal("1234", ret)
|
|
}
|
|
|
|
func Test_Logger_GetRemoteIp3(t *testing.T) {
|
|
a := assert.New(t)
|
|
req, _ := http.NewRequest("GET", "test.com", nil)
|
|
req.RemoteAddr = "1234:80"
|
|
ret := getRemoteIp(req)
|
|
a.Equal("1234", ret)
|
|
}
|
|
|
|
func logRecordFromBuffer(b *bytes.Buffer) *logReccord {
|
|
data := &logReccord{}
|
|
err := json.Unmarshal(b.Bytes(), data)
|
|
if err != nil {
|
|
panic(err.Error() + " " + b.String())
|
|
}
|
|
return data
|
|
}
|
|
|
|
func mapFromBuffer(b *bytes.Buffer) map[string]interface{} {
|
|
data := map[string]interface{}{}
|
|
err := json.Unmarshal(b.Bytes(), &data)
|
|
if err != nil {
|
|
panic(err.Error() + " " + b.String())
|
|
}
|
|
return data
|
|
}
|