Skip to content

Commit 8534d30

Browse files
committed
docs: update main README with new expressions
Signed-off-by: Leonardo Di Donato <leodidonato@gmail.com>
1 parent e8f0dd8 commit 8534d30

2 files changed

Lines changed: 18 additions & 45 deletions

File tree

README.md

Lines changed: 14 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,13 @@ The **module name** is `if`.
1313
Its syntax is:
1414

1515
```caddyfile
16-
if {
17-
<expression>
18-
...
19-
} [<encoder>]
16+
if "<expression>" [<encoder>]
2017
```
2118

2219
This Caddy module logs as the `<encoder>` demands if at least one of the expressions is met.
2320

21+
The `<expression>` must be enclosed in double quotes.
22+
2423
The supported encoders are:
2524

2625
- [`json`](https://caddyserver.com/docs/caddyfile/directives/log#json)
@@ -31,23 +30,11 @@ When no `<encoder>` is specified, a default encoder (`console` or `json`) is aut
3130

3231
### Expressions
3332

34-
Expressions have the following syntax: `<field> <operator> <value>`.
35-
36-
The supported operators are:
37-
38-
- `eq`: equals to
39-
- `ne`: not equals to
40-
- `sw`: starts with
41-
42-
The **field syntax** is as per [buger/jsonparser](https://github.com/buger/jsonparser).
33+
The [language](./lang) supports simple boolean expressions.
4334

44-
So, you can assert conditions also on nested fields!
35+
An expression is - usually - in the form of `<lhs> <operator> <rhs>`. But you can compose and nest them!
4536

46-
Let's say you want to log if the user agent starts starts with some value...
47-
48-
You'd need to traverse the request object, its headers child (another object), and its "User-Agent" child (array).
49-
50-
Sounds difficult. But, it isn't! Express this field as: `request>headers>User-Agent>[0]`.
37+
Take a look at the [language documentation](./lang/README.md) for more information.
5138

5239
## Caddyfile
5340

@@ -56,9 +43,7 @@ Log JSON to stdout if the status starts with a 4 (eg., 404).
5643
```caddyfile
5744
log {
5845
output stdout
59-
format if {
60-
status sw 4
61-
} json
46+
format if "status ~~ `^4`" json
6247
}
6348
```
6449

@@ -67,24 +52,16 @@ Log to stdout in console format if the request's method is "GET".
6752
```caddyfile
6853
log {
6954
output stdout
70-
format if {
71-
request>method eq GET
72-
} console
55+
format if "request>method == `GET`" console
7356
}
7457
```
7558

7659
Log JSON to stdout if at least one of the conditions match.
7760

78-
Notice this means that condistions are in OR.
79-
8061
```caddyfile
8162
log {
8263
output stdout
83-
format if {
84-
status sw 4
85-
status sw 5
86-
request>uri eq "/"
87-
} json
64+
format if "status ~~ `^4` || status ~~ `^5` || request>uri == `/`" json
8865
}
8966
```
9067

@@ -93,9 +70,7 @@ Log JSON to stdout if the visit is from a Mozilla browser.
9370
```caddyfile
9471
log {
9572
output stdout
96-
format if {
97-
request>headers>User-Agent>[0] sw Mozilla
98-
} json
73+
format if "request>headers>User-Agent>[0] ~~ `Gecko`" json
9974
}
10075
```
10176

@@ -104,9 +79,7 @@ for responses with HTTP status equal to 200.
10479

10580
```caddyfile
10681
log {
107-
format if {
108-
status eq 200
109-
} jsonselect "{ts} {logger} {duration}"
82+
format if "status == 200" jsonselect "{ts} {logger} {duration}"
11083
}
11184
```
11285

@@ -116,17 +89,15 @@ This outputs a nice JSON like the following one:
11689
{"ts":1626440165.351731,"logger":"http.log.access.log0","duration":0.000198292}
11790
```
11891

119-
Do you wanna log Stackdriver entries only for 4** response status codes?
92+
Do you wanna log [Stackdriver](https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry) entries only for 4** response status codes?
12093

12194
Let's do it!
12295

12396
Change the level and time format, and also change the key names for the resulting JSON.
12497

12598
```caddyfile
12699
log {
127-
format if {
128-
status sw 4
129-
} jsonselect "{severity:level} {timestamp:ts} {logName:logger} {httpRequest>requestMethod:request>method} {httpRequest>protocol:request>proto} {httpRequest>status:status} {httpRequest>responseSize:size} {httpRequest>userAgent:request>headers>User-Agent>[0]}" {
100+
format if "status ~~ `^4`" jsonselect "{severity:level} {timestamp:ts} {logName:logger} {httpRequest>requestMethod:request>method} {httpRequest>protocol:request>proto} {httpRequest>status:status} {httpRequest>responseSize:size} {httpRequest>userAgent:request>headers>User-Agent>[0]} {httpRequest>requestUrl:request>uri}" {
130101
level_format "upper"
131102
time_format "rfc3339_nano"
132103
}
@@ -136,7 +107,7 @@ log {
136107
This outputs:
137108

138109
```json
139-
{"severity":"INFO","timestamp":"2021-07-19T15:44:44.077586Z","logName":"http.log.access.log0","httpRequest":{"requestMethod":"GET","protocol":"HTTP/2.0","status":200,"responseSize":11348,"userAgent":"Mozilla/5.0 ..."}}
110+
{"severity":"INFO","timestamp":"2021-07-19T15:44:44.077586Z","logName":"http.log.access.log0","httpRequest":{"requestMethod":"GET","protocol":"HTTP/2.0","status":200,"responseSize":11348,"userAgent":"Mozilla/5.0 ...","requestUrl":"/leo"}}
140111
```
141112

142113
## Try it out

plugin.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ func (ce ConditionalEncoder) EncodeEntry(e zapcore.Entry, fields []zapcore.Field
100100
data = data[pos:]
101101
}
102102

103+
// Extract values
103104
values := make(map[string]interface{})
104105
for _, key := range lang.Fields {
105106
path := strings.Split(key, ">")
@@ -120,19 +121,20 @@ func (ce ConditionalEncoder) EncodeEntry(e zapcore.Entry, fields []zapcore.Field
120121
}
121122
}
122123

124+
// Evaluate the expression against values
123125
res, err := lang.Execute(ce.Eval, values)
124126
emit, ok := res.(bool)
125127
if !ok {
126128
ce.Logger(&ce).Error("expecting a boolean expression", zap.String("return", fmt.Sprintf("%T", res)))
127-
goto output
129+
goto emitNothing
128130
}
129131

130132
if emit {
131133
// Using the original (wrapped) encoder for output
132134
return ce.Encoder.EncodeEntry(e, fields)
133135
}
134136

135-
output:
137+
emitNothing:
136138
buf.Reset()
137139
return buf, nil
138140
}

0 commit comments

Comments
 (0)