From c47f682c3406edf53a74fc14f9e6c8f2a58d9458 Mon Sep 17 00:00:00 2001 From: Mark Nellemann Date: Sun, 22 Jan 2023 11:44:03 +0100 Subject: [PATCH] Improve robustness of GELF forwarding and parsing. --- .drone.yml | 10 ++++---- doc/syslogd.service | 2 +- gradle.properties | 2 +- .../biz/nellemann/syslogd/SyslogPrinter.java | 24 +++++++++---------- .../biz/nellemann/syslogd/net/TcpServer.java | 10 ++++++-- .../biz/nellemann/syslogd/net/UdpServer.java | 7 +++++- .../nellemann/syslogd/parser/GelfParser.java | 3 ++- .../nellemann/syslogd/GelfParserTest.groovy | 12 ++++++++++ 8 files changed, 47 insertions(+), 23 deletions(-) diff --git a/.drone.yml b/.drone.yml index c80e25c..e44d16f 100644 --- a/.drone.yml +++ b/.drone.yml @@ -11,13 +11,13 @@ steps: - name: publish image: eclipse-temurin:8-jdk environment: - AUTH_TOKEN: # Gitea authentication: username:token - from_secret: auth # Name of DroneCI secret exposing above + AUTH_TOKEN: # Gitea access token ENV variable + from_secret: auth # Name of DroneCI secret exposed above commands: - ./gradlew packages - - for file in build/libs/*-all.jar ; do curl --user "$${AUTH_TOKEN}" --upload-file "$${file}" "https://git.data.coop/api/packages/${DRONE_REPO_OWNER}/generic/${DRONE_REPO_NAME}/${DRONE_TAG}/$(basename $file)" ; done - - for file in build/distributions/*.deb ; do curl --user "$${AUTH_TOKEN}" --upload-file "$${file}" "https://git.data.coop/api/packages/${DRONE_REPO_OWNER}/generic/${DRONE_REPO_NAME}/${DRONE_TAG}/$(basename $file)" ; done - - for file in build/distributions/*.rpm ; do curl --user "$${AUTH_TOKEN}" --upload-file "$${file}" "https://git.data.coop/api/packages/${DRONE_REPO_OWNER}/generic/${DRONE_REPO_NAME}/${DRONE_TAG}/$(basename $file)" ; done + - for file in build/libs/*-all.jar ; do curl --user "${DRONE_REPO_OWNER}:$${AUTH_TOKEN}" --upload-file "$${file}" "https://git.data.coop/api/packages/${DRONE_REPO_OWNER}/generic/${DRONE_REPO_NAME}/${DRONE_TAG}/$(basename $file)" ; done + - for file in build/distributions/*.deb ; do curl --user "${DRONE_REPO_OWNER}:$${AUTH_TOKEN}" --upload-file "$${file}" "https://git.data.coop/api/packages/${DRONE_REPO_OWNER}/generic/${DRONE_REPO_NAME}/${DRONE_TAG}/$(basename $file)" ; done + - for file in build/distributions/*.rpm ; do curl --user "${DRONE_REPO_OWNER}:$${AUTH_TOKEN}" --upload-file "$${file}" "https://git.data.coop/api/packages/${DRONE_REPO_OWNER}/generic/${DRONE_REPO_NAME}/${DRONE_TAG}/$(basename $file)" ; done when: event: - tag diff --git a/doc/syslogd.service b/doc/syslogd.service index ee87569..eeb3a2c 100644 --- a/doc/syslogd.service +++ b/doc/syslogd.service @@ -4,7 +4,7 @@ Description=Syslog Director [Service] TimeoutStartSec=0 Restart=always -ExecStart=/opt/syslogd/bin/syslogd --port 514 --no-stdout --syslog=udp://localhost:1514 +ExecStart=/opt/syslogd/bin/syslogd --port 514 --no-ansi [Install] WantedBy=default.target diff --git a/gradle.properties b/gradle.properties index d38dadf..fe1d807 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ id = syslogd name = syslogd group = biz.nellemann.syslogd -version = 1.3.1 +version = 1.3.2 description = "Syslog Director" diff --git a/src/main/java/biz/nellemann/syslogd/SyslogPrinter.java b/src/main/java/biz/nellemann/syslogd/SyslogPrinter.java index e5be1dd..d575a47 100644 --- a/src/main/java/biz/nellemann/syslogd/SyslogPrinter.java +++ b/src/main/java/biz/nellemann/syslogd/SyslogPrinter.java @@ -103,18 +103,18 @@ public class SyslogPrinter { * @return */ public static String toGelf(SyslogMessage msg) { - StringBuilder sb = new StringBuilder("{ \"version\": \"1.1\","); - sb.append(String.format("\"host\": \"%s\",", msg.hostname)); - sb.append(String.format("\"short_message\": \"%s\",", JsonUtil.encode(msg.message))); - sb.append(String.format("\"full_message\": \"%s\",", msg.structuredData)); - sb.append(String.format("\"timestamp\": %d,", msg.timestamp.getEpochSecond())); - sb.append(String.format("\"level\": %d,", msg.severity.toNumber())); - sb.append(String.format("\"_facility\": \"%s\",", msg.facility)); - sb.append(String.format("\"_severity\": \"%s\",", msg.severity)); - sb.append(String.format("\"_application\": \"%s\",", msg.application)); - if(msg.processId != null) { sb.append(String.format("\"_process-id\": \"%s\",", msg.processId)); } - if(msg.messageId != null) { sb.append(String.format("\"_message-id\": \"%s\",", msg.messageId)); } - if(msg.structuredData != null) { sb.append(String.format("\"_structured-data\": \"%s\",", msg.structuredData)); } + StringBuilder sb = new StringBuilder("{ \"version\": \"1.1\""); + sb.append(String.format(", \"host\": \"%s\"", msg.hostname)); + sb.append(String.format(", \"short_message\": \"%s\"", JsonUtil.encode(msg.message))); + sb.append(String.format(", \"full_message\": \"%s\"", JsonUtil.encode(msg.structuredData))); + sb.append(String.format(", \"timestamp\": %d", msg.timestamp.getEpochSecond())); + sb.append(String.format(", \"level\": %d", msg.severity.toNumber())); + sb.append(String.format(", \"_facility\": \"%s\"", msg.facility)); + sb.append(String.format(", \"_severity\": \"%s\"", msg.severity)); + sb.append(String.format(", \"_application\": \"%s\"", msg.application)); + if(msg.processId != null) { sb.append(String.format(", \"_process-id\": \"%s\"", msg.processId)); } + if(msg.messageId != null) { sb.append(String.format(", \"_message-id\": \"%s\"", msg.messageId)); } + if(msg.structuredData != null) { sb.append(String.format(", \"_structured-data\": \"%s\"", JsonUtil.encode(msg.structuredData))); } sb.append("}"); return sb.toString(); } diff --git a/src/main/java/biz/nellemann/syslogd/net/TcpServer.java b/src/main/java/biz/nellemann/syslogd/net/TcpServer.java index afea1a4..2186b22 100644 --- a/src/main/java/biz/nellemann/syslogd/net/TcpServer.java +++ b/src/main/java/biz/nellemann/syslogd/net/TcpServer.java @@ -26,10 +26,16 @@ import java.net.ServerSocket; import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.ArrayList; public class TcpServer { + private final static Logger log = LoggerFactory.getLogger(TcpServer.class); + private final int port; private ServerSocket serverSocket; @@ -91,14 +97,14 @@ public class TcpServer { sendEvent(inputLine); } } catch (IOException e) { - System.err.printf("TcpServer - error: %s\n", e.getMessage()); + log.warn("run() - read error: {}", e.getMessage()); } try { in.close(); clientSocket.close(); } catch (IOException e) { - System.err.printf("TcpServer - error: %s\n", e.getMessage()); + log.warn("run() - close error: {}", e.getMessage()); } } diff --git a/src/main/java/biz/nellemann/syslogd/net/UdpServer.java b/src/main/java/biz/nellemann/syslogd/net/UdpServer.java index 131fd7a..ebf148c 100644 --- a/src/main/java/biz/nellemann/syslogd/net/UdpServer.java +++ b/src/main/java/biz/nellemann/syslogd/net/UdpServer.java @@ -24,8 +24,13 @@ import java.net.DatagramSocket; import java.util.ArrayList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class UdpServer extends Thread { + private final static Logger log = LoggerFactory.getLogger(UdpServer.class); + protected DatagramSocket socket; protected boolean listen = true; @@ -44,7 +49,7 @@ public class UdpServer extends Thread { //String packetData = new String(packet.getData(), packet.getOffset(), packet.getLength(), StandardCharsets.UTF_8); sendEvent(packet); } catch (Exception e) { - e.printStackTrace(); + log.error("run() - error: {}", e.getMessage()); listen = false; } } diff --git a/src/main/java/biz/nellemann/syslogd/parser/GelfParser.java b/src/main/java/biz/nellemann/syslogd/parser/GelfParser.java index fa73d1f..9e45a98 100644 --- a/src/main/java/biz/nellemann/syslogd/parser/GelfParser.java +++ b/src/main/java/biz/nellemann/syslogd/parser/GelfParser.java @@ -81,11 +81,12 @@ public class GelfParser extends SyslogParser { @Override public SyslogMessage parse(String input) { + if(!input.startsWith("{")) return null; // Avoid trying to parse non-JSON content SyslogMessage message = null; try { message = objectMapper.readValue(input, SyslogMessage.class); } catch (JsonProcessingException e) { - log.warn("parse() - error: {}", e.getMessage()); + log.debug("parse() - error: {}", e.getMessage()); } return message; } diff --git a/src/test/groovy/biz/nellemann/syslogd/GelfParserTest.groovy b/src/test/groovy/biz/nellemann/syslogd/GelfParserTest.groovy index 4424c4a..786f7a9 100644 --- a/src/test/groovy/biz/nellemann/syslogd/GelfParserTest.groovy +++ b/src/test/groovy/biz/nellemann/syslogd/GelfParserTest.groovy @@ -85,4 +85,16 @@ class GelfParserTest extends Specification { } + void "junk GET request"() { + + setup: + def input = 'GET /' + + when: + SyslogMessage msg = syslogParser.parse(input) + + then: + msg == null + } + }