commit
0909298bbc
|
@ -18,7 +18,8 @@ dependencies {
|
|||
implementation 'org.slf4j:slf4j-simple:1.7.30'
|
||||
|
||||
testImplementation('org.spockframework:spock-core:2.0-M4-groovy-3.0')
|
||||
testImplementation("org.slf4j:slf4j-simple:1.7.30")
|
||||
testImplementation 'org.slf4j:slf4j-api:1.7.30'
|
||||
testRuntime("org.slf4j:slf4j-simple:1.7.30")
|
||||
}
|
||||
|
||||
application {
|
||||
|
|
|
@ -4,7 +4,7 @@ Description=Simple Syslog Service
|
|||
[Service]
|
||||
TimeoutStartSec=0
|
||||
Restart=always
|
||||
ExecStart=/opt/syslogd/bin/syslogd --no-stdout --forward localhost:1514
|
||||
ExecStart=/opt/syslogd/bin/syslogd --no-stdout --forward=localhost:1514
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
id = syslogd
|
||||
group = biz.nellemann.syslogd
|
||||
version = 1.0.9
|
||||
version = 1.0.10
|
||||
|
|
|
@ -15,6 +15,13 @@
|
|||
*/
|
||||
package biz.nellemann.syslogd;
|
||||
|
||||
import biz.nellemann.syslogd.msg.SyslogMessage;
|
||||
import biz.nellemann.syslogd.net.TcpServer;
|
||||
import biz.nellemann.syslogd.net.UdpClient;
|
||||
import biz.nellemann.syslogd.net.UdpServer;
|
||||
import biz.nellemann.syslogd.parser.SyslogParser;
|
||||
import biz.nellemann.syslogd.parser.SyslogParserRfc3164;
|
||||
import biz.nellemann.syslogd.parser.SyslogParserRfc5424;
|
||||
import org.slf4j.impl.SimpleLogger;
|
||||
|
||||
import picocli.CommandLine;
|
||||
|
@ -32,6 +39,7 @@ import java.util.regex.Pattern;
|
|||
public class Application implements Callable<Integer>, LogListener {
|
||||
|
||||
private boolean doForward = false;
|
||||
private SyslogParser syslogParser;
|
||||
private UdpClient udpClient;
|
||||
|
||||
|
||||
|
@ -53,7 +61,7 @@ public class Application implements Callable<Integer>, LogListener {
|
|||
@CommandLine.Option(names = "--rfc5424", description = "Parse RFC-5424 messages [default: RFC-3164].", defaultValue = "false")
|
||||
private boolean rfc5424;
|
||||
|
||||
@CommandLine.Option(names = { "-f", "--forward"}, description = "Forward to UDP host[:port] (RFC-3164).", paramLabel = "<host>")
|
||||
@CommandLine.Option(names = { "-f", "--forward"}, description = "Forward to UDP host[:port] (RFC-5424).", paramLabel = "<host>")
|
||||
private String forward;
|
||||
|
||||
@CommandLine.Option(names = { "-d", "--debug" }, description = "Enable debugging [default: 'false'].")
|
||||
|
@ -67,6 +75,12 @@ public class Application implements Callable<Integer>, LogListener {
|
|||
System.setProperty(SimpleLogger.DEFAULT_LOG_LEVEL_KEY, "DEBUG");
|
||||
}
|
||||
|
||||
if(rfc5424) {
|
||||
syslogParser = new SyslogParserRfc5424();
|
||||
} else {
|
||||
syslogParser = new SyslogParserRfc3164();
|
||||
}
|
||||
|
||||
if(forward != null && !forward.isEmpty()) {
|
||||
String fHost, fPort;
|
||||
Pattern pattern = Pattern.compile("^([^:]+)(?::([0-9]+))?$", Pattern.CASE_INSENSITIVE);
|
||||
|
@ -110,11 +124,7 @@ public class Application implements Callable<Integer>, LogListener {
|
|||
String message = event.getMessage();
|
||||
SyslogMessage msg = null;
|
||||
try {
|
||||
if(rfc5424) {
|
||||
msg = SyslogParser.parseRfc5424(message);
|
||||
} else {
|
||||
msg = SyslogParser.parseRfc3164(message);
|
||||
}
|
||||
msg = syslogParser.parse(message);
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -131,7 +141,7 @@ public class Application implements Callable<Integer>, LogListener {
|
|||
|
||||
if(doForward) {
|
||||
try {
|
||||
udpClient.send(SyslogPrinter.toRfc3164(msg));
|
||||
udpClient.send(SyslogPrinter.toRfc5424(msg));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
|
|
@ -16,5 +16,5 @@
|
|||
package biz.nellemann.syslogd;
|
||||
|
||||
public interface LogListener {
|
||||
void onLogEvent(LogEvent event);
|
||||
public void onLogEvent(LogEvent event);
|
||||
}
|
||||
|
|
|
@ -1,201 +0,0 @@
|
|||
/*
|
||||
Copyright 2020 mark.nellemann@gmail.com
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package biz.nellemann.syslogd;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.time.*;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class SyslogParser {
|
||||
|
||||
private final static Logger log = LoggerFactory.getLogger(SyslogParser.class);
|
||||
|
||||
|
||||
/**
|
||||
* Parses [rfc3164](https://tools.ietf.org/html/rfc3164) syslog messages.
|
||||
*
|
||||
* @param input
|
||||
* @return
|
||||
* @throws NumberFormatException
|
||||
*/
|
||||
public static SyslogMessage parseRfc3164(final String input) throws NumberFormatException {
|
||||
|
||||
Pattern pattern = Pattern.compile("^<(\\d{1,3})>(\\D{3}\\s+\\d{1,2} \\d{2}:\\d{2}:\\d{2})\\s+(Message forwarded from \\S+:|\\S+)\\s+([^\\s:]+):?\\s+(.*)", Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcher = pattern.matcher(input);
|
||||
boolean matchFound = matcher.find();
|
||||
if(!matchFound) {
|
||||
//log.warn("parseRfc3164() - Match not found in: ");
|
||||
System.err.println("!" + input);
|
||||
return null;
|
||||
}
|
||||
|
||||
String pri = matcher.group(1);
|
||||
String date = matcher.group(2);
|
||||
String hostname = matcher.group(3);
|
||||
String application = matcher.group(4);
|
||||
String msg = matcher.group(5);
|
||||
|
||||
if(hostname.endsWith(":")) {
|
||||
String[] tmp = hostname.split(" ");
|
||||
hostname = tmp[tmp.length-1];
|
||||
hostname = hostname.substring(0, hostname.length()-1);
|
||||
}
|
||||
|
||||
Integer facility = getFacility(pri);
|
||||
Integer severity = getSeverity(pri);
|
||||
|
||||
SyslogMessage syslogMessage = new SyslogMessage(msg.trim());
|
||||
syslogMessage.facility = Facility.getByNumber(facility);
|
||||
syslogMessage.severity = Severity.getByNumber(severity);
|
||||
syslogMessage.timestamp = parseRfc3164Timestamp(date);
|
||||
syslogMessage.hostname = hostname;
|
||||
syslogMessage.application = application;
|
||||
|
||||
return syslogMessage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses [rfc5424](https://tools.ietf.org/html/rfc5424) syslog messages.
|
||||
*
|
||||
* @param input
|
||||
* @return
|
||||
* @throws NumberFormatException
|
||||
*/
|
||||
public static SyslogMessage parseRfc5424(final String input) throws NumberFormatException {
|
||||
|
||||
Pattern pattern = Pattern.compile("^<(\\d{1,3})>(\\d+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\[.*\\])\\s+(\\S+)", Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcher = pattern.matcher(input);
|
||||
boolean matchFound = matcher.find();
|
||||
if(!matchFound) {
|
||||
//log.warn("parseRfc5424() - Match not found in: " + input);
|
||||
System.err.println("!" + input);
|
||||
return null;
|
||||
}
|
||||
|
||||
String pri = matcher.group(1);
|
||||
String ver = matcher.group(2);
|
||||
String date = matcher.group(3);
|
||||
String host = matcher.group(4);
|
||||
String app = matcher.group(5);
|
||||
String procId = matcher.group(6);
|
||||
String msgId = matcher.group(7);
|
||||
String data = matcher.group(8);
|
||||
String msg = matcher.group(9);
|
||||
|
||||
Integer facility = getFacility(pri);
|
||||
Integer severity = getSeverity(pri);
|
||||
|
||||
SyslogMessage syslogMessage = new SyslogMessage(msg.trim());
|
||||
syslogMessage.facility = Facility.getByNumber(facility);
|
||||
syslogMessage.severity = Severity.getByNumber(severity);
|
||||
syslogMessage.version = Integer.parseInt(ver);
|
||||
syslogMessage.timestamp = parseRfc5424Timestamp(date);
|
||||
syslogMessage.hostname = host;
|
||||
if(app != null && !app.equals("-"))
|
||||
syslogMessage.application = app;
|
||||
if(procId != null && !procId.equals("-"))
|
||||
syslogMessage.processId = procId;
|
||||
if(msgId != null && !msgId.equals("-"))
|
||||
syslogMessage.messageId = msgId;
|
||||
syslogMessage.structuredData = data;
|
||||
|
||||
return syslogMessage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse rfc3164 TIMESTAMP field into Instant.
|
||||
*
|
||||
* @param dateString
|
||||
* @return
|
||||
*/
|
||||
static protected Instant parseRfc3164Timestamp(String dateString) {
|
||||
|
||||
// We need to add year to parse date correctly
|
||||
OffsetDateTime odt = OffsetDateTime.now();
|
||||
|
||||
// Date: Mmm dd hh:mm:ss
|
||||
Instant instant = null;
|
||||
try {
|
||||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy MMM [ ]d HH:mm:ss").withZone(ZoneOffset.UTC);
|
||||
instant = Instant.from(dateTimeFormatter.parse(odt.getYear() + " " + dateString));
|
||||
} catch(DateTimeParseException e) {
|
||||
log.error("parseDate()", e);
|
||||
}
|
||||
|
||||
return instant;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse rfc5424 TIMESTAMP field into Instant.
|
||||
*
|
||||
* @param dateString
|
||||
* @return
|
||||
*/
|
||||
static protected Instant parseRfc5424Timestamp(String dateString) {
|
||||
|
||||
Instant instant = null;
|
||||
try {
|
||||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
|
||||
instant = Instant.from(dateTimeFormatter.parse(dateString));
|
||||
} catch(DateTimeParseException e) {
|
||||
log.error("parseTimestamp()", e);
|
||||
}
|
||||
|
||||
return instant;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts syslog PRI field into Facility.
|
||||
*
|
||||
* @param pri
|
||||
* @return
|
||||
*/
|
||||
static protected int getFacility(String pri) {
|
||||
|
||||
int priority = Integer.parseInt(pri);
|
||||
int facility = priority >> 3;
|
||||
|
||||
//log.debug("getFacility() - " + pri + " => " + facility);
|
||||
return facility;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts syslog PRI field into Severity.
|
||||
*
|
||||
* @param pri
|
||||
* @return
|
||||
*/
|
||||
static protected int getSeverity(String pri) {
|
||||
|
||||
int priority = Integer.parseInt(pri);
|
||||
int severity = priority & 0x07;
|
||||
|
||||
//log.debug("getSeverity() - " + pri + " => " + severity);
|
||||
return severity;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,10 +1,19 @@
|
|||
package biz.nellemann.syslogd;
|
||||
|
||||
import biz.nellemann.syslogd.msg.Facility;
|
||||
import biz.nellemann.syslogd.msg.Severity;
|
||||
import biz.nellemann.syslogd.msg.SyslogMessage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SyslogPrinter {
|
||||
|
||||
private final static Logger log = LoggerFactory.getLogger(SyslogPrinter.class);
|
||||
|
||||
private final static char SPACE = ' ';
|
||||
|
||||
public static String toString(SyslogMessage msg) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(msg.timestamp.toString());
|
||||
StringBuilder sb = new StringBuilder(msg.timestamp.toString());
|
||||
sb.append(String.format(" [%8.8s.%-6.6s] ", msg.facility, msg.severity));
|
||||
sb.append(String.format(" %-16.16s ", msg.hostname));
|
||||
sb.append(String.format(" %-32.32s ", msg.application));
|
||||
|
@ -14,9 +23,7 @@ public class SyslogPrinter {
|
|||
|
||||
|
||||
public static String toAnsiString(SyslogMessage msg) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append(msg.timestamp.toString());
|
||||
StringBuilder sb = new StringBuilder(msg.timestamp.toString());
|
||||
|
||||
if (msg.severity.toNumber() < 3) {
|
||||
sb.append(Ansi.RED);
|
||||
|
@ -40,30 +47,34 @@ public class SyslogPrinter {
|
|||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(getPri(msg.facility, msg.severity));
|
||||
sb.append(new java.text.SimpleDateFormat("MMM dd HH:mm:ss").format(new java.util.Date(msg.timestamp.toEpochMilli())));
|
||||
sb.append(" " + msg.hostname);
|
||||
sb.append(" " + msg.application);
|
||||
sb.append(": " + msg.message);
|
||||
|
||||
sb.append(SPACE).append(msg.hostname);
|
||||
sb.append(SPACE).append(msg.application);
|
||||
sb.append(":").append(SPACE).append(msg.message);
|
||||
log.debug(sb.toString());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
// <13>1 2020-09-23T08:57:30.950699+02:00 xps13 mark - - [timeQuality tzKnown="1" isSynced="1" syncAccuracy="125500"] adfdfdf3432434565656
|
||||
// <34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - BOM'su root' failed for lonvick on /dev/pts/8
|
||||
public static String toRfc5424(SyslogMessage msg) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(getPri(msg.facility, msg.severity));
|
||||
sb.append("1"); // Version
|
||||
sb.append(" " + new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(new java.util.Date(msg.timestamp.toEpochMilli())));
|
||||
sb.append(" " + msg.hostname);
|
||||
sb.append(" " + msg.application);
|
||||
sb.append(": " + msg.message);
|
||||
|
||||
sb.append(getPri(msg.facility, msg.severity)).append("1");
|
||||
sb.append(SPACE).append(new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").format(new java.util.Date(msg.timestamp.toEpochMilli())));
|
||||
sb.append(SPACE).append(msg.hostname);
|
||||
sb.append(SPACE).append(msg.application);
|
||||
sb.append(SPACE).append(msg.processId);
|
||||
sb.append(SPACE).append(msg.messageId);
|
||||
sb.append(SPACE).append(msg.structuredData);
|
||||
sb.append(SPACE).append(msg.message);
|
||||
log.debug(sb.toString());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
static private String getPri(Facility facility, Severity severity) {
|
||||
int prival = (facility.toNumber() * 8) + severity.toNumber();
|
||||
return String.format("<%d>", prival);
|
||||
int pri = (facility.toNumber() * 8) + severity.toNumber();
|
||||
return String.format("%c%d%c", '<', pri, '>');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
package biz.nellemann.syslogd;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
|
||||
public class UdpClient {
|
||||
|
||||
private DatagramSocket socket;
|
||||
private InetAddress address;
|
||||
private Integer port;
|
||||
|
||||
private byte[] buf;
|
||||
|
||||
public UdpClient(String host, Integer port) throws UnknownHostException, SocketException {
|
||||
socket = new DatagramSocket();
|
||||
address = InetAddress.getByName(host);
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public void send(String msg) throws IOException {
|
||||
buf = msg.getBytes();
|
||||
DatagramPacket packet
|
||||
= new DatagramPacket(buf, buf.length, address, port);
|
||||
socket.send(packet);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
socket.close();
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package biz.nellemann.syslogd;
|
||||
package biz.nellemann.syslogd.msg;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
|
@ -1,4 +1,4 @@
|
|||
package biz.nellemann.syslogd;
|
||||
package biz.nellemann.syslogd.msg;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
|
@ -13,40 +13,40 @@
|
|||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package biz.nellemann.syslogd;
|
||||
package biz.nellemann.syslogd.msg;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
public class SyslogMessage {
|
||||
|
||||
protected Facility facility;
|
||||
protected Severity severity;
|
||||
public Facility facility;
|
||||
public Severity severity;
|
||||
|
||||
// The VERSION field denotes the version of the syslog protocol specification.
|
||||
protected Integer version;
|
||||
public Integer version;
|
||||
|
||||
// The TIMESTAMP field is a formalized timestamp derived from [RFC3339].
|
||||
protected Instant timestamp;
|
||||
public Instant timestamp;
|
||||
|
||||
// The HOSTNAME field identifies the machine that originally sent the syslog message.
|
||||
protected String hostname;
|
||||
public String hostname;
|
||||
|
||||
// The APP-NAME field SHOULD identify the device or application that originated the message.
|
||||
protected String application;
|
||||
public String application = "-";
|
||||
|
||||
// The PROCID field is often used to provide the process name or process ID associated with a syslog system.
|
||||
protected String processId;
|
||||
public String processId = "-";
|
||||
|
||||
// The MSGID SHOULD identify the type of message.
|
||||
protected String messageId;
|
||||
public String messageId = "-";
|
||||
|
||||
// STRUCTURED-DATA provides a mechanism to express information in a well defined, easily parseable and interpretable data format.
|
||||
protected String structuredData;
|
||||
public String structuredData = "-";
|
||||
|
||||
// The MSG part contains a free-form message that provides information about the event.
|
||||
protected final String message;
|
||||
public final String message;
|
||||
|
||||
SyslogMessage(final String message) {
|
||||
public SyslogMessage(final String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
|
@ -13,26 +13,29 @@
|
|||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package biz.nellemann.syslogd;
|
||||
package biz.nellemann.syslogd.net;
|
||||
|
||||
import biz.nellemann.syslogd.LogEvent;
|
||||
import biz.nellemann.syslogd.LogListener;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class TcpServer {
|
||||
|
||||
private final int port;
|
||||
private ServerSocket serverSocket;
|
||||
|
||||
TcpServer() {
|
||||
public TcpServer() {
|
||||
this(514);
|
||||
}
|
||||
|
||||
TcpServer(int port) {
|
||||
public TcpServer(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
50
src/main/java/biz/nellemann/syslogd/net/UdpClient.java
Normal file
50
src/main/java/biz/nellemann/syslogd/net/UdpClient.java
Normal file
|
@ -0,0 +1,50 @@
|
|||
package biz.nellemann.syslogd.net;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class UdpClient {
|
||||
|
||||
private final static Logger log = LoggerFactory.getLogger(UdpClient.class);
|
||||
|
||||
private DatagramSocket socket;
|
||||
private InetAddress address;
|
||||
private final Integer port;
|
||||
|
||||
public UdpClient(String host, Integer port) throws UnknownHostException, SocketException {
|
||||
|
||||
try {
|
||||
this.address = InetAddress.getByName(host);
|
||||
} catch (UnknownHostException e) {
|
||||
log.error("UdpClient() - UnknownHostException: " + e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
this.socket = new DatagramSocket();
|
||||
} catch (SocketException e) {
|
||||
log.error("UdpClient() - Could not instantiate DatagramSocket: " + e.getMessage());
|
||||
}
|
||||
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public void send(String msg) {
|
||||
byte[] buf = msg.getBytes(StandardCharsets.US_ASCII);
|
||||
DatagramPacket packet = new DatagramPacket(buf, buf.length, address, port);
|
||||
if(this.socket != null) {
|
||||
try {
|
||||
socket.send(packet);
|
||||
} catch (IOException e) {
|
||||
log.error("send() - Could not send packet: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
socket.close();
|
||||
}
|
||||
}
|
|
@ -13,7 +13,11 @@
|
|||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package biz.nellemann.syslogd;
|
||||
package biz.nellemann.syslogd.net;
|
||||
|
||||
import biz.nellemann.syslogd.Application;
|
||||
import biz.nellemann.syslogd.LogEvent;
|
||||
import biz.nellemann.syslogd.LogListener;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
|
@ -68,7 +72,7 @@ public class UdpServer extends Thread {
|
|||
|
||||
protected List<LogListener> eventListeners = new ArrayList<>();
|
||||
|
||||
public synchronized void addEventListener( LogListener l ) {
|
||||
public synchronized void addEventListener(Application l ) {
|
||||
eventListeners.add( l );
|
||||
}
|
||||
|
66
src/main/java/biz/nellemann/syslogd/parser/SyslogParser.java
Normal file
66
src/main/java/biz/nellemann/syslogd/parser/SyslogParser.java
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
Copyright 2020 mark.nellemann@gmail.com
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package biz.nellemann.syslogd.parser;
|
||||
|
||||
import biz.nellemann.syslogd.msg.SyslogMessage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
public abstract class SyslogParser {
|
||||
|
||||
private final static Logger log = LoggerFactory.getLogger(SyslogParser.class);
|
||||
|
||||
|
||||
public abstract SyslogMessage parse(final String input);
|
||||
|
||||
abstract Instant parseTimestamp(final String dateString);
|
||||
|
||||
|
||||
/**
|
||||
* Converts syslog PRI field into Facility.
|
||||
*
|
||||
* @param pri
|
||||
* @return
|
||||
*/
|
||||
public int getFacility(String pri) {
|
||||
|
||||
int priority = Integer.parseInt(pri);
|
||||
int facility = priority >> 3;
|
||||
|
||||
//log.debug("getFacility() - " + pri + " => " + facility);
|
||||
return facility;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts syslog PRI field into Severity.
|
||||
*
|
||||
* @param pri
|
||||
* @return
|
||||
*/
|
||||
public int getSeverity(String pri) {
|
||||
|
||||
int priority = Integer.parseInt(pri);
|
||||
int severity = priority & 0x07;
|
||||
|
||||
//log.debug("getSeverity() - " + pri + " => " + severity);
|
||||
return severity;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
Copyright 2020 mark.nellemann@gmail.com
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package biz.nellemann.syslogd.parser;
|
||||
|
||||
import biz.nellemann.syslogd.msg.Facility;
|
||||
import biz.nellemann.syslogd.msg.Severity;
|
||||
import biz.nellemann.syslogd.msg.SyslogMessage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.time.*;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class SyslogParserRfc3164 extends SyslogParser {
|
||||
|
||||
private final static Logger log = LoggerFactory.getLogger(SyslogParserRfc3164.class);
|
||||
|
||||
private final Pattern pattern = Pattern.compile("^<(\\d{1,3})>(\\D{3}\\s+\\d{1,2} \\d{2}:\\d{2}:\\d{2})\\s+(Message forwarded from \\S+:|\\S+)\\s+([^\\s:]+):?\\s+(.*)", Pattern.CASE_INSENSITIVE);
|
||||
private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy MMM [ ]d HH:mm:ss").withZone(ZoneId.systemDefault()); //.withZone(ZoneOffset.UTC);
|
||||
|
||||
/**
|
||||
* Parses [rfc3164](https://tools.ietf.org/html/rfc3164) syslog messages.
|
||||
*
|
||||
* @param input
|
||||
* @return
|
||||
* @throws NumberFormatException
|
||||
*/
|
||||
@Override
|
||||
public SyslogMessage parse(final String input) throws NumberFormatException {
|
||||
|
||||
log.debug("parseRfc3164() " + input);
|
||||
|
||||
Matcher matcher = pattern.matcher(input);
|
||||
if(!matcher.find()) {
|
||||
System.err.println("!" + input);
|
||||
return null;
|
||||
}
|
||||
|
||||
String pri = matcher.group(1);
|
||||
String date = matcher.group(2);
|
||||
String hostname = matcher.group(3);
|
||||
String application = matcher.group(4);
|
||||
String msg = matcher.group(5);
|
||||
|
||||
if(hostname.endsWith(":")) {
|
||||
String[] tmp = hostname.split(" ");
|
||||
hostname = tmp[tmp.length-1];
|
||||
hostname = hostname.substring(0, hostname.length()-1);
|
||||
}
|
||||
|
||||
Integer facility = getFacility(pri);
|
||||
Integer severity = getSeverity(pri);
|
||||
|
||||
SyslogMessage syslogMessage = new SyslogMessage(msg.trim());
|
||||
syslogMessage.facility = Facility.getByNumber(facility);
|
||||
syslogMessage.severity = Severity.getByNumber(severity);
|
||||
syslogMessage.timestamp = parseTimestamp(date);
|
||||
syslogMessage.hostname = hostname;
|
||||
syslogMessage.application = application;
|
||||
|
||||
return syslogMessage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse rfc3164 TIMESTAMP field into Instant.
|
||||
*
|
||||
* @param dateString
|
||||
* @return
|
||||
*/
|
||||
protected Instant parseTimestamp(String dateString) {
|
||||
|
||||
// We need to add year to parse date correctly
|
||||
OffsetDateTime odt = OffsetDateTime.now();
|
||||
|
||||
// Date: Mmm dd hh:mm:ss
|
||||
Instant instant = null;
|
||||
try {
|
||||
instant = Instant.from(dateTimeFormatter.parse(odt.getYear() + " " + dateString));
|
||||
} catch(DateTimeParseException e) {
|
||||
log.error("parseDate()", e);
|
||||
}
|
||||
|
||||
return instant;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
Copyright 2020 mark.nellemann@gmail.com
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
package biz.nellemann.syslogd.parser;
|
||||
|
||||
import biz.nellemann.syslogd.msg.Severity;
|
||||
import biz.nellemann.syslogd.msg.Facility;
|
||||
import biz.nellemann.syslogd.msg.SyslogMessage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class SyslogParserRfc5424 extends SyslogParser {
|
||||
|
||||
private final static Logger log = LoggerFactory.getLogger(SyslogParserRfc5424.class);
|
||||
|
||||
private final Pattern pattern = Pattern.compile("^<(\\d{1,3})>(\\d+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\[.*\\]|-)\\s+(\\S+)", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
/**
|
||||
* Parses [rfc5424](https://tools.ietf.org/html/rfc5424) syslog messages.
|
||||
*
|
||||
* @param input
|
||||
* @return
|
||||
* @throws NumberFormatException
|
||||
*/
|
||||
@Override
|
||||
public SyslogMessage parse(final String input) throws NumberFormatException {
|
||||
|
||||
log.debug("parseRfc5424() " + input);
|
||||
|
||||
Matcher matcher = pattern.matcher(input);
|
||||
boolean matchFound = matcher.find();
|
||||
if(!matchFound) {
|
||||
log.debug("parseRfc5424() - Match not found in: " + input);
|
||||
System.err.println("!" + input);
|
||||
return null;
|
||||
}
|
||||
|
||||
String pri = matcher.group(1);
|
||||
String ver = matcher.group(2);
|
||||
String date = matcher.group(3);
|
||||
String host = matcher.group(4);
|
||||
String app = matcher.group(5);
|
||||
String procId = matcher.group(6);
|
||||
String msgId = matcher.group(7);
|
||||
String data = matcher.group(8);
|
||||
String msg = matcher.group(9);
|
||||
|
||||
Integer facility = getFacility(pri);
|
||||
Integer severity = getSeverity(pri);
|
||||
|
||||
SyslogMessage syslogMessage = new SyslogMessage(msg.trim());
|
||||
syslogMessage.facility = Facility.getByNumber(facility);
|
||||
syslogMessage.severity = Severity.getByNumber(severity);
|
||||
syslogMessage.version = Integer.parseInt(ver);
|
||||
syslogMessage.timestamp = parseTimestamp(date);
|
||||
syslogMessage.hostname = host;
|
||||
if(app != null && !app.equals("-"))
|
||||
syslogMessage.application = app;
|
||||
if(procId != null && !procId.equals("-"))
|
||||
syslogMessage.processId = procId;
|
||||
if(msgId != null && !msgId.equals("-"))
|
||||
syslogMessage.messageId = msgId;
|
||||
if(data != null && !data.equals("-"))
|
||||
syslogMessage.structuredData = data;
|
||||
|
||||
return syslogMessage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse rfc5424 TIMESTAMP field into Instant.
|
||||
*
|
||||
* @param dateString
|
||||
* @return
|
||||
*/
|
||||
protected Instant parseTimestamp(String dateString) {
|
||||
|
||||
/*
|
||||
https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
|
||||
|
||||
ex1: 1985-04-12T23:20:50.52Z
|
||||
ex2: 1985-04-12T19:20:50.52-04:00
|
||||
ex3: 2003-10-11T22:14:15.003Z
|
||||
ex4: 2003-08-24T05:14:15.000003-07:00
|
||||
ex5: 2003-08-24T05:14:15.000000003-07:00
|
||||
*/
|
||||
|
||||
List<String> formatStrings = Arrays.asList(
|
||||
"yyyy-MM-dd'T'HH:mm:ss.SS'Z'",
|
||||
"yyyy-MM-dd'T'HH:mm:ss.SSXXX",
|
||||
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
|
||||
"yyyy-MM-dd'T'HH:mm:ss.SSSSSSXXX",
|
||||
"yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSSXXX"
|
||||
);
|
||||
|
||||
for(String formatString : formatStrings)
|
||||
{
|
||||
try {
|
||||
return new SimpleDateFormat(formatString).parse(dateString).toInstant();
|
||||
}
|
||||
catch (ParseException e) {}
|
||||
}
|
||||
/*
|
||||
try {
|
||||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
|
||||
instant = Instant.from(dateTimeFormatter.parse(dateString));
|
||||
} catch(DateTimeParseException e) {
|
||||
log.error("parseTimestamp()", e);
|
||||
}
|
||||
return instant;*/
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
package biz.nellemann.syslogd
|
||||
|
||||
import biz.nellemann.syslogd.msg.SyslogMessage
|
||||
import biz.nellemann.syslogd.parser.SyslogParser
|
||||
import biz.nellemann.syslogd.parser.SyslogParserRfc3164
|
||||
import spock.lang.Specification
|
||||
import java.time.Instant
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
class SyslogParserRfc3164Test extends Specification {
|
||||
|
||||
SyslogParser syslogParser;
|
||||
|
||||
void setup() {
|
||||
syslogParser = new SyslogParserRfc3164();
|
||||
}
|
||||
|
||||
|
||||
void "test rfc3164 aix/vios message"() {
|
||||
|
||||
setup:
|
||||
def input = "<13>Sep 23 08:37:09 Message forwarded from p924vio1: padmin: test"
|
||||
|
||||
when:
|
||||
SyslogMessage msg = syslogParser.parse(input)
|
||||
|
||||
then:
|
||||
msg.message == "test"
|
||||
msg.hostname == "p924vio1"
|
||||
msg.application == "padmin"
|
||||
}
|
||||
|
||||
void "test another rfc3164 aix/vios message"() {
|
||||
|
||||
setup:
|
||||
def input = "<13>Dec 18 10:09:22 Message forwarded from p924vio1: root: [errnotify] seq: 24266 - AA8AB241 1218100920 T O OPERATOR OPERATOR NOTIFICATION"
|
||||
|
||||
when:
|
||||
SyslogMessage msg = syslogParser.parse(input)
|
||||
|
||||
then:
|
||||
msg.message == "[errnotify] seq: 24266 - AA8AB241 1218100920 T O OPERATOR OPERATOR NOTIFICATION"
|
||||
msg.hostname == "p924vio1"
|
||||
msg.application == "root"
|
||||
}
|
||||
|
||||
void "test rfc3164 normal message"() {
|
||||
|
||||
setup:
|
||||
def input = "<13>Sep 23 08:53:28 xps13 mark: adfdfdf3432434"
|
||||
|
||||
when:
|
||||
SyslogMessage msg = syslogParser.parse(input)
|
||||
|
||||
then:
|
||||
msg.message == "adfdfdf3432434"
|
||||
msg.hostname == "xps13"
|
||||
msg.application == "mark"
|
||||
}
|
||||
|
||||
void "test rsyslogd sudo message"() {
|
||||
setup:
|
||||
String input = "<85>Oct 5 17:13:41 xps13 sudo: mark : TTY=pts/1 ; PWD=/etc/rsyslog.d ; USER=root ; COMMAND=/usr/sbin/service rsyslog restart"
|
||||
|
||||
when:
|
||||
SyslogMessage msg = syslogParser.parse(input)
|
||||
|
||||
then:
|
||||
msg.application == "sudo"
|
||||
msg.message == "mark : TTY=pts/1 ; PWD=/etc/rsyslog.d ; USER=root ; COMMAND=/usr/sbin/service rsyslog restart"
|
||||
}
|
||||
|
||||
void "test gdm-session message"() {
|
||||
setup:
|
||||
String input = "<12>Oct 5 18:31:01 xps13 /usr/lib/gdm3/gdm-x-session[1921]: (EE) event5 - CUST0001:00 06CB:76AF Touchpad: kernel bug: Touch jump detected and discarded."
|
||||
|
||||
when:
|
||||
SyslogMessage msg = syslogParser.parse(input)
|
||||
|
||||
then:
|
||||
msg.application == "/usr/lib/gdm3/gdm-x-session[1921]"
|
||||
msg.message == "(EE) event5 - CUST0001:00 06CB:76AF Touchpad: kernel bug: Touch jump detected and discarded."
|
||||
}
|
||||
|
||||
void "test intellij message"() {
|
||||
setup:
|
||||
String input = "<14>Oct 6 05:10:26 xps13 com.jetbrains.IntelliJ-IDEA-Ulti git4idea.commands.GitStandardProgressAnalyzer\$1.onLineAvailable(GitStandardProgressAnalyzer.java:45)"
|
||||
|
||||
when:
|
||||
SyslogMessage msg = syslogParser.parse(input)
|
||||
|
||||
then:
|
||||
msg.application == "com.jetbrains.IntelliJ-IDEA-Ulti"
|
||||
msg.message == "git4idea.commands.GitStandardProgressAnalyzer\$1.onLineAvailable(GitStandardProgressAnalyzer.java:45)"
|
||||
}
|
||||
|
||||
void "test parseRfc3164Timestamp"() {
|
||||
|
||||
setup:
|
||||
OffsetDateTime odt = OffsetDateTime.now()
|
||||
String dateString = "Sep 12 20:50:13"
|
||||
|
||||
when:
|
||||
Instant inst = syslogParser.parseTimestamp(dateString)
|
||||
|
||||
then:
|
||||
inst.toString() == "${odt.getYear()}-09-12T18:50:13Z"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
package biz.nellemann.syslogd
|
||||
|
||||
import biz.nellemann.syslogd.msg.SyslogMessage
|
||||
import biz.nellemann.syslogd.parser.SyslogParser
|
||||
import biz.nellemann.syslogd.parser.SyslogParserRfc5424
|
||||
import spock.lang.Specification
|
||||
import java.time.Instant
|
||||
|
||||
class SyslogParserRfc5424Test extends Specification {
|
||||
|
||||
SyslogParser syslogParser;
|
||||
|
||||
void setup() {
|
||||
syslogParser = new SyslogParserRfc5424();
|
||||
}
|
||||
|
||||
void "test rfc5424 message"() {
|
||||
|
||||
setup:
|
||||
def input = '<13>1 2020-09-23T08:57:30.950699+02:00 xps13 mark - - [exampleSDID@32473 iut="3" eventSource="Application" eventID="1011"] adfdfdf3432434565656'
|
||||
|
||||
when:
|
||||
SyslogMessage msg = syslogParser.parse(input)
|
||||
|
||||
then:
|
||||
msg.message == "adfdfdf3432434565656"
|
||||
msg.processId == "-"
|
||||
}
|
||||
|
||||
void "test rfc5424 example message"() {
|
||||
|
||||
setup:
|
||||
def input = "<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - BOM'su root' failed for lonvick on /dev/pts/8"
|
||||
|
||||
when:
|
||||
SyslogMessage msg = syslogParser.parse(input)
|
||||
|
||||
then:
|
||||
msg.hostname == "mymachine.example.com"
|
||||
msg.application == "su"
|
||||
msg.processId == "-"
|
||||
msg.messageId == "ID47"
|
||||
msg.structuredData == "-"
|
||||
}
|
||||
|
||||
void "test rfc5424 example2 message"() {
|
||||
|
||||
setup:
|
||||
def input = "<165>1 2003-08-24T05:14:15.000003-07:00 192.0.2.1 myproc 8710 - - %% It's time to make the do-nuts."
|
||||
|
||||
when:
|
||||
SyslogMessage msg = syslogParser.parse(input)
|
||||
|
||||
then:
|
||||
msg.hostname == "192.0.2.1"
|
||||
msg.application == "myproc"
|
||||
msg.processId == "8710"
|
||||
msg.messageId == "-"
|
||||
msg.structuredData == "-"
|
||||
}
|
||||
|
||||
void "test parseRfc5424Timestamp ex1"() {
|
||||
setup:
|
||||
String dateString = "1985-04-12T23:20:50.52Z"
|
||||
|
||||
when:
|
||||
Instant inst = syslogParser.parseTimestamp(dateString)
|
||||
|
||||
then:
|
||||
inst.toString() == "1985-04-12T21:20:50.052Z"
|
||||
inst.toEpochMilli() == 482188850052
|
||||
}
|
||||
|
||||
void "test parseRfc5424Timestamp ex2"() {
|
||||
setup:
|
||||
String dateString = "1985-04-12T19:20:50.52-04:00"
|
||||
|
||||
when:
|
||||
Instant inst = syslogParser.parseTimestamp(dateString)
|
||||
|
||||
then:
|
||||
inst.toString() == "1985-04-12T23:20:50.052Z"
|
||||
inst.toEpochMilli() == 482196050052
|
||||
}
|
||||
|
||||
void "test parseRfc5424Timestamp ex3"() {
|
||||
setup:
|
||||
String dateString = "2003-10-11T22:14:15.003Z"
|
||||
|
||||
when:
|
||||
Instant inst = syslogParser.parseTimestamp(dateString)
|
||||
|
||||
then:
|
||||
inst.toString() == "2003-10-11T20:14:15.003Z"
|
||||
inst.toEpochMilli() == 1065903255003
|
||||
}
|
||||
|
||||
void "test parseRfc5424Timestamp ex4"() {
|
||||
setup:
|
||||
String dateString = "2003-08-24T05:14:15.000003-07:00"
|
||||
|
||||
when:
|
||||
Instant inst = syslogParser.parseTimestamp(dateString)
|
||||
|
||||
then:
|
||||
inst.toString() == "2003-08-24T12:14:15.003Z"
|
||||
inst.toEpochMilli() == 1061727255003
|
||||
}
|
||||
|
||||
void "test parseRfc5424Timestamp ex5"() {
|
||||
setup:
|
||||
String dateString = "2003-08-24T05:14:15.000000003-07:00"
|
||||
|
||||
when:
|
||||
Instant inst = syslogParser.parseTimestamp(dateString)
|
||||
|
||||
then:
|
||||
inst.toString() == "2003-08-24T12:14:15.003Z"
|
||||
inst.toEpochMilli() == 1061727255003
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,125 +1,33 @@
|
|||
package biz.nellemann.syslogd
|
||||
|
||||
import biz.nellemann.syslogd.msg.Facility
|
||||
import biz.nellemann.syslogd.msg.Severity
|
||||
import biz.nellemann.syslogd.parser.SyslogParser
|
||||
import biz.nellemann.syslogd.parser.SyslogParserRfc5424
|
||||
import spock.lang.Specification
|
||||
import java.time.Instant
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
class SyslogParserTest extends Specification {
|
||||
|
||||
void "test rfc5424 message"() {
|
||||
SyslogParser syslogParser;
|
||||
|
||||
setup:
|
||||
def input = "<13>1 2020-09-23T08:57:30.950699+02:00 xps13 mark - - [timeQuality tzKnown=\"1\" isSynced=\"1\" syncAccuracy=\"125500\"] adfdfdf3432434565656"
|
||||
void setup() {
|
||||
syslogParser = new SyslogParserRfc5424();
|
||||
}
|
||||
|
||||
void "test facility LOCAL0"() {
|
||||
when:
|
||||
SyslogMessage msg = SyslogParser.parseRfc5424(input)
|
||||
int code = syslogParser.getFacility("132")
|
||||
|
||||
then:
|
||||
msg.message == "adfdfdf3432434565656"
|
||||
code == Facility.LOCAL0.toNumber()
|
||||
}
|
||||
|
||||
void "test rfc3164 aix/vios message"() {
|
||||
|
||||
setup:
|
||||
def input = "<13>Sep 23 08:37:09 Message forwarded from p924vio1: padmin: test"
|
||||
|
||||
void "test severity WARN"() {
|
||||
when:
|
||||
SyslogMessage msg = SyslogParser.parseRfc3164(input)
|
||||
int code = syslogParser.getSeverity("132")
|
||||
|
||||
then:
|
||||
msg.message == "test"
|
||||
msg.hostname == "p924vio1"
|
||||
msg.application == "padmin"
|
||||
}
|
||||
|
||||
void "test another rfc3164 aix/vios message"() {
|
||||
|
||||
setup:
|
||||
def input = "<13>Dec 18 10:09:22 Message forwarded from p924vio1: root: [errnotify] seq: 24266 - AA8AB241 1218100920 T O OPERATOR OPERATOR NOTIFICATION"
|
||||
|
||||
when:
|
||||
SyslogMessage msg = SyslogParser.parseRfc3164(input)
|
||||
|
||||
then:
|
||||
msg.message == "[errnotify] seq: 24266 - AA8AB241 1218100920 T O OPERATOR OPERATOR NOTIFICATION"
|
||||
msg.hostname == "p924vio1"
|
||||
msg.application == "root"
|
||||
}
|
||||
|
||||
void "test rfc3164 normal message"() {
|
||||
|
||||
setup:
|
||||
def input = "<13>Sep 23 08:53:28 xps13 mark: adfdfdf3432434"
|
||||
|
||||
when:
|
||||
SyslogMessage msg = SyslogParser.parseRfc3164(input)
|
||||
|
||||
then:
|
||||
msg.message == "adfdfdf3432434"
|
||||
msg.hostname == "xps13"
|
||||
msg.application == "mark"
|
||||
}
|
||||
|
||||
void "test rsyslogd sudo message"() {
|
||||
setup:
|
||||
String input = "<85>Oct 5 17:13:41 xps13 sudo: mark : TTY=pts/1 ; PWD=/etc/rsyslog.d ; USER=root ; COMMAND=/usr/sbin/service rsyslog restart"
|
||||
|
||||
when:
|
||||
SyslogMessage msg = SyslogParser.parseRfc3164(input)
|
||||
|
||||
then:
|
||||
msg.application == "sudo"
|
||||
msg.message == "mark : TTY=pts/1 ; PWD=/etc/rsyslog.d ; USER=root ; COMMAND=/usr/sbin/service rsyslog restart"
|
||||
}
|
||||
|
||||
void "test gdm-session message"() {
|
||||
setup:
|
||||
String input = "<12>Oct 5 18:31:01 xps13 /usr/lib/gdm3/gdm-x-session[1921]: (EE) event5 - CUST0001:00 06CB:76AF Touchpad: kernel bug: Touch jump detected and discarded."
|
||||
|
||||
when:
|
||||
SyslogMessage msg = SyslogParser.parseRfc3164(input)
|
||||
|
||||
then:
|
||||
msg.application == "/usr/lib/gdm3/gdm-x-session[1921]"
|
||||
msg.message == "(EE) event5 - CUST0001:00 06CB:76AF Touchpad: kernel bug: Touch jump detected and discarded."
|
||||
}
|
||||
|
||||
void "test intellij message"() {
|
||||
setup:
|
||||
String input = "<14>Oct 6 05:10:26 xps13 com.jetbrains.IntelliJ-IDEA-Ulti git4idea.commands.GitStandardProgressAnalyzer\$1.onLineAvailable(GitStandardProgressAnalyzer.java:45)"
|
||||
|
||||
when:
|
||||
SyslogMessage msg = SyslogParser.parseRfc3164(input)
|
||||
|
||||
then:
|
||||
msg.application == "com.jetbrains.IntelliJ-IDEA-Ulti"
|
||||
msg.message == "git4idea.commands.GitStandardProgressAnalyzer\$1.onLineAvailable(GitStandardProgressAnalyzer.java:45)"
|
||||
}
|
||||
|
||||
void "test parseRfc3164Timestamp"() {
|
||||
|
||||
setup:
|
||||
OffsetDateTime odt = OffsetDateTime.now()
|
||||
String dateString = "Sep 12 20:50:13"
|
||||
|
||||
when:
|
||||
Instant inst = SyslogParser.parseRfc3164Timestamp(dateString)
|
||||
|
||||
then:
|
||||
inst.toString() == "${odt.getYear()}-09-12T20:50:13Z"
|
||||
}
|
||||
|
||||
void "test parseRfc5424Timestamp"() {
|
||||
|
||||
setup:
|
||||
String dateString = "2020-09-22T20:10:30.925438+02:00"
|
||||
|
||||
when:
|
||||
Instant inst = SyslogParser.parseRfc5424Timestamp(dateString)
|
||||
|
||||
then:
|
||||
inst.toString() == "2020-09-22T18:10:30.925438Z"
|
||||
inst.toEpochMilli() == 1600798230925l
|
||||
code == Severity.WARN.toNumber()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
6
src/test/resources/simplelogger.properties
Normal file
6
src/test/resources/simplelogger.properties
Normal file
|
@ -0,0 +1,6 @@
|
|||
org.slf4j.simpleLogger.logFile=System.err
|
||||
org.slf4j.simpleLogger.showDateTime=false
|
||||
org.slf4j.simpleLogger.showShortLogName=true
|
||||
org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss.SSS
|
||||
org.slf4j.simpleLogger.levelInBrackets=true
|
||||
org.slf4j.simpleLogger.defaultLogLevel=debug
|
Loading…
Reference in a new issue