Notification on specific logs

So I am utilising the caddy-security plugins to provide me with some authentication for my caddy server. This is working as expected.

What I would like is to generate a plugin that hooks into the caddy logs and when a specific log is found (authorisation granted / failed) it can notify me via a method of my choosing (Pushover in my case)

At the moment I am struggling to understand what namespace I need to hook into to listen to all the logs. I thought about creating a filter, but that only affect a field on every log.

I then thought about a specific writer, which is a notification writer, and then adding some filters into that to only capture what I need, but it started to get really messy.

Could do with some advice to set me on the right path.

I’m sure there are otherway to achieve this, if so, I am all ears.

You could either write a writer or an encoder module. You could implement your module as a pass-through (similar to filter encoder) which wraps another module to retain “normal” behaviour if you want. Or you could just set up your notifier as a separate logger that doesn’t emit anything.

If you use a writer then you’d need to decode the log; you’d probably use a JSON encoder to pair with it, so you would decode/unmarshal the JSON log and read it to do whatever.

If you use an encoder and you implement EncodeEntry(zapcore.Entry, []zapcore.Field) then you have access to Entry which has the message, level, logger name (namespace), etc, and you can implement your notification logic there, and use output discard to throw away stuff passed to that logger.

You could use the existing net writer and process logs with a separate server reading from a TCP stream.

Thank you for your response and guidence @francislavoie.

A few follow up questions.

This log i am looking to notify on can appear on any site I have configured, so I can’t create a new log for a specific hostname.

Assuming I was creating a writer, I would use the below config with NEW_WRITER being the newly created plugin. This would infact send all my logs to this new writer and override the logs going anywhere else, such as the console. I dont think this would work for me as I would want it to intercept the log stream rather then redirect it.

log default {
	output NEW_WRITER

Could I do instead:

log default {
	output stdout
	format json
log notifylogger {
	output NEW_WRITER
	include my.namespace

Would this ensure that the logs for my.namespace show up not only in std out but also my other logger, of does caddy only match one?

The other option would be as you said to create an encoder like the filter encoder.

log default {
	output stdout
	format NEW_ENCODER {
		wrap json

This I assume is what you mean by retaining the existing logging output and format, but intercepting each log.

Have I understood your response correctly?


Yes, if no include or exclude is specified for a logger, it will catch all logs. If you use include then only logs of that namespace will be passed to that logger. They aren’t mutually exclusive, the same log can be handled by more than one logger.


This topic was automatically closed after 30 days. New replies are no longer allowed.