Skip to content

leodido/caddy-conditional-logging

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Caddy Conditional Logging

Hey Caddy, please log only if ...

This plugin implements a logging encoder that let's you log depending on conditions.

Conditions can be express through a simple expression language.

Module

The module name is if.

Its syntax is:

if "<expression>" [<encoder>]

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

The <expression> must be enclosed in double quotes.

The supported encoders are:

When no <encoder> is specified, a default encoder (console or json) is automatically set up depending on the environments.

Expressions

The language supports simple boolean expressions.

An expression is - usually - in the form of <lhs> <operator> <rhs>. But you can compose and nest them!

Take a look at the language documentation for more information.

Caddyfile

Log JSON to stdout if the status starts with a 4 (eg., 404).

log {
  output stdout
  format if "status ~~ `^4`" json
}

Log to stdout in console format if the request's method is "GET".

log {
  output stdout
  format if "request>method == `GET`" console
}

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

log {
  output stdout
  format if "status ~~ `^4` || status ~~ `^5` || request>uri == `/`" json
}

Log JSON to stdout if the visit is from a Mozilla browser.

log {
  output stdout
  format if "request>headers>User-Agent>[0] ~~ `Gecko`" json
}

Log a JSON containing only the timestamp, the logger name, and the duration for responses with HTTP status equal to 200.

log {
  format if "status == 200" jsonselect "{ts} {logger} {duration}"
}

This outputs a nice JSON like the following one:

{"ts":1626440165.351731,"logger":"http.log.access.log0","duration":0.000198292}

Do you wanna log Stackdriver entries only for 4** response status codes?

Let's do it!

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

log {
  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}" {
    level_format "upper"
    time_format "rfc3339_nano"
  }
}

This outputs:

{"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"}}

Try it out

From the root directoy of this project, run:

xcaddy run

Then open https://localhost:2015, go on existing and non-existing pages, and observe the access logs.

To install xcaddy in case you need to, run:

go get -u github.com/caddyserver/xcaddy/cmd/xcaddy

Build

To build Caddy with this module in, execute:

xcaddy build --with github.com/leodido/caddy-conditional-logging

Analytics