mirror of
https://github.com/kataras/iris.git
synced 2025-02-09 02:34:55 +01:00
accesslog: add a blank configuration field as requested at #1627
This commit is contained in:
parent
99fd50bf9d
commit
fb00ecd2b7
|
@ -143,15 +143,21 @@ type AccessLog struct {
|
||||||
//
|
//
|
||||||
// Defaults to "2006-01-02 15:04:05"
|
// Defaults to "2006-01-02 15:04:05"
|
||||||
TimeFormat string
|
TimeFormat string
|
||||||
|
// A text that will appear in a blank value.
|
||||||
|
// Applies to the default formatter on
|
||||||
|
// IP, RequestBody and ResponseBody fields, if enabled, so far.
|
||||||
|
//
|
||||||
|
// Defaults to nil.
|
||||||
|
Blank []byte
|
||||||
// Round the latency based on the given duration, e.g. time.Second.
|
// Round the latency based on the given duration, e.g. time.Second.
|
||||||
//
|
//
|
||||||
// Defaults to 0.
|
// Defaults to 0.
|
||||||
LatencyRound time.Duration
|
LatencyRound time.Duration
|
||||||
|
|
||||||
// IP displays the remote address.
|
// IP displays the remote address.
|
||||||
//
|
//
|
||||||
// Defaults to true.
|
// Defaults to true.
|
||||||
IP bool
|
IP bool
|
||||||
|
|
||||||
// The number of bytes for the request body only.
|
// The number of bytes for the request body only.
|
||||||
// Applied when BytesReceived is false.
|
// Applied when BytesReceived is false.
|
||||||
//
|
//
|
||||||
|
@ -174,7 +180,6 @@ type AccessLog struct {
|
||||||
// They both default to false.
|
// They both default to false.
|
||||||
BytesReceived bool
|
BytesReceived bool
|
||||||
BytesSent bool
|
BytesSent bool
|
||||||
|
|
||||||
// Enable request body logging.
|
// Enable request body logging.
|
||||||
// Note that, if this is true then it modifies the underline request's body type.
|
// Note that, if this is true then it modifies the underline request's body type.
|
||||||
//
|
//
|
||||||
|
@ -257,6 +262,7 @@ func New(w io.Writer) *AccessLog {
|
||||||
Clock: clockFunc(time.Now),
|
Clock: clockFunc(time.Now),
|
||||||
Delim: defaultDelim,
|
Delim: defaultDelim,
|
||||||
TimeFormat: defaultTimeFormat,
|
TimeFormat: defaultTimeFormat,
|
||||||
|
Blank: nil,
|
||||||
LatencyRound: 0,
|
LatencyRound: 0,
|
||||||
Async: false,
|
Async: false,
|
||||||
IP: true,
|
IP: true,
|
||||||
|
@ -808,7 +814,7 @@ func (ac *AccessLog) Print(ctx *context.Context,
|
||||||
builder.WriteByte(ac.Delim)
|
builder.WriteByte(ac.Delim)
|
||||||
|
|
||||||
if ac.IP {
|
if ac.IP {
|
||||||
builder.WriteString(ip)
|
ac.writeText(builder, ip)
|
||||||
builder.WriteByte(ac.Delim)
|
builder.WriteByte(ac.Delim)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,12 +836,12 @@ func (ac *AccessLog) Print(ctx *context.Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
if ac.RequestBody {
|
if ac.RequestBody {
|
||||||
builder.WriteString(reqBody)
|
ac.writeText(builder, reqBody)
|
||||||
builder.WriteByte(ac.Delim)
|
builder.WriteByte(ac.Delim)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ac.ResponseBody {
|
if ac.ResponseBody {
|
||||||
builder.WriteString(respBody)
|
ac.writeText(builder, respBody)
|
||||||
builder.WriteByte(ac.Delim)
|
builder.WriteByte(ac.Delim)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -848,6 +854,20 @@ func (ac *AccessLog) Print(ctx *context.Context,
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We could have a map of blanks per field,
|
||||||
|
// but let's don't coplicate things so much
|
||||||
|
// as the end-developer can use a custom template.
|
||||||
|
func (ac *AccessLog) writeText(buf *bytes.Buffer, s string) {
|
||||||
|
if len(s) == 0 {
|
||||||
|
if len(ac.Blank) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
buf.Write(ac.Blank)
|
||||||
|
} else {
|
||||||
|
buf.WriteString(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var lineBreaksReplacer = strings.NewReplacer("\n\r", " ", "\n", " ")
|
var lineBreaksReplacer = strings.NewReplacer("\n\r", " ", "\n", " ")
|
||||||
|
|
||||||
func (ac *AccessLog) getErrorText(err error) (text string) { // caller checks for nil.
|
func (ac *AccessLog) getErrorText(err error) (text string) { // caller checks for nil.
|
||||||
|
|
|
@ -169,6 +169,40 @@ func TestAccessLogBroker(t *testing.T) {
|
||||||
ac.Close()
|
ac.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccessLogBlank(t *testing.T) {
|
||||||
|
w := new(bytes.Buffer)
|
||||||
|
ac := New(w)
|
||||||
|
clockTime, _ := time.Parse(defaultTimeFormat, "1993-01-01 05:00:00")
|
||||||
|
ac.Clock = TClock(clockTime)
|
||||||
|
ac.Blank = []byte("<no value>")
|
||||||
|
|
||||||
|
ac.Print(
|
||||||
|
nil,
|
||||||
|
time.Second,
|
||||||
|
defaultTimeFormat,
|
||||||
|
200,
|
||||||
|
"GET",
|
||||||
|
"/",
|
||||||
|
"127.0.0.1",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
|
||||||
|
ac.Close()
|
||||||
|
// the request and bodies length are enabled by-default, zero bytes length
|
||||||
|
// are written with 0 B and this cannot changed, so the request field
|
||||||
|
// should be written as "<no value>".
|
||||||
|
expected := "1993-01-01 05:00:00|1s|200|GET|/|127.0.0.1|0 B|0 B|<no value>|\n"
|
||||||
|
if got := w.String(); expected != got {
|
||||||
|
t.Fatalf("expected:\n'%s'\n\nbut got:\n'%s'", expected, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type noOpFormatter struct{}
|
type noOpFormatter struct{}
|
||||||
|
|
||||||
func (*noOpFormatter) SetOutput(io.Writer) {}
|
func (*noOpFormatter) SetOutput(io.Writer) {}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user