Logging requests in Caddy

Read more articles on Cloud, Caddy
Logging requests in Caddy

Subscribe

Get updated 1 - 2 times a month when new articles are published, no spam ever.

In this article you going to learn how to log requests and various options available to configure logging using the log directive.

Enable logging using log directive #

Use the log directive to enable request logs.

:80 {
	log

	handle {
		respond "Hello World"
	}
}
Caddyfile

Visit http://localhost:80 and you will see the request being logged.

Be default the log format is json.

{"level":"info","ts":1690074874.4119136,"logger":"http.log.access","msg":"handled request","request":{"remote_ip":"172.17.0.1","remote_port":"39286","proto":"HTTP/1.1","method":"GET","host":"localhost:8080","uri":"/","headers":{"Sec-Ch-Ua":["\"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"114\", \"Brave\";v=\"114\""],"User-Agent":["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"],"Sec-Gpc":["1"],"Accept-Encoding":["gzip, deflate, br"],"Cache-Control":["max-age=0"],"Sec-Ch-Ua-Platform":["\"macOS\""],"Upgrade-Insecure-Requests":["1"],"Sec-Fetch-Mode":["navigate"],"Sec-Fetch-Dest":["document"],"Cookie":[],"Connection":["keep-alive"],"Sec-Fetch-User":["?1"],"Sec-Ch-Ua-Mobile":["?0"],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8"],"Sec-Fetch-Site":["none"],"Accept-Language":["en-US,en;q=0.9"]}},"user_id":"","duration":0.000011793,"size":11,"status":200,"resp_headers":{"Server":["Caddy"],"Content-Type":["text/plain; charset=utf-8"]}}

Change log format #

There two formats available json and console, the default is json.

Use the format directive and set it to console as follows.

:80 {
	log {
		format console
	}

	handle {
		respond "Hello World"
	}
}
Caddyfile

Most of it is still json even after chaing it to console.

2023/07/23 02:49:05.900	INFO	http.log.access.log0	handled request	{"request": {"remote_ip": "172.17.0.1", "remote_port": "39862", "proto": "HTTP/1.1", "method": "GET", "host": "localhost:8080", "uri": "/", "headers": {"Upgrade-Insecure-Requests": ["1"], "Accept": ["text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8"], "Sec-Gpc": ["1"], "Sec-Fetch-Dest": ["document"], "Sec-Ch-Ua-Platform": ["\"macOS\""], "User-Agent": ["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"], "Accept-Language": ["en-US,en;q=0.9"], "Sec-Fetch-Site": ["none"], "Sec-Fetch-User": ["?1"], "Accept-Encoding": ["gzip, deflate, br"], "Cookie": [], "Connection": ["keep-alive"], "Cache-Control": ["max-age=0"], "Sec-Ch-Ua": ["\"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"114\", \"Brave\";v=\"114\""], "Sec-Ch-Ua-Mobile": ["?0"], "Sec-Fetch-Mode": ["navigate"]}}, "user_id": "", "duration": 0.00001076, "size": 11, "status": 200, "resp_headers": {"Server": ["Caddy"], "Content-Type": ["text/plain; charset=utf-8"]}}

Filter fields #

By default log spits out everything inside the log. But use can use the filter directive to perform operations on the fields as required.

For example, to hide the Authorization header from the log do as follows.

:80 {
	log {
		format filter {
			wrap console
			fields {
				request>headers>Authorization delete
			}
		}
	}

	handle {
		respond "Hello World"
	}
}
Caddyfile

This will remove the Authorization header from the logs.

filter works slightly differently, it is set as a format value and the actual format (json or console) is set inside the wrap property.

You can perform many more operations using filter such as replace and hash. Read about all the filter options here.

Take another example, let's say you want to remove the q param from query, you would do it as follows.

:80 {
	log {
		format filter {
			wrap console
			fields {
				request>uri query {
					delete q
				}
			}
		}
	}

	handle {
		respond "Hello World"
	}
}
Caddyfile

Read the log documentation to learn more about query and cookie filters.

Skipping logs #

Let's say you want to skip log for a specific section. For example, assume you have two handle blogs and you don't want to logs requests for one handle. You can use skip_log directive.

:80 {
	log {
		format filter {
			wrap console
			fields {
				request>uri query {
					delete q
				}
			}
		}
	}
    
	handle /auth/api* {
    	skip_log
		respond "Auth API"
	}

	handle {
		respond "Hello World"
	}
}
Caddyfile

Subscribe

Get updated 1 - 2 times a month when new articles are published, no spam ever.

    TheDeveloperCafe © 2022-2024