Enable access logs globally on all sites using Caddyfile

1. Caddy version (caddy version):

v2.4.6 h1:HGkGICFGvyrodcqOOclHKfvJC0qTU7vny/7FhYp9hNw=

2. How I run Caddy:

Using caddy-docker-proxy - but i’ve come up with a simple example below to run it standalone mode below.

a. System environment:

Debian/11

b. Command:

caddy run --config Caddyfile

c. Service/unit/compose file:

n/a

d. My complete Caddyfile or JSON config:

{
        log {
                format json
        }
}
http://localhost:8080/ {
        respond "Hello, caddy log test world!"
}

3. The problem I’m having:

I would like access logs enabled on all sites globally in json format.

It would be best to do this on a global level because I’m using caddy-docker-proxy and would like to reduce the boilerplate for each site (and prevent sites accidentally being missed from the access log).

But with the above configuration I am not able to get access logs. When I do:

$ curl http://localhost:8080
Hello, caddy log test world

I serve the request, but not access logs are output.

Is there any way to do this with the caddyfile?

4. Error messages and/or full log output:

2021/12/06 19:06:15.739 INFO    using provided configuration    {"config_file": "Caddyfile", "config_adapter": ""}
{"level":"info","ts":1638817575.742325,"logger":"admin","msg":"admin endpoint started","address":"tcp/localhost:2019","enforce_origin":false,"origins":["localhost:2019","[::1]:2019","127.0.0.1:2019"]}
{"level":"info","ts":1638817575.7426467,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc0004681c0"}
{"level":"info","ts":1638817575.7427516,"logger":"tls","msg":"cleaning storage unit","description":"FileStorage:/home/poltawski/.local/share/caddy"}
{"level":"info","ts":1638817575.7428076,"logger":"tls","msg":"finished cleaning storage units"}
{"level":"info","ts":1638817575.742976,"msg":"autosaved config (load with --resume flag)","file":"/home/poltawski/.config/caddy/autosave.json"}
{"level":"info","ts":1638817575.7430086,"msg":"serving initial configuration"}

5. What I already tried:

Putting the log directive in site does work, like below. But I am trying to avoid duplicating the log directive in every single site.

{
        log {
                format json
        }
}
http://localhost:8080/ {
        respond "Hello, caddy log test world!"
        log {
                format json
        }
}

Outputs:

{"level":"info","ts":1638817803.1193275,"logger":"http.log.access.log0","msg":"handled request","request":{"remote_addr":"127.0.0.1:56780","proto":"HTTP/1.1","method":"GET","host":"localhost:8080","uri":"/","headers":{"User-Agent":["curl/7.74.0"],"Accept":["*/*"]}},"common_log":"127.0.0.1 - - [06/Dec/2021:19:10:03 +0000] \"GET / HTTP/1.1\" 200 28","user_id":"","duration":0.0000499,"size":28,"status":200,"resp_headers":{"Server":["Caddy"],"Content-Type":[]

As I’m using caddy-docker-proxy I need to use Caddyfile syntax.

6. Links to relevant resources:

Similar question - Enable logging globally - #2 by matt

To mitigate repetition, you can use Caddyfile snippets:

By default, the log global options doesn’t configure access logs. You would need configure them to include logs from the http.log.access namespace.

Also FYI, you have a trailing slash here, which will set up a path matcher which would only match requests to exactly / and nothing else. Path matching in Caddy is exact. So remove the slash at the end to make sure all paths will be handled by that site.

Thanks - i’ve encountered another drawback of adding this duplication, each site logs as a different logger, i.e. "logger":"http.log.access.log2""logger":"http.log.access.log17" etc

Is this possible to do from the Caddyfile?

Also FYI, you have a trailing slash here,

Thanks :slight_smile:

I’m not sure I understand why you think this is a drawback? That’s fine :man_shrugging:

Yes, the page I linked to is the documentation for the global options in the Caddyfile.

I’m not sure I understand why you think this is a drawback?

It’s not a big deal, but i’d like to filter to the exact logger for all logs across hosts.

Yes, the page I linked to is the documentation for the global options in the Caddyfile.

I didn’t realise this, but I’m afraid i’m still stumped into hot to achieve this, none of the include options I try seem to get the logs output. I have tried different variants of http.log.access

{
        log {
                format json
                output stderr
                include http.log.access
        }
}
http://localhost:8080 {
        respond "Hello, caddy log test world!"
}

Not sure what you mean by “filter” in this case. I don’t see a filter in your logging config.

I’ll double check the behaviour for this this evening.

Alright, so a config like this does work:

{
	log {
		format json
		output stderr
	}
}

http://localhost:8080 {
	log
	respond "Hello, caddy log test world!"
}

The key is you need to at least enable log in each site so that shouldLogRequest is true:

Doing so, it’ll use the default logger instead of configuring a per-site logger, so you can use the global options to configure all of them at once.

2 Likes

This topic was automatically closed after 30 days. New replies are no longer allowed.