Using {host} as part of a log output filename

1. The problem I’m having:

I have followed discussion Logging snippet using {host} placeholder for log filename and the patch was landed at caddyfile: Add support for args on imports #3423

But it does not work on mine. :slightly_frowning_face:

It cannot replace {host} as the {args[0]} of a snippet for log output file.

2. Error messages and/or full log output:

{"level":"info","ts":1742132974.028858,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
{"level":"info","ts":1742132974.0328307,"msg":"adapted config to JSON","adapter":"caddyfile"}
Error: 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}
{"level":"info","ts":1742132975.4025917,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
{"level":"info","ts":1742132975.4074125,"msg":"adapted config to JSON","adapter":"caddyfile"}
Error: loading initial config: loading new config: setting up custom log 'log1': loading log writer module: loading module 'file': provision caddy.logging.writers.file: invalid filename for log file: unrecognized placeholder {http.request.host}
{"level":"info","ts":1742132979.1320577,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
{"level":"info","ts":1742132979.1396198,"msg":"adapted config to JSON","adapter":"caddyfile"}
Error: loading initial config: loading new config: setting up custom log 'log6': loading log writer module: loading module 'file': provision caddy.logging.writers.file: invalid filename for log file: unrecognized placeholder {http.request.host}
{"level":"info","ts":1742132984.1881135,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
{"level":"info","ts":1742132984.1925123,"msg":"adapted config to JSON","adapter":"caddyfile"}
Error: loading initial config: loading new config: setting up custom log 'log1': loading log writer module: loading module 'file': provision caddy.logging.writers.file: invalid filename for log file: unrecognized placeholder {http.request.host}
{"level":"info","ts":1742132989.4567785,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
{"level":"info","ts":1742132989.461187,"msg":"adapted config to JSON","adapter":"caddyfile"}
Error: loading initial config: loading new config: setting up custom log 'log2': loading log writer module: loading module 'file': provision caddy.logging.writers.file: invalid filename for log file: unrecognized placeholder {http.request.host}
{"level":"info","ts":1742132991.6371255,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
{"level":"info","ts":1742132991.641008,"msg":"adapted config to JSON","adapter":"caddyfile"}
Error: loading initial config: loading new config: setting up custom log 'log6': loading log writer module: loading module 'file': provision caddy.logging.writers.file: invalid filename for log file: unrecognized placeholder {http.request.host}
{"level":"info","ts":1742132995.584764,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
{"level":"info","ts":1742132995.588706,"msg":"adapted config to JSON","adapter":"caddyfile"}
Error: loading initial config: loading new config: setting up custom log 'log6': loading log writer module: loading module 'file': provision caddy.logging.writers.file: invalid filename for log file: unrecognized placeholder {http.request.host}
{"level":"info","ts":1742133002.5841055,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
{"level":"info","ts":1742133002.5883136,"msg":"adapted config to JSON","adapter":"caddyfile"}
Error: loading initial config: loading new config: setting up custom log 'log6': loading log writer module: loading module 'file': provision caddy.logging.writers.file: invalid filename for log file: unrecognized placeholder {http.request.host}

3. Caddy version:

2.9.1-builder

4. How I installed and ran Caddy:

a. System environment:

# cat /etc/debian_version 
12.10

b. Command:

# docker compose up -d

c. Service/unit/compose file:

---
# caddy/compose.yaml

services:
  caddy:
    build:
      context: .
    container_name: caddy2
    pull_policy: build
    restart: unless-stopped
    user: "3012:3012"
    cap_add:
      - NET_ADMIN
    env_file:
      - ./secrets.env
    ports:
      - "5580:80"
      - "5443:443"
      - "5443:443/udp"
    volumes:
      - ./caddy:/etc/caddy
      - ./config:/config:rw
      - ./data:/data:rw
      - ./srv:/srv
      - /mnt/logs/caddy/:/logs

d. My complete Caddy config:

{
	# 	auto_https disable_redirects
	grace_period 10s

	email janus.ng@gmail.com

	# operation CA
	# 	acme_ca https://acme-v02.api.letsencrypt.org/directory
	# staging CA
	acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
}

(rp) {
	tls {
		dns duckdns {args[0]}
	}
	reverse_proxy {args[1]}
	log {
		output file /logs/{args[2]}.json {
			roll_size 10MB
			roll_keep 10
			roll_keep_for 168h
		}
		format json
	}
}

######
# ha.*
ha.[REDACT] homeassistant.[REDACT] {
	import rp {env.DUCKDNS_API_TOKEN} http://10.27.0.50:8123 {host}
}
ha.[REDACT] {
	import rp {env.DYNU_API_TOKEN} http://10.27.0.50:8123 {host}
}

#######
# ha2.*
ha2.[REDACT] homeassistant2.[REDACT] {
	import rp {env.DUCKDNS_API_TOKEN} http://10.27.0.65:8123 {host}
}
ha2.[REDACT] {
	import rp {env.DYNU_API_TOKEN} http://10.27.0.65:8123 {host}
}

######
# nc.*
nc.[REDACT] nextcloud.[REDACT] {
	import rp {env.DUCKDNS_API_TOKEN} http://10.27.0.65:1780 {host}
}
nc.[REDACT] {
	import rp {env.DYNU_API_TOKEN} http://10.27.0.65:1780 {host}
}

########
# plex.*
plex.[REDACT] {
	import rp {env.DUCKDNS_API_TOKEN} http://10.27.0.50:32400 {host}
}
plex.[REDACT] {
	import rp {env.DYNU_API_TOKEN} http://10.27.0.50:32400 {host}
}

#######
# v2ray.*
v2.[REDACT] {
	import rp {env.DUCKDNS_API_TOKEN} http://10.27.0.50:6080 {host}
}

v2.[REDACT] {
	import rp {env.DYNU_API_TOKEN} http://10.27.0.50:6080 {host}
}

5. Links to relevant resources:

$ cat Dockerfile
FROM caddy:2.9.1-builder AS builder

RUN xcaddy build \
	--with github.com/caddy-dns/dynu \
	--with github.com/caddy-dns/duckdns

FROM caddy:2.9.1

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

{host} only exists when there’s an incoming HTTP request.

When Caddy starts, it needs to create a log file, but since there’s no HTTP request at that moment, there’s no {host} value available. In other words, {host} doesn’t exist yet during Caddy’s startup, so it can’t be used at that point.

@francislavoie clearly explains that here.

In the links you provided, they are using hardcoded values instead. So, in your case, you’d have to use somethign like this:

# ...

ha.[REDACT] homeassistant.[REDACT] {
	import rp {env.DUCKDNS_API_TOKEN} http://10.27.0.50:8123 ha.[REDACT]
}

# ...
4 Likes

Thanks for your explanation.

1 Like

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