Logging snippet using {host} placeholder for log filename

Hi,

I have a number of sub-domains being served by Caddy v2 and each one has the following code at the top to define a separate log file;

nextcloud.domain.tld {
  log {
    output file /var/log/caddy/nextcloud.domain.tld.access.log
  }
  ...
}

I was hoping to simplify this and pull the log code out into a reusable snippet, something like;

(logging) {
  log {
    output file /var/log/caddy/{host}.access.log
  }
}

So by adding import logging I would get a separate log (access) file for each site/sub-domain.

But when Caddy starts up I get the following error;

May 18 11:21:17 web01 caddy[11992]: run: loading initial config: loading new config: setting up custom log 'log0': loading log writer module: loading module 'file': provision caddy.logging.writers.file: invalid filename for log file: unrecognized placeholder {http.request.host}

Is this something that should be possible? I couldn’t find anything in the docs which suggests I can’t use http placeholders in a log filename.

Thanks,
Ben

Logging is initialized at the time that the server starts up, not during requests. Log files are opened once and kept open until the server shuts down. Much more efficient that way.

So the answer is no, you can’t use request placeholders for defining the log filename.

Thanks @francislavoie, that makes sense. So there is no way to simplify the logging config? No placeholder for the configured site name/address I could use instead?

Unfortunately, no, not currently.

But your question gave me a thought, it might be possible to implement support for arguments to be passed to snippets on import. I’ll need to spend more time thinking it through though, I’ll reply here if I’ve come up with it.

2 Likes

That was the other thought I had also, passing arguments to snippets, but assumed it was not possible. I will leave you to percolate… :slight_smile:

2 Likes

I would appreciate a way to have one log per host, which I do right now with multiple ˋlog` directives.

If I understand correctly, arguments could be a way to reproduce that setup with just one directive ?

My current thought is to have something like this:

(log_common) {
  log {
    output file /var/log/caddy/{args.0}.access.log
  }
}

a.example.com {
  import log_common a.example.com
}

b.example.com {
  import log_common b.example.com
}

No promises though.

It would work great for me. :+1:

Alright, wrote the proposal:

3 Likes

That is incredible @francislavoie - 9 hours from asking the question to a completed PR! Thank you very much! Hopefully others get plenty of use/benefit from this also.

1 Like

I never wrote an update here, but this is now available in Caddy v2.1

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.