Log_skip for response status

1. The problem I’m having:

I’m trying to only log access logs that are >=400. I’ve tried various directives, matchers and conditionals with no luck. I’d like to be able to do something like

log_skip {
 status 200
}

or

@no_log status 200
log_skip @no_log

3. Caddy version:

2.9.1

4. How I installed and ran Caddy:

na

d. My complete Caddy config:

{
	servers :18443 {
		protocols h1 h2

		listener_wrappers {
			proxy_protocol {
				fallback_policy require
			}
		}
	}
}

localhost:18443 {
	log {
		output file /var/log/caddy/access.log {
			mode 644
		}
		format transform `{access_log}`
	}

   # tls on_demand is necessary for caddy auto sign cert on the fly.
    tls {
		on_demand
		client_auth {
			mode require_and_verify
			trusted_ca_cert_file ./client-ca.pem
		}
    }

	log_append access_log {http.access.log}
	logger

	test_http {
		replacer {
			http.access.log
		}
	}
}

logger is a http.handlers.logger custom plugin I wrote that forms a log entry structure with all the fields I need. I use transform encoder to then use the replacer the plugin generates by using log_append

5. Links to relevant resources:

This is the wrong way to do it. For custom log structure, your module needs to be a log encoder module, not handler.

This works. You just need to adapt it.

example.com {
	log
	respond /400 400
	respond /200 200
	intercept {
		@200 {
			status 200
		}
		handle_response @200 {
			log_skip
		}
	}
}

Would the intercept directive be the way to go to handle the following scenario? Especially in reverse proxy setups.

  • Internal requests (originating from LAN): Log only requests that return a different HTTP status code than 200.
  • External requests (originating from WAN): Log all requests, regardless of the returned status code.

(Split DNS in use)

The log_skip accept a request matcher. It is clear how to use a remote_ip (or a more elaborated CEL version) to determine if the requests comes from inside or outside, but I assume the status code is undetermined at that point.

But intercept knows the status code. I always encourage experimentation to learn any tool thoroughly. Give it a shot, see how it behaves.

I have certainly been experimenting and keep doing so :blush:

But within the context of reverse proxies, wouldn’t it be better to use handle_response rather than intercept?

My idea would be something like…

example.com {
    <log options omitted>
    reverse_proxy localhost:8000 {
        @ok status 1xx 2xx 3xx
        handle_response @ok {
            copy_response

            @local `remote_ip('192.168.1.10', '192.168.1.11')`
            log_skip @local
        }
   }
}

Where the intention would be to log all external requests, and both 4xx and 5xx errors originating from two local IP addresses.

PS: I think my questions/comments still align with the original question, but I am happy to create a separated message if preferred.

I also tried the intercept example from Log_skip for response status - #2 by Mohammed90.

It does work, but if the site block uses a reverse proxy, the request headers get duplicated. I think this is the equivalent of having a copy_response_headers in a handle_response block, but I could be wrong. By reading intercept (Caddyfile directive) — Caddy Documentation , my understanding is that intercept should not be used in a reverse proxy setup. Better to use handle_response within the reverse_proxy block.

I’m investigating the duplication of headers, but your intercept_response approach works just as well.