Monitoring Log Volume - `logrus`

Writing a custom formatter

package log_instrumentation

import (
	"github.com/sirupsen/logrus"

	"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 InstrumentedTextFormatter struct {
	logrus.TextFormatter
}

func (f *InstrumentedTextFormatter) Format(e *logrus.Entry) ([]byte, error) {
	bs, err := f.TextFormatter.Format(e)
	level := e.Level.String()
	logMessagesLines.WithLabelValues(level).Inc()
	logMessagesBytes.WithLabelValues(level).Add(float64(len(bs)))
	return bs, err
}

type InstrumentedJsonFormatter struct {
	logrus.JSONFormatter
}

func (f *InstrumentedJsonFormatter) Format(e *logrus.Entry) ([]byte, error) {
	bs, err := f.JSONFormatter.Format(e)
	level := e.Level.String()
	logMessagesLines.WithLabelValues(level).Inc()
	logMessagesBytes.WithLabelValues(level).Add(float64(len(bs)))
	return bs, err
}

Usage

package log_instrumentation

import (
	"testing"

	"github.com/sirupsen/logrus"

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

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

func TestHook(t *testing.T) {
	formatter := &InstrumentedTextFormatter{}
	formatter.DisableTimestamp = true

	logger := logrus.New()
	logger.SetFormatter(formatter)

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

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

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