Browse Source
This change is aimed at enhancing the logging module within the Caddyfile directive to allow users to configure logs other than the HTTP access log stream, which is the current capability of the Caddyfile [1]. The intent here is to leverage the same syntax as the server log directive at a global level, so that similar customizations can be added without needing to resort to a JSON-based configuration. Discussion for this approach happened in the referenced issue. Closes https://github.com/caddyserver/caddy/issues/3958 [1] https://caddyserver.com/docs/caddyfile/directives/logmaster
committed by
GitHub
9 changed files with 414 additions and 26 deletions
@ -0,0 +1,64 @@ |
|||||
|
package httpcaddyfile |
||||
|
|
||||
|
import ( |
||||
|
"testing" |
||||
|
|
||||
|
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" |
||||
|
_ "github.com/caddyserver/caddy/v2/modules/logging" |
||||
|
) |
||||
|
|
||||
|
func TestGlobalLogOptionSyntax(t *testing.T) { |
||||
|
for i, tc := range []struct { |
||||
|
input string |
||||
|
output string |
||||
|
expectError bool |
||||
|
}{ |
||||
|
// NOTE: Additional test cases of successful Caddyfile parsing
|
||||
|
// are present in: caddytest/integration/caddyfile_adapt/
|
||||
|
{ |
||||
|
input: `{ |
||||
|
log default |
||||
|
} |
||||
|
`, |
||||
|
output: `{}`, |
||||
|
expectError: false, |
||||
|
}, |
||||
|
{ |
||||
|
input: `{ |
||||
|
log example { |
||||
|
output file foo.log |
||||
|
} |
||||
|
log example { |
||||
|
format json |
||||
|
} |
||||
|
} |
||||
|
`, |
||||
|
expectError: true, |
||||
|
}, |
||||
|
{ |
||||
|
input: `{ |
||||
|
log example /foo { |
||||
|
output file foo.log |
||||
|
} |
||||
|
} |
||||
|
`, |
||||
|
expectError: true, |
||||
|
}, |
||||
|
} { |
||||
|
|
||||
|
adapter := caddyfile.Adapter{ |
||||
|
ServerType: ServerType{}, |
||||
|
} |
||||
|
|
||||
|
out, _, err := adapter.Adapt([]byte(tc.input), nil) |
||||
|
|
||||
|
if err != nil != tc.expectError { |
||||
|
t.Errorf("Test %d error expectation failed Expected: %v, got %v", i, tc.expectError, err) |
||||
|
continue |
||||
|
} |
||||
|
|
||||
|
if string(out) != tc.output { |
||||
|
t.Errorf("Test %d error output mismatch Expected: %s, got %s", i, tc.output, out) |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,77 @@ |
|||||
|
{ |
||||
|
log { |
||||
|
output file caddy.log |
||||
|
include some-log-source |
||||
|
exclude admin.api admin2.api |
||||
|
} |
||||
|
log custom-logger { |
||||
|
output file caddy.log |
||||
|
level WARN |
||||
|
include custom-log-source |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
:8884 { |
||||
|
log { |
||||
|
format json |
||||
|
output file access.log |
||||
|
} |
||||
|
} |
||||
|
---------- |
||||
|
{ |
||||
|
"logging": { |
||||
|
"logs": { |
||||
|
"custom-logger": { |
||||
|
"writer": { |
||||
|
"filename": "caddy.log", |
||||
|
"output": "file" |
||||
|
}, |
||||
|
"level": "WARN", |
||||
|
"include": [ |
||||
|
"custom-log-source" |
||||
|
] |
||||
|
}, |
||||
|
"default": { |
||||
|
"writer": { |
||||
|
"filename": "caddy.log", |
||||
|
"output": "file" |
||||
|
}, |
||||
|
"include": [ |
||||
|
"some-log-source" |
||||
|
], |
||||
|
"exclude": [ |
||||
|
"admin.api", |
||||
|
"admin2.api", |
||||
|
"custom-log-source", |
||||
|
"http.log.access.log0" |
||||
|
] |
||||
|
}, |
||||
|
"log0": { |
||||
|
"writer": { |
||||
|
"filename": "access.log", |
||||
|
"output": "file" |
||||
|
}, |
||||
|
"encoder": { |
||||
|
"format": "json" |
||||
|
}, |
||||
|
"include": [ |
||||
|
"http.log.access.log0" |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"apps": { |
||||
|
"http": { |
||||
|
"servers": { |
||||
|
"srv0": { |
||||
|
"listen": [ |
||||
|
":8884" |
||||
|
], |
||||
|
"logs": { |
||||
|
"default_logger_name": "log0" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,18 @@ |
|||||
|
{ |
||||
|
log { |
||||
|
output file foo.log |
||||
|
} |
||||
|
} |
||||
|
---------- |
||||
|
{ |
||||
|
"logging": { |
||||
|
"logs": { |
||||
|
"default": { |
||||
|
"writer": { |
||||
|
"filename": "foo.log", |
||||
|
"output": "file" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,39 @@ |
|||||
|
{ |
||||
|
log custom-logger { |
||||
|
format filter { |
||||
|
wrap console |
||||
|
fields { |
||||
|
common_log delete |
||||
|
request>remote_addr ip_mask { |
||||
|
ipv4 24 |
||||
|
ipv6 32 |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
---------- |
||||
|
{ |
||||
|
"logging": { |
||||
|
"logs": { |
||||
|
"custom-logger": { |
||||
|
"encoder": { |
||||
|
"fields": { |
||||
|
"common_log": { |
||||
|
"filter": "delete" |
||||
|
}, |
||||
|
"request\u003eremote_addr": { |
||||
|
"filter": "ip_mask", |
||||
|
"ipv4_cidr": 24, |
||||
|
"ipv6_cidr": 32 |
||||
|
} |
||||
|
}, |
||||
|
"format": "filter", |
||||
|
"wrap": { |
||||
|
"format": "console" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,26 @@ |
|||||
|
{ |
||||
|
log first { |
||||
|
output file foo.log |
||||
|
} |
||||
|
log second { |
||||
|
format json |
||||
|
} |
||||
|
} |
||||
|
---------- |
||||
|
{ |
||||
|
"logging": { |
||||
|
"logs": { |
||||
|
"first": { |
||||
|
"writer": { |
||||
|
"filename": "foo.log", |
||||
|
"output": "file" |
||||
|
} |
||||
|
}, |
||||
|
"second": { |
||||
|
"encoder": { |
||||
|
"format": "json" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue