-
Notifications
You must be signed in to change notification settings - Fork 1
/
syslogoutput.go
120 lines (110 loc) · 2.71 KB
/
syslogoutput.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package main
import (
syslog "github.com/RackSec/srslog"
"log"
"time"
"strings"
)
type syslogOutputPrivate struct {
fd *syslog.Writer
}
func newSyslogOutputDesc() *outputDesc {
return &outputDesc{
sendStart: syslogOutputSendStart,
open: syslogOpen,
private: new(syslogOutputPrivate),
}
}
func syslogParseTarget(sc *scriptLine) (proto, target, formatter, framer string) {
target=sc.target
proto="tcp"
formatter="rfc5424"
framer=""
// target:
// 1234:514
// (tcp|udp):1234:514
// (tcp|udp)/format:1234:514
// (tcp|udp)/format/frame:1234:514
// unix
// unix/format/frame
//
var formatframe string
if target=="unix" {
target=""
proto=""
formatter="unix";
framer="";
} else if target[0:5]=="unix/" {
formatframe=target[5:]
target=""
proto=""
framer="" // change default
} else if target[0:4]=="tcp:" {
target=target[4:]
proto="tcp"
} else if target[0:4]=="udp:" {
target=target[4:]
proto="udp"
} else if target[0:4]=="tcp/" || target[0:4]=="udp/" {
if target[0:4]=="udp/" {
proto="udp"
}
idx:=strings.IndexByte(target, ':')
formatframe=target[4:idx]
target=target[idx+1:]
} else {
// take as is
}
if formatframe != "" {
idx:=strings.IndexByte(formatframe, '/')
if idx==-1 {
formatter=formatframe
} else {
formatter=formatframe[0:idx]
framer=formatframe[idx+1:]
}
}
return proto,target,formatter,framer
}
func syslogOpen(sc *scriptLine) {
proto, target, formatter, framer := syslogParseTarget(sc)
log.Printf("in: %s => proto %s target %s formatter %s framer %s", sc.target, proto,target,formatter, framer)
s, err := syslog.Dial(proto, target,
syslog.LOG_INFO|syslog.LOG_DAEMON, sc.msgid)
if err != nil {
log.Fatalf("failed to open syslog %s: %v\n", sc.target, err)
}
priv := (*syslogOutputPrivate)(sc.desc.private.(*syslogOutputPrivate))
switch formatter {
case "rfc3164", "3164":
s.SetFormatter(syslog.RFC3164Formatter)
case "rfc5424", "5424":
s.SetFormatter(syslog.RFC5424Formatter)
case "unix":
s.SetFormatter(syslog.UnixFormatter)
case "compat", "":
s.SetFormatter(syslog.DefaultFormatter)
default:
log.Fatalf("unknown formatter '%s' in %s\n", formatter, sc.target)
}
switch framer {
case "rfc5425", "5425":
s.SetFramer(syslog.RFC5425MessageLengthFramer)
case "none","":
s.SetFramer(syslog.DefaultFramer)
default:
log.Fatalf("unknown framer '%s' in %s\n", framer, sc.target)
}
priv.fd = s
}
func syslogOutputSendStart(sc *scriptLine, buf []byte) {
priv := (*syslogOutputPrivate)(sc.desc.private.(*syslogOutputPrivate))
for {
_, err := priv.fd.WriteWithPriority(sc.priority, buf)
if err == nil {
break
}
log.Printf("unable to write to %s, pausing: %v\n", sc.target, err)
time.Sleep(time.Second)
}
}