Skip to content

Commit f54de23

Browse files
author
Huksley
committed
Improved plain sender and structured sender. First implementation of CEF
sender.
1 parent 0bc4173 commit f54de23

File tree

5 files changed

+138
-26
lines changed

5 files changed

+138
-26
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@
1616
.jhw-cache
1717
/bin/
1818
/build/
19+
GraylogSyslogOutput.jar

src/main/java/com/wizecore/graylog2/plugin/CEFSender.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.wizecore.graylog2.plugin;
22

3+
import java.util.Map;
4+
35
import org.graylog2.plugin.Message;
46
import org.graylog2.syslog4j.SyslogIF;
57

@@ -11,8 +13,7 @@
1113
* http://blog.rootshell.be/2011/05/11/ossec-speaks-arcsight/
1214
*
1315
*
14-
* CEF:Version|Device Vendor|Device Product|Device Version|Signature ID|\
15-
Name|Severity|Extension
16+
* CEF:Version|Device Vendor|Device Product|Device Version|Signature ID|Name|Severity|Extension
1617
1718
CEF:0|ArcSight|Logger|5.0.0.5355.2|sensor:115|Logger Internal Event|1|\
1819
cat=/Monitor/Sensor/Fan5 cs2=Current Value cnt=1 dvc=10.0.0.1 cs3=Ok \
@@ -23,6 +24,22 @@ public class CEFSender implements MessageSender {
2324

2425
@Override
2526
public void send(SyslogIF syslog, int level, Message msg) {
26-
throw new UnsupportedOperationException("CEF is not yet complete!");
27+
StringBuilder out = new StringBuilder();
28+
PlainSender.appendHeader(msg, out);
29+
out.append("CEF:0|ArcSight|Logger|5.0.0.5355.2|log:1|");
30+
String str = msg.getMessage();
31+
if (str.contains("|")) {
32+
str = str.replace("|", "");
33+
}
34+
out.append(str);
35+
out.append("|").append(level) .append("|"); // severity
36+
Map<String, Object> fields = msg.getFields();
37+
for (String k: fields.keySet()) {
38+
Object v = fields.get(k);
39+
if (!k.equals("message") && !k.equals("full_message")) {
40+
String s = v != null ? v.toString() : "null";
41+
out.append(k).append('=').append(s);
42+
}
43+
}
2744
}
2845
}

src/main/java/com/wizecore/graylog2/plugin/PlainSender.java

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@
1010

