-
Notifications
You must be signed in to change notification settings - Fork 1
/
syslogd.go
94 lines (84 loc) · 2.7 KB
/
syslogd.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package sink
import (
"encoding/base64"
"fmt"
"strconv"
"strings"
"time"
"github.com/agalue/gominion/api"
"github.com/agalue/gominion/log"
"gopkg.in/mcuadros/go-syslog.v2"
)
// SyslogModule represents the heartbeat module
type SyslogModule struct {
sink api.Sink
config *api.MinionConfig
server *syslog.Server
channel syslog.LogPartsChannel
}
// GetID gets the ID of the sink module
func (module *SyslogModule) GetID() string {
return "Syslog"
}
// Start initiates a Syslog UDP and TCP receiver
func (module *SyslogModule) Start(config *api.MinionConfig, sink api.Sink) error {
if config.SyslogPort == 0 {
log.Warnf("Syslog Module disabled")
return nil
}
log.Infof("Starting Syslog receiver on port UDP/TCP %d", config.SyslogPort)
module.config = config
module.sink = sink
listenAddr := fmt.Sprintf("0.0.0.0:%d", config.SyslogPort)
module.channel = make(syslog.LogPartsChannel)
module.server = syslog.NewServer()
module.server.SetFormat(syslog.Automatic)
module.server.SetHandler(syslog.NewChannelHandler(module.channel))
if err := module.server.ListenUDP(listenAddr); err != nil {
return fmt.Errorf("cannot start Syslog UDP listener: %s", err)
}
if err := module.server.ListenTCP(listenAddr); err != nil {
return fmt.Errorf("cannot start Syslog TCP listener: %s", err)
}
if err := module.server.Boot(); err != nil {
return fmt.Errorf("cannot boot Syslog server: %s", err)
}
go func(channel syslog.LogPartsChannel) {
for logParts := range channel {
if messageLog := module.buildMessageLog(logParts); messageLog != nil {
sendXMLResponse(module.GetID(), module.config, module.sink, messageLog)
}
}
}(module.channel)
return nil
}
// Stop shutdowns the sink module
func (module *SyslogModule) Stop() {
log.Warnf("Stopping Syslog receiver")
if module.server != nil {
close(module.channel)
module.server.Kill()
}
}
func (module *SyslogModule) buildMessageLog(logParts map[string]interface{}) *api.SyslogMessageLogDTO {
if logParts["content"].(string) == "X" {
return nil
}
clientParts := strings.Split(logParts["client"].(string), ":")
clientPort, _ := strconv.Atoi(clientParts[1])
messageLog := &api.SyslogMessageLogDTO{
Location: module.config.Location,
SystemID: module.config.ID,
SourceAddress: clientParts[0],
SourcePort: clientPort,
}
timestamp := logParts["timestamp"].(time.Time)
log.Debugf("Received Syslog message from %s", messageLog.SourceAddress)
content := fmt.Sprintf("<%d>%s", logParts["priority"].(int), logParts["content"].(string))
message := api.SyslogMessageDTO{
Timestamp: timestamp.Format(api.TimeFormat),
Content: []byte(base64.StdEncoding.EncodeToString([]byte(content))),
}
messageLog.AddMessage(message)
return messageLog
}