Monitoring Log Volume - `zerolog`

Writing a custom write adapter

package log_instrumentation

import (
	"io"

	"github.com/rs/zerolog"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promauto"
)

var (
	logMessagesLines = promauto.NewCounterVec(prometheus.CounterOpts{
		Name: "log_messages_lines_total",
		Help: "Total number of log messages.",
	}, []string{"level"})

	logMessagesBytes = promauto.NewCounterVec(prometheus.CounterOpts{
		Name: "log_messages_size_bytes_total",
		Help: "Total size of log messages.",
	}, []string{"level"})
)

type InstrumentedWriteAdapter struct {
	io.Writer
}

func (lw InstrumentedWriteAdapter) WriteLevel(l zerolog.Level, p []byte) (n int, err error) {
	level := l.String()
	logMessagesLines.WithLabelValues(level).Inc()
	logMessagesBytes.WithLabelValues(level).Add(float64(len(p)))
	return lw.Write(p)
}

func (lw InstrumentedWriteAdapter) Close() error {
	if closer, ok := lw.Writer.(io.Closer); ok {
		return closer.Close()
	}
	return nil
}

Usage

package log_instrumentation

import (
	"os"
	"testing"

	"github.com/rs/zerolog"

	"github.com/prometheus/client_golang/prometheus/testutil"

	"github.com/stretchr/testify/assert"
)

func TestHook(t *testing.T) {
	logger := zerolog.New(os.Stdout).With().Logger()
	logger = logger.Output(&InstrumentedWriteAdapter{os.Stdout})

	logger.Info().Msg("hello world")
	logger.Info().Msg("hello world")
	logger.Error().Msg("hello world")

	assert.Equal(t, float64(2), testutil.ToFloat64(logMessagesLines.WithLabelValues("info")))
	assert.Equal(t, float64(82), testutil.ToFloat64(logMessagesBytes.WithLabelValues("info")))

	assert.Equal(t, float64(1), testutil.ToFloat64(logMessagesLines.WithLabelValues("error")))
	assert.Equal(t, float64(42), testutil.ToFloat64(logMessagesBytes.WithLabelValues("error")))
}