Correct parsing of PRI to facility and severity + ansi colors in output.
This commit is contained in:
parent
7a019c5c18
commit
4106453a68
87
src/main/java/biz/nellemann/syslogd/Color.java
Normal file
87
src/main/java/biz/nellemann/syslogd/Color.java
Normal file
|
@ -0,0 +1,87 @@
|
|||
package biz.nellemann.syslogd;
|
||||
|
||||
public enum Color {
|
||||
//Color end string, color reset
|
||||
RESET("\033[0m"),
|
||||
|
||||
// Regular Colors. Normal color, no bold, background color etc.
|
||||
BLACK("\033[0;30m"), // BLACK
|
||||
RED("\033[0;31m"), // RED
|
||||
GREEN("\033[0;32m"), // GREEN
|
||||
YELLOW("\033[0;33m"), // YELLOW
|
||||
BLUE("\033[0;34m"), // BLUE
|
||||
MAGENTA("\033[0;35m"), // MAGENTA
|
||||
CYAN("\033[0;36m"), // CYAN
|
||||
WHITE("\033[0;37m"), // WHITE
|
||||
|
||||
// Bold
|
||||
BLACK_BOLD("\033[1;30m"), // BLACK
|
||||
RED_BOLD("\033[1;31m"), // RED
|
||||
GREEN_BOLD("\033[1;32m"), // GREEN
|
||||
YELLOW_BOLD("\033[1;33m"), // YELLOW
|
||||
BLUE_BOLD("\033[1;34m"), // BLUE
|
||||
MAGENTA_BOLD("\033[1;35m"), // MAGENTA
|
||||
CYAN_BOLD("\033[1;36m"), // CYAN
|
||||
WHITE_BOLD("\033[1;37m"), // WHITE
|
||||
|
||||
// Underline
|
||||
BLACK_UNDERLINED("\033[4;30m"), // BLACK
|
||||
RED_UNDERLINED("\033[4;31m"), // RED
|
||||
GREEN_UNDERLINED("\033[4;32m"), // GREEN
|
||||
YELLOW_UNDERLINED("\033[4;33m"), // YELLOW
|
||||
BLUE_UNDERLINED("\033[4;34m"), // BLUE
|
||||
MAGENTA_UNDERLINED("\033[4;35m"), // MAGENTA
|
||||
CYAN_UNDERLINED("\033[4;36m"), // CYAN
|
||||
WHITE_UNDERLINED("\033[4;37m"), // WHITE
|
||||
|
||||
// Background
|
||||
BLACK_BACKGROUND("\033[40m"), // BLACK
|
||||
RED_BACKGROUND("\033[41m"), // RED
|
||||
GREEN_BACKGROUND("\033[42m"), // GREEN
|
||||
YELLOW_BACKGROUND("\033[43m"), // YELLOW
|
||||
BLUE_BACKGROUND("\033[44m"), // BLUE
|
||||
MAGENTA_BACKGROUND("\033[45m"), // MAGENTA
|
||||
CYAN_BACKGROUND("\033[46m"), // CYAN
|
||||
WHITE_BACKGROUND("\033[47m"), // WHITE
|
||||
|
||||
// High Intensity
|
||||
BLACK_BRIGHT("\033[0;90m"), // BLACK
|
||||
RED_BRIGHT("\033[0;91m"), // RED
|
||||
GREEN_BRIGHT("\033[0;92m"), // GREEN
|
||||
YELLOW_BRIGHT("\033[0;93m"), // YELLOW
|
||||
BLUE_BRIGHT("\033[0;94m"), // BLUE
|
||||
MAGENTA_BRIGHT("\033[0;95m"), // MAGENTA
|
||||
CYAN_BRIGHT("\033[0;96m"), // CYAN
|
||||
WHITE_BRIGHT("\033[0;97m"), // WHITE
|
||||
|
||||
// Bold High Intensity
|
||||
BLACK_BOLD_BRIGHT("\033[1;90m"), // BLACK
|
||||
RED_BOLD_BRIGHT("\033[1;91m"), // RED
|
||||
GREEN_BOLD_BRIGHT("\033[1;92m"), // GREEN
|
||||
YELLOW_BOLD_BRIGHT("\033[1;93m"), // YELLOW
|
||||
BLUE_BOLD_BRIGHT("\033[1;94m"), // BLUE
|
||||
MAGENTA_BOLD_BRIGHT("\033[1;95m"), // MAGENTA
|
||||
CYAN_BOLD_BRIGHT("\033[1;96m"), // CYAN
|
||||
WHITE_BOLD_BRIGHT("\033[1;97m"), // WHITE
|
||||
|
||||
// High Intensity backgrounds
|
||||
BLACK_BACKGROUND_BRIGHT("\033[0;100m"), // BLACK
|
||||
RED_BACKGROUND_BRIGHT("\033[0;101m"), // RED
|
||||
GREEN_BACKGROUND_BRIGHT("\033[0;102m"), // GREEN
|
||||
YELLOW_BACKGROUND_BRIGHT("\033[0;103m"), // YELLOW
|
||||
BLUE_BACKGROUND_BRIGHT("\033[0;104m"), // BLUE
|
||||
MAGENTA_BACKGROUND_BRIGHT("\033[0;105m"), // MAGENTA
|
||||
CYAN_BACKGROUND_BRIGHT("\033[0;106m"), // CYAN
|
||||
WHITE_BACKGROUND_BRIGHT("\033[0;107m"); // WHITE
|
||||
|
||||
private final String code;
|
||||
|
||||
Color(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return code;
|
||||
}
|
||||
}
|
80
src/main/java/biz/nellemann/syslogd/Facility.java
Normal file
80
src/main/java/biz/nellemann/syslogd/Facility.java
Normal file
|
@ -0,0 +1,80 @@
|
|||
package biz.nellemann.syslogd;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/*
|
||||
0 kernel messages
|
||||
1 user-level messages
|
||||
2 mail system
|
||||
3 system daemons
|
||||
4 security/authorization messages
|
||||
5 messages generated internally by syslogd
|
||||
6 line printer subsystem
|
||||
7 network news subsystem
|
||||
8 UUCP subsystem
|
||||
9 clock daemon
|
||||
10 security/authorization messages
|
||||
11 FTP daemon
|
||||
12 NTP subsystem
|
||||
13 log audit
|
||||
14 log alert
|
||||
15 clock daemon (note 2)
|
||||
16 local use 0 (local0)
|
||||
17 local use 1 (local1)
|
||||
18 local use 2 (local2)
|
||||
19 local use 3 (local3)
|
||||
20 local use 4 (local4)
|
||||
21 local use 5 (local5)
|
||||
22 local use 6 (local6)
|
||||
23 local use 7 (local7)
|
||||
*/
|
||||
public enum Facility {
|
||||
|
||||
KERNEL(0),
|
||||
USER(1),
|
||||
MAIL(2),
|
||||
DAEMON(3),
|
||||
AUTH(4),
|
||||
SYSLOG(5),
|
||||
PRINT(6),
|
||||
NEWS(7),
|
||||
UUCP(8),
|
||||
CRON(9),
|
||||
AUTHPRIV(10),
|
||||
FTP(11),
|
||||
NTP(12),
|
||||
AUDIT(13),
|
||||
ALERT(14),
|
||||
TIME(15),
|
||||
LOCAL0(16),
|
||||
LOCAL1(17),
|
||||
LOCAL2(18),
|
||||
LOCAL3(19),
|
||||
LOCAL4(20),
|
||||
LOCAL5(21),
|
||||
LOCAL6(22),
|
||||
LOCAL7(23);
|
||||
|
||||
// Cache lookups
|
||||
private static final Map<Integer, Facility> BY_NUMBER = new HashMap<>();
|
||||
static {
|
||||
for (Facility f: values()) {
|
||||
BY_NUMBER.put(f.facilityNumber, f);
|
||||
}
|
||||
}
|
||||
|
||||
public static Facility getByNumber(Integer number) {
|
||||
return BY_NUMBER.get(number);
|
||||
}
|
||||
|
||||
public Integer toNumber() {
|
||||
return this.facilityNumber;
|
||||
}
|
||||
|
||||
private Integer facilityNumber;
|
||||
private Facility(int facilityNumber) {
|
||||
this.facilityNumber = facilityNumber;
|
||||
}
|
||||
|
||||
}
|
48
src/main/java/biz/nellemann/syslogd/Severity.java
Normal file
48
src/main/java/biz/nellemann/syslogd/Severity.java
Normal file
|
@ -0,0 +1,48 @@
|
|||
package biz.nellemann.syslogd;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/*
|
||||
0 Emergency: system is unusable
|
||||
1 Alert: action must be taken immediately
|
||||
2 Critical: critical conditions
|
||||
3 Error: error conditions
|
||||
4 Warning: warning conditions
|
||||
5 Notice: normal but significant condition
|
||||
6 Informational: informational messages
|
||||
7 Debug: debug-level messages
|
||||
*/
|
||||
public enum Severity {
|
||||
|
||||
EMERG(0),
|
||||
ALERT(1),
|
||||
CRIT(2),
|
||||
ERROR(3),
|
||||
WARN(4),
|
||||
NOTICE(5),
|
||||
INFO(6),
|
||||
DEBUG(7);
|
||||
|
||||
// Cache lookups
|
||||
private static final Map<Integer, Severity> BY_NUMBER = new HashMap<>();
|
||||
static {
|
||||
for (Severity s: values()) {
|
||||
BY_NUMBER.put(s.severityNumber, s);
|
||||
}
|
||||
}
|
||||
|
||||
public static Severity getByNumber(Integer number) {
|
||||
return BY_NUMBER.get(number);
|
||||
}
|
||||
|
||||
public Integer toNumber() {
|
||||
return this.severityNumber;
|
||||
}
|
||||
|
||||
private Integer severityNumber;
|
||||
private Severity(int severityNumber) {
|
||||
this.severityNumber = severityNumber;
|
||||
}
|
||||
|
||||
}
|
|
@ -19,46 +19,8 @@ import java.time.Instant;
|
|||
|
||||
public class SyslogMessage {
|
||||
|
||||
/*
|
||||
0 kernel messages
|
||||
1 user-level messages
|
||||
2 mail system
|
||||
3 system daemons
|
||||
4 security/authorization messages
|
||||
5 messages generated internally by syslogd
|
||||
6 line printer subsystem
|
||||
7 network news subsystem
|
||||
8 UUCP subsystem
|
||||
9 clock daemon
|
||||
10 security/authorization messages
|
||||
11 FTP daemon
|
||||
12 NTP subsystem
|
||||
13 log audit
|
||||
14 log alert
|
||||
15 clock daemon (note 2)
|
||||
16 local use 0 (local0)
|
||||
17 local use 1 (local1)
|
||||
18 local use 2 (local2)
|
||||
19 local use 3 (local3)
|
||||
20 local use 4 (local4)
|
||||
21 local use 5 (local5)
|
||||
22 local use 6 (local6)
|
||||
23 local use 7 (local7)
|
||||
*/
|
||||
protected Integer facility;
|
||||
|
||||
|
||||
/*
|
||||
0 Emergency: system is unusable
|
||||
1 Alert: action must be taken immediately
|
||||
2 Critical: critical conditions
|
||||
3 Error: error conditions
|
||||
4 Warning: warning conditions
|
||||
5 Notice: normal but significant condition
|
||||
6 Informational: informational messages
|
||||
7 Debug: debug-level messages
|
||||
*/
|
||||
Integer severity;
|
||||
Facility facility;
|
||||
Severity severity;
|
||||
|
||||
// The VERSION field denotes the version of the syslog protocol specification.
|
||||
Integer version;
|
||||
|
@ -86,7 +48,26 @@ public class SyslogMessage {
|
|||
|
||||
|
||||
public String toString() {
|
||||
return String.format("%s %s %s: %s", timestamp.toString(), hostname, application, message);
|
||||
//return String.format("%s %s %s: %s", timestamp.toString(), hostname, application, message);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append(Color.WHITE); sb.append(timestamp.toString() + " "); sb.append(Color.RESET);
|
||||
|
||||
if(severity.toNumber() < 3 ) {
|
||||
sb.append(Color.RED);
|
||||
} else if(severity.toNumber() < 5) {
|
||||
sb.append(Color.YELLOW);
|
||||
} else {
|
||||
sb.append(Color.GREEN);
|
||||
}
|
||||
sb.append("[" + facility + "." + severity + "]"); sb.append(Color.RESET);
|
||||
|
||||
sb.append(Color.BLUE); sb.append("\t" + hostname); sb.append(Color.RESET);
|
||||
sb.append(Color.CYAN); sb.append("\t" + application); sb.append(Color.RESET);
|
||||
sb.append("\t" + message);
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ import org.slf4j.LoggerFactory;
|
|||
import java.time.*;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -38,7 +37,7 @@ public class SyslogParser {
|
|||
|
||||
public static SyslogMessage parseRfc3164(String input) throws NumberFormatException {
|
||||
|
||||
Pattern pattern = Pattern.compile("^<(\\d{1,3})>(\\D{3} \\d{2} \\d{2}:\\d{2}:\\d{2})\\s+(\\S+)\\s+(\\S+): (.*)", Pattern.CASE_INSENSITIVE);
|
||||
Pattern pattern = Pattern.compile("^<(\\d{1,3})>(\\D{3} \\d{2} \\d{2}:\\d{2}:\\d{2})\\s+(?:Message forwarded from )?([^\\s:]+):?\\s+(\\S+): (.*)", Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcher = pattern.matcher(input);
|
||||
boolean matchFound = matcher.find();
|
||||
if(!matchFound) {
|
||||
|
@ -58,14 +57,14 @@ public class SyslogParser {
|
|||
log.debug("APP: " + application);
|
||||
log.debug("MSG: " + message);
|
||||
|
||||
Integer facility = Integer.parseInt(pri.substring(0, pri.length()-1));
|
||||
Integer severity = Integer.parseInt(pri.substring(pri.length()-1));
|
||||
Integer facility = getFacility(pri);
|
||||
Integer severity = getSeverity(pri);
|
||||
log.debug("facility: " + facility);
|
||||
log.debug("severity: " + severity);
|
||||
|
||||
SyslogMessage syslogMessage = new SyslogMessage();
|
||||
syslogMessage.facility = facility;
|
||||
syslogMessage.severity = severity;
|
||||
syslogMessage.facility = Facility.getByNumber(facility);
|
||||
syslogMessage.severity = Severity.getByNumber(severity);
|
||||
syslogMessage.timestamp = parseRfc3164Timestamp(date);
|
||||
syslogMessage.hostname = hostname;
|
||||
syslogMessage.application = application;
|
||||
|
@ -105,14 +104,14 @@ public class SyslogParser {
|
|||
log.debug("DATA: " + data);
|
||||
log.debug("MSG: " + msg);
|
||||
|
||||
Integer facility = Integer.parseInt(pri.substring(0, pri.length()-1));
|
||||
Integer severity = Integer.parseInt(pri.substring(pri.length()-1));
|
||||
Integer facility = getFacility(pri);
|
||||
Integer severity = getSeverity(pri);
|
||||
log.debug("facility: " + facility);
|
||||
log.debug("severity: " + severity);
|
||||
|
||||
SyslogMessage syslogMessage = new SyslogMessage();
|
||||
syslogMessage.facility = facility;
|
||||
syslogMessage.severity = severity;
|
||||
syslogMessage.facility = Facility.getByNumber(facility);
|
||||
syslogMessage.severity = Severity.getByNumber(severity);
|
||||
syslogMessage.version = Integer.parseInt(ver);
|
||||
syslogMessage.timestamp = parseRfc5424Timestamp(date);
|
||||
syslogMessage.hostname = host;
|
||||
|
@ -160,4 +159,28 @@ public class SyslogParser {
|
|||
return instant;
|
||||
}
|
||||
|
||||
/*
|
||||
The priority value is calculated using the formula (Priority = Facility * 8 + Level).
|
||||
For example, a kernel message (Facility=0) with a Severity of Emergency (Severity=0) would have a Priority value of 0.
|
||||
Also, a "local use 4" message (Facility=20) with a Severity of Notice (Severity=5) would have a Priority value of 165.
|
||||
*/
|
||||
|
||||
static protected int getFacility(String prio) {
|
||||
|
||||
int priority = Integer.parseInt(prio);
|
||||
int facility = priority >> 3;
|
||||
|
||||
log.debug("getFacility() - " + prio + " => " + facility);
|
||||
return facility;
|
||||
}
|
||||
|
||||
static protected int getSeverity(String prio) {
|
||||
|
||||
int priority = Integer.parseInt(prio);
|
||||
int severity = priority & 0x07;
|
||||
|
||||
log.debug("getSeverity() - " + prio + " => " + severity);
|
||||
return severity;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,47 @@ import java.time.OffsetDateTime;
|
|||
|
||||
class SyslogParserTest extends Specification {
|
||||
|
||||
void "test rfc5424 message"() {
|
||||
|
||||
setup:
|
||||
def input = "<13>1 2020-09-23T08:57:30.950699+02:00 xps13 mark - - [timeQuality tzKnown=\"1\" isSynced=\"1\" syncAccuracy=\"125500\"] adfdfdf3432434565656"
|
||||
|
||||
when:
|
||||
SyslogMessage msg = SyslogParser.parseRfc5424(input)
|
||||
|
||||
then:
|
||||
msg.message == "adfdfdf3432434565656"
|
||||
}
|
||||
|
||||
|
||||
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.parseRfc3164(input)
|
||||
|
||||
then:
|
||||
msg.message == "test"
|
||||
msg.hostname == "p924vio1"
|
||||
msg.application == "padmin"
|
||||
}
|
||||
|
||||
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 parseRfc3164Timestamp"() {
|
||||
|
||||
setup:
|
||||
|
|
Loading…
Reference in a new issue