experimental TCP hook for logrus

This commit is contained in:
Christian Schwarz 2017-09-23 12:58:13 +02:00
parent 9465b593f9
commit 83edcb3889
2 changed files with 80 additions and 1 deletions

View File

@ -5,6 +5,7 @@ import (
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"os"
"time"
)
type LoggingConfig struct {
@ -12,6 +13,15 @@ type LoggingConfig struct {
Level logrus.Level
Format LogFormat
}
TCP *TCPLoggingConfig
}
type TCPLoggingConfig struct {
Level logrus.Level
Format LogFormat
Net string
Address string
RetryInterval time.Duration
}
func parseLogging(i interface{}) (c *LoggingConfig, err error) {
@ -28,6 +38,13 @@ func parseLogging(i interface{}) (c *LoggingConfig, err error) {
Level string
Format string
}
TCP struct {
Level string
Format string
Net string
Address string
RetryInterval string `mapstructure:"retry_interval"`
}
}
if err = mapstructure.Decode(i, &asMap); err != nil {
return nil, errors.Wrap(err, "mapstructure error")
@ -48,6 +65,20 @@ func parseLogging(i interface{}) (c *LoggingConfig, err error) {
c.Stdout.Format = format
}
if asMap.TCP.Address != "" {
c.TCP = &TCPLoggingConfig{}
c.TCP.Format, err = parseLogFormat(asMap.TCP.Format)
if err != nil {
return nil, errors.Wrap(err, "cannot parse log format")
}
c.TCP.Level, err = logrus.ParseLevel(asMap.TCP.Level)
if err != nil {
return nil, errors.Wrap(err, "cannot parse level")
}
c.TCP.RetryInterval, err = time.ParseDuration(asMap.TCP.RetryInterval)
c.TCP.Net, c.TCP.Address = asMap.TCP.Net, asMap.TCP.Address
}
return c, nil
}
@ -96,9 +127,12 @@ func (c *LoggingConfig) MakeLogrus() (l logrus.FieldLogger) {
log := logrus.New()
log.Out = os.Stdout
log.Level = c.Stdout.Level
log.Level = logrus.DebugLevel // FIXTHIS IN LOGRUS
log.Formatter = c.Stdout.Format.Formatter()
th := &TCPHook{Formatter: JSONFormatter{}, MinLevel: c.TCP.Level, Net: c.TCP.Net, Address: c.TCP.Address, RetryInterval: c.TCP.RetryInterval}
log.Hooks.Add(th)
return log
}

View File

@ -6,6 +6,7 @@ import (
"fmt"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"net"
"strings"
"time"
)
@ -121,6 +122,50 @@ func (f JSONFormatter) Format(e *logrus.Entry) ([]byte, error) {
}
type TCPHook struct {
Formatter logrus.Formatter
MinLevel logrus.Level
Net, Address string
RetryInterval time.Duration
conn net.Conn
retry time.Time
}
func (h *TCPHook) Levels() []logrus.Level {
for i := range logrus.AllLevels { // assume it's ordered
if logrus.AllLevels[i] == h.MinLevel {
return logrus.AllLevels[:i]
}
}
return logrus.AllLevels
}
func (h *TCPHook) Fire(e *logrus.Entry) error {
b, err := h.Formatter.Format(e)
if err != nil {
return err
}
if h.conn == nil {
if time.Now().Sub(h.retry) < h.RetryInterval {
return errors.New("TCP hook reconnect prohibited by retry interval")
}
h.conn, err = net.Dial(h.Net, h.Address)
if err != nil {
h.retry = time.Now()
return errors.Wrap(err, "cannot dial")
}
}
_, err = h.conn.Write(b)
if err != nil {
h.conn.Close()
h.conn = nil
}
return nil
}
type nopWriter int
func (w nopWriter) Write(p []byte) (n int, err error) { return len(p), nil }