Improve robustness of GELF forwarding and parsing.
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing

This commit is contained in:
Mark Nellemann 2023-01-22 11:44:03 +01:00
parent b291f87693
commit c47f682c34
8 changed files with 47 additions and 23 deletions

View file

@ -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

View file

@ -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

View file

@ -1,5 +1,5 @@
id = syslogd
name = syslogd
group = biz.nellemann.syslogd
version = 1.3.1
version = 1.3.2
description = "Syslog Director"

View file

@ -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();
}

View file

@ -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());
}
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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
}
}