1
0
Fork 0
mirror of https://github.com/Luzifer/elastic_cron.git synced 2024-11-09 22:20:04 +00:00
elastic_cron/syslog.go

107 lines
2.1 KiB
Go
Raw Normal View History

2016-02-26 17:44:10 +00:00
package main
import (
"bytes"
"fmt"
"io"
"net"
"text/template"
2016-02-26 17:44:10 +00:00
"time"
"github.com/cenkalti/backoff"
)
const (
readWriteTimeout = 1 * time.Second
tcpDialTimeout = 5 * time.Second
)
func NewSyslogAdapter(address, logFormat string) (*SyslogAdapter, error) {
2016-02-26 17:44:10 +00:00
return &SyslogAdapter{
address: address,
logFormat: logFormat,
2016-02-26 17:44:10 +00:00
dialer: &net.Dialer{
Timeout: tcpDialTimeout,
},
}, nil
}
type message struct {
Date time.Time
JobName string
Message string
Severity int
}
type SyslogAdapter struct {
address string
logFormat string
dialer *net.Dialer
}
func (a *SyslogAdapter) formatMessage(m *message) (string, error) {
t, err := template.New("logFormat").Funcs(template.FuncMap{
"syslogpri": func(pri int) int { return 16*8 + pri },
}).Parse(a.logFormat)
if err != nil {
return "", err
}
buf := bytes.NewBufferString("")
if err := t.Execute(buf, map[string]interface{}{
"Date": m.Date,
"JobName": m.JobName,
"Hostname": cfg.Hostname,
"Message": m.Message,
"Severity": m.Severity,
}); err != nil {
return "", err
}
return buf.String(), nil
2016-02-26 17:44:10 +00:00
}
func (a *SyslogAdapter) Stream(logstream chan *message) {
backoff.Retry(func() error {
conn, err := a.dialer.Dial("tcp", a.address)
if err != nil {
fmt.Printf("syslog: Unable to dial to remote address\n")
return fmt.Errorf("Catch me if you can.")
}
defer conn.Close()
b := new(bytes.Buffer)
for msg := range logstream {
b.Reset()
msgLine, err := a.formatMessage(msg)
if err != nil {
return err
}
fmt.Fprintln(b, msgLine)
2016-02-26 17:44:10 +00:00
if err := conn.SetDeadline(time.Now().Add(readWriteTimeout)); err != nil {
fmt.Printf("syslog: Unable to set deadline: %s\n", err)
return fmt.Errorf("Catch me if you can.")
}
logLine := b.Bytes()
written, err := io.Copy(conn, b)
if err != nil {
if written > 0 {
fmt.Printf("syslog: (%d/%d) %s\n", written, len(logLine), err)
} else {
fmt.Printf("syslog: %s\n", err)
}
return fmt.Errorf("syslog: %s", err)
}
}
fmt.Printf("syslog: I got out of the channel watch. This should never happen.\n")
return fmt.Errorf("Wat? Why am I here?")
}, &backoff.ZeroBackOff{})
}