Skip to content

Commit 4c6f3b5

Browse files
authored
Add UTF8 BOM support (#37)
1 parent 75f8a84 commit 4c6f3b5

File tree

5 files changed

+47
-4
lines changed

5 files changed

+47
-4
lines changed

README.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
Based on the syslog4j library bundled with Graylog.
44

5-
This plugin allows you to forward messages from a Graylog 2.X server in syslog format. Messages can be dispatched over TCP or UDP and formatted as plain text (classic), structured syslog (rfc 5424) or CEF (experimental).
5+
This plugin allows you to forward messages from a Graylog server in syslog format.
6+
Messages can be dispatched over TCP or UDP and formatted as plain text (classic), structured syslog (rfc 5424) or CEF (experimental).
67

7-
This plugin supports Graylog 2.4.x, 2.5.x, 3.0.0. Other releases might work, pls try to use latest plugin.
8+
This plugin supports Graylog 2.4.x, 2.5.x, 3.0.0 and 3.3.x.
9+
Newever releases might work, please try to use the latest plugin.
810

911
## Graylog marketplace
1012

@@ -31,7 +33,7 @@ You can build a plugin (JAR) with `mvn package`.
3133
- _Syslog port_: Syslog receiver port on remote host, usually 514
3234
- _Format_: Specify one of plain, structured, full, cef or custom:FQCN (see below for explanation on values)
3335

34-
![Screenshot of add new output dialog](graylog2-output-syslog-2.1.3-parameters.png)
36+
![Screenshot of add new output dialog](graylog2-output-syslog-parameters.png)
3537

3638
## Supported formats
3739

@@ -145,6 +147,20 @@ If existing fields does not contain such keys, following fields will be added to
145147
| msg | Message text (`message`) |
146148
| externalId | Message ID (assigned by Graylog) |
147149

150+
### Receiving and sending UTF-8 messages.
151+
152+
Graylog internally are fully UTF-8 capable. All messages are stored as Unicode. When sending messages to syslog server,
153+
154+
RFC requires adding BOM mark to the messages to identify the string is UTF-8 encoded.
155+
156+
```
157+
curl -XPOST http://localhost:12201/gelf -p0 -d '{"short_message":"Hello there🙂Ё Ђ Ѓ Є Ѕ І Ї Ј Љ Њ Ћ Ќ Ў Џ А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я а б в г д е ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ "}'
158+
```
159+
160+
When running syslog (syslog-ng v 3.27.1), this gets written to /var/log/messages
161+
162+
Jun 20 19:31:43 Ruslans-MacBook-Pro11111111111111111111111 .local Hello there🙂Ё Ђ Ѓ Є Ѕ І Ї Ј Љ Њ Ћ Ќ Ў Џ А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я а б в г д е ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ы ь э ю я À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ
163+
148164
## Links
149165

150166
- https://tools.ietf.org/html/rfc5424
-46.1 KB
Binary file not shown.
112 KB
Loading

run-graylog

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@ sleep 5
2121
$GL/bin/graylogctl run
2222

2323
## Run two consoles additionally:
24-
## sudo docker run -it -p 514:514/udp -p 601:601 --name syslog-ng balabit/syslog-ng:latest
24+
## docker run -it -p 514:514/udp -p 514:514/tcp -p 601:601 --name syslog-ng balabit/syslog-ng:latest
2525
## docker exec syslog-ng tail -f /var/log/messages

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.graylog2.syslog4j.SyslogConfigIF;
1717
import org.graylog2.syslog4j.SyslogIF;
1818
import org.graylog2.syslog4j.impl.message.processor.SyslogMessageProcessor;
19+
import org.graylog2.syslog4j.impl.message.processor.structured.StructuredSyslogMessageProcessor;
1920
import org.graylog2.syslog4j.impl.net.tcp.TCPNetSyslogConfig;
2021
import org.graylog2.syslog4j.impl.net.tcp.ssl.SSLTCPNetSyslogConfig;
2122
import org.graylog2.syslog4j.impl.net.udp.UDPNetSyslogConfig;
@@ -38,6 +39,7 @@ public class SyslogOutput implements MessageOutput {
3839

3940
public final static int PORT_MIN = 9000;
4041
public final static int PORT_MAX = 9099;
42+
public final static byte[] BOM = { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF };
4143

4244
private Logger log = Logger.getLogger(SyslogOutput.class.getName());
4345
private String host;
@@ -128,6 +130,7 @@ public SyslogOutput(@Assisted Stream stream, @Assisted Configuration conf) {
128130
} else {
129131
throw new IllegalArgumentException("Unknown protocol: " + protocol);
130132
}
133+
131134
config.setHost(host);
132135
config.setPort(port);
133136
int maxlen = 16 * 1024;
@@ -142,6 +145,29 @@ public SyslogOutput(@Assisted Stream stream, @Assisted Configuration conf) {
142145
String hash = protocol + "_" + host + "_" + port + "_" + format;
143146
syslog = Syslog.exists(hash) ? Syslog.getInstance(hash) : Syslog.createInstance(hash, config);
144147

148+
boolean utf8 = conf.getBoolean("utf8");
149+
if (utf8) {
150+
syslog.setMessageProcessor(new SyslogMessageProcessor() {
151+
public byte[] createPacketData(byte[] header, byte[] message, int start, int length, byte[] splitBeginText, byte[] splitEndText) {
152+
byte[] buf = super.createPacketData(header, message, start, length, splitBeginText, splitEndText);
153+
byte[] newBuf = new byte[buf.length + BOM.length];
154+
System.arraycopy(BOM, 0, newBuf, 0, BOM.length);
155+
System.arraycopy(buf, 0, newBuf, BOM.length, buf.length);
156+
return newBuf;
157+
}
158+
});
159+
160+
syslog.setStructuredMessageProcessor(new StructuredSyslogMessageProcessor() {
161+
public byte[] createPacketData(byte[] header, byte[] message, int start, int length, byte[] splitBeginText, byte[] splitEndText) {
162+
byte[] buf = super.createPacketData(header, message, start, length, splitBeginText, splitEndText);
163+
byte[] newBuf = new byte[buf.length + BOM.length];
164+
System.arraycopy(BOM, 0, newBuf, 0, BOM.length);
165+
System.arraycopy(buf, 0, newBuf, BOM.length, buf.length);
166+
return newBuf;
167+
}
168+
});
169+
}
170+
145171
sender = createSender(format, conf);
146172

147173
if (sender instanceof TransparentSyslogSender) {
@@ -293,6 +319,7 @@ public ConfigurationRequest getRequestedConfiguration() {
293319
configurationRequest.addField(new TextField("truststore", "Trust store", "", "Path to Java keystore (required for SSL over TCP). Optional (if not set, equals to key store). Must contain peers we trust connecting to.", ConfigurationField.Optional.OPTIONAL));
294320
configurationRequest.addField(new TextField("truststorePassword", "Trust store password", "", "", ConfigurationField.Optional.OPTIONAL));
295321

322+
configurationRequest.addField(new BooleanField("utf8", "UTF-8 BOM", false,"Always add BOM to messages send. Use this to conform to RFC 5424 requirements for UTF-8 messages."));
296323
return configurationRequest;
297324
}
298325
}

0 commit comments

Comments
 (0)