1111
/**
1212
* Formats fields into message text
13+
*
14+
15+
<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - BOM'su root' failed for lonvick on /dev/pts/8
16+
^priority
17+
^ version
18+
^ date
19+
^ host
20+
^ APP-NAME
21+
^ structured data?
22+
^ MSGID
23+
1324
*/
1425
public class PlainSender implements MessageSender {
1526
private Logger log = Logger.getLogger(PlainSender.class.getName());
@@ -22,23 +33,31 @@ public class PlainSender implements MessageSender {
2233
* @param dt
2334
* @return
2435
*/
25-
public static String formatTimestamp(Date dt) {
36+
public static void appendSyslogTimestamp(Date dt, StringBuilder buffer) {
2637
SimpleDateFormat dateFormat = new SimpleDateFormat(SYSLOG_DATEFORMAT,Locale.ENGLISH);
2738
String datePrefix = dateFormat.format(dt);
2839

29-
StringBuilder buffer = new StringBuilder();
3040
int pos = buffer.length() + 4;
3141
buffer.append(datePrefix);
3242

3343
// RFC 3164 requires leading space for days 1-9
3444
if (buffer.charAt(pos) == '0') {
3545
buffer.setCharAt(pos,' ');
36-
}
37-
return buffer.toString();
46+
}
3847
}
3948

4049
@Override
4150
public void send(SyslogIF syslog, int level, Message msg) {
51+
StringBuilder out = new StringBuilder();
52+
appendHeader(msg, out);
53+
54+
out.append(msg.getMessage());
55+
String str = out.toString();
56+
log.info("Sending plain message: " + level + ", " + str);
57+
syslog.log(level, str);
58+
}
59+
60+
public static void appendHeader(Message msg, StringBuilder out) {
4261
Date dt = null;
4362
Object ts = msg.getField("timestamp");
4463
if (ts != null && ts instanceof Number) {
@@ -49,36 +68,34 @@ public void send(SyslogIF syslog, int level, Message msg) {
4968
dt = new Date();
5069
}
5170

52-
StringBuilder out = new StringBuilder();
53-
5471
// Write time
55-
out.append(formatTimestamp(dt));
72+
appendSyslogTimestamp(dt, out);
5673
out.append(" ");
5774

5875
// Write source (host)
5976
String source = msg.getSource();
6077
if (source != null) {
6178
out.append(source).append(" ");
79+
} else {
80+
out.append("- ");
6281
}
6382

6483
// Write service
6584
Object facility = msg.getField("facility");
6685
if (facility != null) {
67-
out.append("[").append(facility.toString()).append("]");
86+
out.append(facility.toString()).append(" ");
87+
} else {
88+
out.append("- ");
6889
}
6990

91+
// MSGID
7092
Object username = msg.getField("username");
7193
if (username != null) {
72-
out.append("[").append(username.toString()).append("]");
73-
}
74-
75-
if (out.length() > 0) {
76-
out.append(' ');
94+
out.append(username.toString()).append(" ");
95+
} else {
96+
out.append("- ");
7797
}
7898

79-
out.append(msg.getMessage());
80-
String str = out.toString();
81-
log.info("Sending plain message: " + level + ", " + str);
82-
syslog.log(level, str);
99+
out.append(' ');
83100
}
84101
}

src/main/java/com/wizecore/graylog2/plugin/StructuredSender.java

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,55 @@
88
import org.graylog2.syslog4j.SyslogIF;
99
import org.graylog2.syslog4j.impl.message.structured.StructuredSyslogMessage;
1010

11+
/**
12+
* https://tools.ietf.org/html/rfc5424
13+
*
14+
* <165>1 2003-10-11T22:14:15.003Z mymachine.example.com
15+
evntslog - ID47 [exampleSDID@0 iut="3" eventSource=
16+
"Application" eventID="1011"] BOMAn application
17+
event log entry...
18+
19+
*/
1120
public class StructuredSender implements MessageSender {
1221
private Logger log = Logger.getLogger(StructuredSender.class.getName());
1322

1423
@Override
1524
public void send(SyslogIF syslog, int level, Message msg) {
16-
Map<String, Map<String, String>> data = new HashMap<String, Map<String,String>>();
25+
Map<String, String> sdParams = new HashMap<String, String>();
1726
Map<String, Object> fields = msg.getFields();
1827
for (String key: fields.keySet()) {
19-
Map<String,String> inner = new HashMap<String, String>();
20-
inner.put(key, fields.get(key).toString());
21-
data.put(key, inner);
28+
sdParams.put(key, fields.get(key).toString());
29+
}
30+
31+
// http://www.iana.org/assignments/enterprise-numbers/enterprise-numbers
32+
// <name>@<enterpriseId>
33+
String sdId = "all@0";
34+
log.info("Sending " + level + ", " + msg.getId() + ", " + msg.getSource() + ", " + sdId + "=" + sdParams + ", " + msg.getMessage());
35+
Map<String,Map<String,String>> sd = new HashMap<String, Map<String,String>>();
36+
sd.put(sdId, sdParams);
37+
38+
String msgId = null;
39+
if (msgId == null) {
40+
String source = msg.getSource();
41+
if (source != null) {
42+
msgId = source;
43+
}
44+
}
45+
if (msgId == null) {
46+
msgId = "-";
47+
}
48+
49+
String sourceId = null;
50+
if (sourceId == null) {
51+
Object facility = msg.getField("facility");
52+
if (facility != null) {
53+
sourceId = facility.toString();
54+
}
55+
}
56+
if (sourceId == null) {
57+
sourceId = "-";
2258
}
2359

24-
log.info("Sending " + level + ", " + msg.getId() + ", " + msg.getSource() + ", " + data + ", " + msg.getMessage());
25-
syslog.log(level, new StructuredSyslogMessage(msg.getId(), msg.getSource(), data, msg.getMessage()));
60+
syslog.log(level, new StructuredSyslogMessage(msgId, sourceId, sd, msg.getMessage()));
2661
}
2762
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
Numerical Facility
2+
Code
3+
4+
0 kernel messages
5+
1 user-level messages
6+
2 mail system
7+
3 system daemons
8+
4 security/authorization messages
9+
5 messages generated internally by syslogd
10+
6 line printer subsystem
11+
7 network news subsystem
12+
8 UUCP subsystem
13+
9 clock daemon
14+
10 security/authorization messages
15+
11 FTP daemon
16+
12 NTP subsystem
17+
13 log audit
18+
14 log alert
19+
15 clock daemon (note 2)
20+
16 local use 0 (local0)
21+
17 local use 1 (local1)
22+
18 local use 2 (local2)
23+
19 local use 3 (local3)
24+
20 local use 4 (local4)
25+
21 local use 5 (local5)
26+
22 local use 6 (local6)
27+
23 local use 7 (local7)
28+
29+
Numerical Severity
30+
Code
31+
32+
0 Emergency: system is unusable
33+
1 Alert: action must be taken immediately
34+
2 Critical: critical conditions
35+
3 Error: error conditions
36+
4 Warning: warning conditions
37+
5 Notice: normal but significant condition
38+
6 Informational: informational messages
39+
7 Debug: debug-level messages
40+
41+
The Priority value is calculated by first multiplying the Facility
42+
number by 8 and then adding the numerical value of the Severity.

0 commit comments

Comments
 (0)