This commit is contained in:
Francis Lavoie 2024-04-22 06:47:40 -04:00
parent 70d31a6959
commit 0474a06c00
No known key found for this signature in database
GPG key ID: 0F66EE1687682239
6 changed files with 109 additions and 17 deletions

View file

@ -342,7 +342,7 @@ You can use any [Caddy placeholders](/docs/conventions#placeholders) in the Cadd
| `{port}` | `{http.request.port}` | | `{port}` | `{http.request.port}` |
| `{query.*}` | `{http.request.uri.query.*}` | | `{query.*}` | `{http.request.uri.query.*}` |
| `{query}` | `{http.request.uri.query}` | | `{query}` | `{http.request.uri.query}` |
| `{re.*.*}` | `{http.regexp.*.*}` | | `{re.*}` | `{http.regexp.*}` |
| `{remote_host}` | `{http.request.remote.host}` | | `{remote_host}` | `{http.request.remote.host}` |
| `{remote_port}` | `{http.request.remote.port}` | | `{remote_port}` | `{http.request.remote.port}` |
| `{remote}` | `{http.request.remote}` | | `{remote}` | `{http.request.remote}` |

View file

@ -57,6 +57,8 @@ Directive | Description
**[import](/docs/caddyfile/directives/import)** | Include snippets or files **[import](/docs/caddyfile/directives/import)** | Include snippets or files
**[invoke](/docs/caddyfile/directives/invoke)** | Invoke a named route **[invoke](/docs/caddyfile/directives/invoke)** | Invoke a named route
**[log](/docs/caddyfile/directives/log)** | Enables access/request logging **[log](/docs/caddyfile/directives/log)** | Enables access/request logging
**[log_append](/docs/caddyfile/directives/log_append)** | Append a field to the access log
**[log_skip](/docs/caddyfile/directives/log_skip)** | Skip access logging for matched requests
**[map](/docs/caddyfile/directives/map)** | Maps an input value to one or more outputs **[map](/docs/caddyfile/directives/map)** | Maps an input value to one or more outputs
**[method](/docs/caddyfile/directives/method)** | Change the HTTP method internally **[method](/docs/caddyfile/directives/method)** | Change the HTTP method internally
**[metrics](/docs/caddyfile/directives/metrics)** | Configures the Prometheus metrics exposition endpoint **[metrics](/docs/caddyfile/directives/metrics)** | Configures the Prometheus metrics exposition endpoint
@ -70,7 +72,6 @@ Directive | Description
**[rewrite](/docs/caddyfile/directives/rewrite)** | Rewrites the request internally **[rewrite](/docs/caddyfile/directives/rewrite)** | Rewrites the request internally
**[root](/docs/caddyfile/directives/root)** | Set the path to the site root **[root](/docs/caddyfile/directives/root)** | Set the path to the site root
**[route](/docs/caddyfile/directives/route)** | A group of directives treated literally as single unit **[route](/docs/caddyfile/directives/route)** | A group of directives treated literally as single unit
**[skip_log](/docs/caddyfile/directives/skip_log)** | Skip access logging for matched requests
**[templates](/docs/caddyfile/directives/templates)** | Execute templates on the response **[templates](/docs/caddyfile/directives/templates)** | Execute templates on the response
**[tls](/docs/caddyfile/directives/tls)** | Customize TLS settings **[tls](/docs/caddyfile/directives/tls)** | Customize TLS settings
**[tracing](/docs/caddyfile/directives/tracing)** | Integration with OpenTelemetry tracing **[tracing](/docs/caddyfile/directives/tracing)** | Integration with OpenTelemetry tracing
@ -123,7 +124,8 @@ map
vars vars
fs fs
root root
skip_log log_append
log_skip
header header
copy_response_headers # only in reverse_proxy's handle_response block copy_response_headers # only in reverse_proxy's handle_response block

View file

@ -32,7 +32,9 @@ To configure Caddy's runtime logs, see the [`log` global option](/docs/caddyfile
The `log` directive applies to the hostnames of the site block it appears in, unless overridden with the `hostnames` subdirective. The `log` directive applies to the hostnames of the site block it appears in, unless overridden with the `hostnames` subdirective.
When configured, by default all requests to the site will be logged. To conditionally skip some requests from logging, use the [`skip_log` directive](skip_log). When configured, by default all requests to the site will be logged. To conditionally skip some requests from logging, use the [`log_skip` directive](log_skip).
To add custom fields to the log entries, use the [`log_append` directive](log_append).
- [Syntax](#syntax) - [Syntax](#syntax)

View file

@ -0,0 +1,39 @@
---
title: log_append (Caddyfile directive)
---
# log_append
Appends a field to the access log for the current request.
This should be used alongside the [`log` directive](log) which is required to enable access logging in the first place.
The value may be a static string, or a [placeholder](/docs/caddyfile/concepts#placeholders) which will be replaced with the value of the placeholder at the time of the request.
## Syntax
```caddy-d
log_append [<matcher>] <key> <value>
```
## Examples
Display in the logs the area of the site that the request is being served from, either `static` or `dynamic`:
```caddy
example.com {
log
handle /static* {
log_append area "static"
respond "Static response!"
}
handle {
log_append area "dynamic"
reverse_proxy localhost:9000
}
}
```

View file

@ -6,7 +6,7 @@ title: log_skip (Caddyfile directive)
Skips access logging for matched requests. Skips access logging for matched requests.
This should be used alongside the [`log` directive](/docs/caddyfile/directives/log) to skip logging requests that are not relevant for your needs. This should be used alongside the [`log` directive](log) to skip logging requests that are not relevant for your needs.
Prior to v2.8.0, this directive was named `skip_log`, but was renamed for consistency with other directives. Prior to v2.8.0, this directive was named `skip_log`, but was renamed for consistency with other directives.

View file

@ -456,20 +456,37 @@ expression header_regexp('<name>', '<field>', '<regexp>')
expression header_regexp('<field>', '<regexp>') expression header_regexp('<field>', '<regexp>')
``` ```
Like [`header`](#header), but supports regular expressions. Capture groups can be accessed via [placeholder](/docs/caddyfile/concepts#placeholders) like `{re.name.capture_group}` where `name` is the name of the regular expression (optional, but recommended) and `capture_group` is either the name or number of the capture group in the expression. Capture group `0` is the full regexp match, `1` is the first capture group, `2` is the second capture group, and so on. Like [`header`](#header), but supports regular expressions.
The regular expression language used is RE2, included in Go. See the [RE2 syntax reference](https://github.com/google/re2/wiki/Syntax) and the [Go regexp syntax overview](https://pkg.go.dev/regexp/syntax). The regular expression language used is RE2, included in Go. See the [RE2 syntax reference](https://github.com/google/re2/wiki/Syntax) and the [Go regexp syntax overview](https://pkg.go.dev/regexp/syntax).
As of v2.8.0, if `name` is _not_ provided, the name will be taken from the named matcher's name. For example a named matcher `@foo` will cause this matcher to be named `foo`. The main advantage of specifying a name is if more than one regexp matcher is used in the same named matcher.
Capture groups can be accessed via [placeholder](/docs/caddyfile/concepts#placeholders) in directives after matching:
- `{re.<name>.<capture_group>}` where:
- `<name>` is the name of the regular expression,
- `<capture_group>` is either the name or number of the capture group in the expression.
- `{re.<capture_group>}` without a name, is also populated for convenience. The caveat is that if multiple regexp matchers are used in sequence, then the placeholder values will be overwritten by the next matcher.
Capture group `0` is the full regexp match, `1` is the first capture group, `2` is the second capture group, and so on. So `{re.foo.1}` or `{re.1}` will both hold the value of the first capture group.
Only one regular expression is supported per header field. Multiple different fields will be AND'ed. Only one regular expression is supported per header field. Multiple different fields will be AND'ed.
#### Example: #### Example:
Match requests where the Cookie header contains `login_` followed by a hex string, with a capture group that can be accessed with `{re.login.1}`. Match requests where the Cookie header contains `login_` followed by a hex string, with a capture group that can be accessed with `{re.login.1}` or `{re.1}`.
```caddy-d ```caddy-d
@login header_regexp login Cookie login_([a-f0-9]+) @login header_regexp login Cookie login_([a-f0-9]+)
``` ```
This can be simplified by omitting the name, which will be inferred from the named matcher:
```caddy-d
@login header_regexp Cookie login_([a-f0-9]+)
```
Or the same, using a [CEL expression](#expression): Or the same, using a [CEL expression](#expression):
```caddy-d ```caddy-d
@ -684,26 +701,41 @@ expression path_regexp('<name>', '<regexp>')
expression path_regexp('<regexp>') expression path_regexp('<regexp>')
``` ```
Like [`path`](#path), but supports regular expressions. Write the pattern on the URI-decoded/unescaped form of the path. Like [`path`](#path), but supports regular expressions. Runs against the URI-decoded/unescaped path.
The regular expression language used is RE2, included in Go. See the [RE2 syntax reference](https://github.com/google/re2/wiki/Syntax) and the [Go regexp syntax overview](https://pkg.go.dev/regexp/syntax). The regular expression language used is RE2, included in Go. See the [RE2 syntax reference](https://github.com/google/re2/wiki/Syntax) and the [Go regexp syntax overview](https://pkg.go.dev/regexp/syntax).
Capture groups can be accessed via [placeholder](/docs/caddyfile/concepts#placeholders) like `{re.name.capture_group}` where `name` is the name of the regular expression (optional, but recommended) and `capture_group` is either the name or number of the capture group in the expression. Capture group `0` is the full regexp match, `1` is the first capture group, `2` is the second capture group, and so on. As of v2.8.0, if `name` is _not_ provided, the name will be taken from the named matcher's name. For example a named matcher `@foo` will cause this matcher to be named `foo`. The main advantage of specifying a name is if more than one regexp matcher is used in the same named matcher.
Capture groups can be accessed via [placeholder](/docs/caddyfile/concepts#placeholders) in directives after matching:
- `{re.<name>.<capture_group>}` where:
- `<name>` is the name of the regular expression,
- `<capture_group>` is either the name or number of the capture group in the expression.
- `{re.<capture_group>}` without a name, is also populated for convenience. The caveat is that if multiple regexp matchers are used in sequence, then the placeholder values will be overwritten by the next matcher.
Capture group `0` is the full regexp match, `1` is the first capture group, `2` is the second capture group, and so on. So `{re.foo.1}` or `{re.1}` will both hold the value of the first capture group.
There can only be one `path_regexp` pattern per named matcher. There can only be one `path_regexp` pattern per named matcher.
#### Example: #### Example:
Match requests where the path ends a 6 character hex string followed by `.css` or `.js` as the file extension, with capture groups that can be accessed with `{re.static.1}` and `{re.static.2}` for each part enclosed in `( )`, respectively: Match requests where the path ends a 6 character hex string followed by `.css` or `.js` as the file extension, with capture groups (parts enclosed in `( )`), that can be accessed with `{re.static.1}` and `{re.static.2}` (or `{re.1}` and `{re.2}`), respectively:
```caddy-d ```caddy-d
@static path_regexp static \.([a-f0-9]{6})\.(css|js)$ @static path_regexp static \.([a-f0-9]{6})\.(css|js)$
``` ```
This can be simplified by omitting the name, which will be inferred from the named matcher:
```caddy-d
@static path_regexp \.([a-f0-9]{6})\.(css|js)$
```
Or the same, using a [CEL expression](#expression), also validating that the [`file`](#file) exists on disk: Or the same, using a [CEL expression](#expression), also validating that the [`file`](#file) exists on disk:
```caddy-d ```caddy-d
@static `path_regexp('static', '\.([a-f0-9]{6})\.(css|js)$') && file()` @static `path_regexp('\.([a-f0-9]{6})\.(css|js)$') && file()`
``` ```
@ -851,16 +883,33 @@ vars {magic_number} 3 5
vars_regexp [<name>] <variable> <regexp> vars_regexp [<name>] <variable> <regexp>
``` ```
Like [`vars`](#vars), but supports regular expressions. Capture groups can be accessed via [placeholder](/docs/caddyfile/concepts#placeholders) like `{re.name.capture_group}` where `name` is the name of the regular expression (optional, but recommended) and `capture_group` is either the name or number of the capture group in the expression. Capture group `0` is the full regexp match, `1` is the first capture group, `2` is the second capture group, and so on. Like [`vars`](#vars), but supports regular expressions.
The regular expression language used is RE2, included in Go. See the [RE2 syntax reference](https://github.com/google/re2/wiki/Syntax) and the [Go regexp syntax overview](https://pkg.go.dev/regexp/syntax). The regular expression language used is RE2, included in Go. See the [RE2 syntax reference](https://github.com/google/re2/wiki/Syntax) and the [Go regexp syntax overview](https://pkg.go.dev/regexp/syntax).
As of v2.8.0, if `name` is _not_ provided, the name will be taken from the named matcher's name. For example a named matcher `@foo` will cause this matcher to be named `foo`. The main advantage of specifying a name is if more than one regexp matcher is used in the same named matcher.
Capture groups can be accessed via [placeholder](/docs/caddyfile/concepts#placeholders) in directives after matching:
- `{re.<name>.<capture_group>}` where:
- `<name>` is the name of the regular expression,
- `<capture_group>` is either the name or number of the capture group in the expression.
- `{re.<capture_group>}` without a name, is also populated for convenience. The caveat is that if multiple regexp matchers are used in sequence, then the placeholder values will be overwritten by the next matcher.
Capture group `0` is the full regexp match, `1` is the first capture group, `2` is the second capture group, and so on. So `{re.foo.1}` or `{re.1}` will both hold the value of the first capture group.
There can only be one `vars_regexp` matcher per named matcher. There can only be one `vars_regexp` matcher per named matcher.
#### Example: #### Example:
Match an output of the [`map` directive](/docs/caddyfile/directives/map) named `magic_number` for a value starting with `4`, capturing the value in a capture group: Match an output of the [`map` directive](/docs/caddyfile/directives/map) named `magic_number` for a value starting with `4`, capturing the value in a capture group that can be accessed with `{re.magic.1}` or `{re.1}`:
```caddy-d ```caddy-d
vars_regexp magic {magic_number} ^(4.*) @magic vars_regexp magic {magic_number} ^(4.*)
```
This can be simplified by omitting the name, which will be inferred from the named matcher:
```caddy-d
@magic vars_regexp {magic_number} ^(4.*)
``` ```