mirror of
https://github.com/caddyserver/caddy.git
synced 2025-02-24 00:38:53 +01:00
log: 'except' subdirective to skip logging certain requests (#2028)
* proof of concept * Initial implementation with debug code * Tidy up debug code * remove unneeded import * removed extra line * Move ShouldLog function to rule entry Logger type * add tests for ShouldLog * Added tests for log exceptions * Fix logic * fix govet fail for test * Updates requested for code clarity * Update requested for style * log: Minor style tweaks to logic of log exceptions
This commit is contained in:
parent
1580169e2b
commit
1896b420d8
4 changed files with 107 additions and 1 deletions
|
@ -44,6 +44,7 @@ type Logger struct {
|
|||
V4ipMask net.IPMask
|
||||
V6ipMask net.IPMask
|
||||
IPMaskExists bool
|
||||
Exceptions []string
|
||||
}
|
||||
|
||||
// NewTestLogger creates logger suitable for testing purposes
|
||||
|
@ -84,6 +85,17 @@ func (l Logger) MaskIP(ip string) string {
|
|||
|
||||
}
|
||||
|
||||
// ShouldLog returns true if the path is not exempted from
|
||||
// being logged (i.e. it is not found in l.Exceptions).
|
||||
func (l Logger) ShouldLog(path string) bool {
|
||||
for _, exc := range l.Exceptions {
|
||||
if Path(path).Matches(exc) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Attach binds logger Start and Close functions to
|
||||
// controller's OnStartup and OnShutdown hooks.
|
||||
func (l *Logger) Attach(controller *caddy.Controller) {
|
||||
|
|
|
@ -67,6 +67,10 @@ func (l Logger) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
|
|||
|
||||
// Write log entries
|
||||
for _, e := range rule.Entries {
|
||||
// Check if there is an exception to prevent log being written
|
||||
if !e.Log.ShouldLog(r.URL.Path) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Mask IP Address
|
||||
if e.Log.IPMaskExists {
|
||||
|
@ -78,6 +82,7 @@ func (l Logger) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
|
|||
}
|
||||
}
|
||||
e.Log.Println(rep.Replace(e.Format))
|
||||
|
||||
}
|
||||
|
||||
return status, err
|
||||
|
|
|
@ -177,3 +177,85 @@ func TestMultiEntries(t *testing.T) {
|
|||
t.Errorf("Expected %q, but got %q", expect, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLogExcept(t *testing.T) {
|
||||
tests := []struct {
|
||||
LogRules []Rule
|
||||
logPath string
|
||||
shouldLog bool
|
||||
}{
|
||||
{[]Rule{{
|
||||
PathScope: "/",
|
||||
Entries: []*Entry{{
|
||||
Log: &httpserver.Logger{
|
||||
|
||||
Exceptions: []string{"/soup"},
|
||||
},
|
||||
Format: DefaultLogFormat,
|
||||
}},
|
||||
}}, `/soup`, false},
|
||||
{[]Rule{{
|
||||
PathScope: "/",
|
||||
Entries: []*Entry{{
|
||||
Log: &httpserver.Logger{
|
||||
|
||||
Exceptions: []string{"/tart"},
|
||||
},
|
||||
Format: DefaultLogFormat,
|
||||
}},
|
||||
}}, `/soup`, true},
|
||||
{[]Rule{{
|
||||
PathScope: "/",
|
||||
Entries: []*Entry{{
|
||||
Log: &httpserver.Logger{
|
||||
|
||||
Exceptions: []string{"/soup"},
|
||||
},
|
||||
Format: DefaultLogFormat,
|
||||
}},
|
||||
}}, `/tomatosoup`, true},
|
||||
{[]Rule{{
|
||||
PathScope: "/",
|
||||
Entries: []*Entry{{
|
||||
Log: &httpserver.Logger{
|
||||
|
||||
Exceptions: []string{"/pie/"},
|
||||
},
|
||||
Format: DefaultLogFormat,
|
||||
}},
|
||||
// Check exception with a trailing slash does not match without
|
||||
}}, `/pie`, true},
|
||||
{[]Rule{{
|
||||
PathScope: "/",
|
||||
Entries: []*Entry{{
|
||||
Log: &httpserver.Logger{
|
||||
|
||||
Exceptions: []string{"/pie.php"},
|
||||
},
|
||||
Format: DefaultLogFormat,
|
||||
}},
|
||||
}}, `/pie`, true},
|
||||
{[]Rule{{
|
||||
PathScope: "/",
|
||||
Entries: []*Entry{{
|
||||
Log: &httpserver.Logger{
|
||||
|
||||
Exceptions: []string{"/pie"},
|
||||
},
|
||||
Format: DefaultLogFormat,
|
||||
}},
|
||||
// Check that a word without trailing slash will match a filename
|
||||
}}, `/pie.php`, false},
|
||||
}
|
||||
for i, test := range tests {
|
||||
for _, LogRule := range test.LogRules {
|
||||
for _, e := range LogRule.Entries {
|
||||
shouldLog := e.Log.ShouldLog(test.logPath)
|
||||
if shouldLog != test.shouldLog {
|
||||
t.Fatalf("Test %d expected shouldLog=%t but got shouldLog=%t,", i, test.shouldLog, shouldLog)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ func setup(c *caddy.Controller) error {
|
|||
|
||||
func logParse(c *caddy.Controller) ([]*Rule, error) {
|
||||
var rules []*Rule
|
||||
|
||||
var logExceptions []string
|
||||
for c.Next() {
|
||||
args := c.RemainingArgs()
|
||||
|
||||
|
@ -91,6 +91,12 @@ func logParse(c *caddy.Controller) ([]*Rule, error) {
|
|||
|
||||
}
|
||||
|
||||
} else if what == "except" {
|
||||
|
||||
for i := 0; i < len(where); i++ {
|
||||
logExceptions = append(logExceptions, where[i])
|
||||
}
|
||||
|
||||
} else if httpserver.IsLogRollerSubdirective(what) {
|
||||
|
||||
if err := httpserver.ParseRoller(logRoller, what, where...); err != nil {
|
||||
|
@ -133,6 +139,7 @@ func logParse(c *caddy.Controller) ([]*Rule, error) {
|
|||
V4ipMask: ip4Mask,
|
||||
V6ipMask: ip6Mask,
|
||||
IPMaskExists: ipMaskExists,
|
||||
Exceptions: logExceptions,
|
||||
},
|
||||
Format: format,
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue